Reputation: 692
I have an open file descriptor for "/dev/ttyS0" which used to read data from a RS232 device. I am trying to use an epoll instance to do concurrent read from file descriptor As I am getting an error (Resource temporarily unavailable) while reading data from the file descriptor. I have sample code written with epoll to do this but it is not running as expected. Program is infinitely waiting at epoll_wait() call.
Please help me to verify the way I wrote the code
fdRS232 is the opened file descriptor for /dev/ttyS0
int DeviceRS232::readDecoderData(unsigned char *dataBuffer, size_t bufferSize)
{
unsigned char recvBuffer[251];
unsigned char *ptrChar;
int nBytes, portStatus;
int inputBufSize = 0;
// Use epoll for read and write event handling
int fdEpoll, returnStatus;
struct epoll_event rwEpollEvent;
struct epoll_event *prwEpollEvent;
fdEpoll = epoll_create1(0);
if(fdEpoll == -1)
{
std::cout << "Error: " << strerror(errno);
return 0;
}
rwEpollEvent.data.fd = fdRS232;
rwEpollEvent.events = EPOLLIN | EPOLLET;
returnStatus = epoll_ctl(fdEpoll, EPOLL_CTL_ADD, fdRS232, &rwEpollEvent);
if(returnStatus == -1)
{
std::cout << "Error: " << strerror(errno);
return 0;
}
prwEpollEvent = (epoll_event *)calloc(MAX_EVENTS, sizeof(rwEpollEvent));
while(true)
{
std::cout << "test1" << std::endl;
int nfd;
nfd = epoll_wait(fdEpoll, prwEpollEvent, MAX_EVENTS, -1);
std::cout << "ndf: " << nfd << std::endl;
for(int x=0; x<nfd; x++)
{
std::cout << "test-for" << std::endl;
if(prwEpollEvent[x].events & EPOLLERR ||
prwEpollEvent[x].events & EPOLLHUP ||
!(prwEpollEvent[x].events & EPOLLIN))
{
std::cout << "test2" << std::endl;
std::cout << "epoll error: " << strerror(errno);
close(prwEpollEvent[x].data.fd);
continue;
}
else
{
std::cout << "test3" << std::endl;
ChangeCTS(fdRS232, 0);
ChangeRTS(fdRS232, 0);
while(inputBufSize <= 0)
{
ioctl(fdRS232, FIONREAD, &inputBufSize);
usleep(1);
}
if(inputBufSize > 0)
{
int decodePacketLen = 0;
//unsigned char
memset(recvBuffer, 0x00, sizeof(recvBuffer));
nBytes = 0;
usleep(100000);
while(nBytes < ((int)recvBuffer[0] + 2))
{
int index = 0;
int recvDataLen = 0;
if(nBytes != 0)
index = nBytes - 1;
recvDataLen = read(fdRS232, &recvBuffer[index], 251);
if(recvDataLen < 0)
{
std::cout << "[INFO@DeviceRS232::receiveDecodedData]File read error: " << strerror(errno) << std::endl;
//sleep(1);
}
nBytes += recvDataLen;
if(nBytes == ((int)recvBuffer[0] + 2))
break;
}
if(recvBuffer[1] == DECODE_DATA)
sendCommandToDecoder(OPCODE_ACK);
std::cout << "[INFO @ DeviceRS232::receiveDecodedData]Data Lenght (without CheckSum) : " << (int)recvBuffer[0] << std::endl;
for(int i=0; i<nBytes; i++)
{
std::cout << "recvBuffer[" << i << "]: ";
printf("%x\n", recvBuffer[i]);
}
std::cout << "-----------------------------------" << std::endl;
//ChangeRTS(fdRS232, 1);
//ChangeCTS(fdRS232, 1);
//sleep(1);
}
}
}
}
free(prwEpollEvent);
//strcpy((char *)dataBuffer, (char *)recvBuffer);
memcpy((char *)dataBuffer, recvBuffer, sizeof(recvBuffer)/sizeof(recvBuffer[0]));
inputBufSize = 0;
return nBytes;
}
Upvotes: 2
Views: 3520
Reputation: 19395
Program is infinitely waiting at epoll_wait() call.
This is possibly due to using EPOLLET
. See man epoll
, Level-triggered and edge-triggered:
the caller might end up waiting for some data that is already present inside the input buffer.
Just use
rwEpollEvent.events = EPOLLIN;
instead.
Upvotes: 1