Используйте команду epoll () для чтения данных из файлового дескриптора

У меня есть дескриптор открытого файла для «/ DEV / ttyS0«который используется для чтения данных из RS232 устройство. Я пытаюсь использовать Epoll Экземпляр для одновременного чтения из файлового дескриптора. Когда я получаю сообщение об ошибке (ресурс временно недоступен) при чтении данных из файлового дескриптора. У меня есть пример кода, написанный с epoll, чтобы сделать это, но он работает не так, как ожидалось. Программа бесконечно ждет epoll_wait () вызов.

Пожалуйста, помогите мне проверить, как я написал код
fdRS232 дескриптор открытого файла для / 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;
}

1

Решение

Программа бесконечно ждет при вызове epoll_wait ().

Это возможно из-за использования EPOLLET, Увидеть man epoll, Уровень запускается и запускается по краю:

вызывающий абонент может в конечном итоге ждать некоторые данные, которые уже присутствуют
внутри входного буфера.

Просто используйте

    rwEpollEvent.events = EPOLLIN;

вместо.

0

Другие решения


По вопросам рекламы [email protected]