从Linux FIFO读取时出错

从Linux FIFO读取时出错,linux,fifo,Linux,Fifo,在我正在开发的嵌入式应用程序中,我们有一个串行端口抽象,我目前正在开发一个模拟的抽象变体,当您不在“真实”硬件上运行时使用。我使用FIFO文件来实现这一点,因为您可以插入您想要与实际应用程序通信的任何软件,但我在“读取”功能方面遇到了问题,该功能标记您给它的fd无效。尽管我使用了调试工具来验证传递给它的fd是否与先前打开的fd相同,因此它应该是有效的。我找不到这个问题的任何原因 FIFO文件通过此功能打开: int createOpenFifo(const std::string& pa

在我正在开发的嵌入式应用程序中,我们有一个串行端口抽象,我目前正在开发一个模拟的抽象变体,当您不在“真实”硬件上运行时使用。我使用FIFO文件来实现这一点,因为您可以插入您想要与实际应用程序通信的任何软件,但我在“读取”功能方面遇到了问题,该功能标记您给它的fd无效。尽管我使用了调试工具来验证传递给它的fd是否与先前打开的fd相同,因此它应该是有效的。我找不到这个问题的任何原因

FIFO文件通过此功能打开:

int createOpenFifo(const std::string& path, int flags)
{
   int fd = open(path.c_str(), flags);
   if (fd < 0)
   {
      mkfifo(path.c_str(), 0777);
      fd = open(path.c_str(), flags);
      if (fd < 0)
      {
         return -1;
      }
   }
   return fd;
}
int write_serial(handle_t handle, size_t length, const uint8_t* pData)
{
    SerialFifoData* data = static_cast<SerialFifoData*>(handle);

    size_t written = 0;
    while (written < length)
    {
        int result = write(data->writeFd, pData + written, length - written);
        if (result < 0)
        {
           return -1;
        }
        written += result;
    }

    return 0;
}
int read_serial(handle_t handle, size_t buffer_size, uint8_t* pBuffer, size_t* bytes_read)
{
    SerialFifoData* data = static_cast<SerialFifoData*>(handle);

    int return_val = read(data->readFd, pBuffer, buffer_size);

    if (return_val < 0)
    {
        if (errno == EAGAIN || errno == EWOULDBLOCK) // Non-blocking, no data
                                                     // which flag is raised
                                                     // varies between POSIX
                                                     // implementations
        {
            *bytes_read = 0;
            return -2;
        }
        return -1;
    }

    *bytes_read = return_val;
    return 0;
}
int createOpenFifo(const std::string&path,int标志)
{
int fd=open(path.c_str(),标志);
如果(fd<0)
{
mkfifo(path.c_str(),0777);
fd=打开(path.c_str(),标志);
如果(fd<0)
{
返回-1;
}
}
返回fd;
}
然后使用以下功能将FIFO写入:

int createOpenFifo(const std::string& path, int flags)
{
   int fd = open(path.c_str(), flags);
   if (fd < 0)
   {
      mkfifo(path.c_str(), 0777);
      fd = open(path.c_str(), flags);
      if (fd < 0)
      {
         return -1;
      }
   }
   return fd;
}
int write_serial(handle_t handle, size_t length, const uint8_t* pData)
{
    SerialFifoData* data = static_cast<SerialFifoData*>(handle);

    size_t written = 0;
    while (written < length)
    {
        int result = write(data->writeFd, pData + written, length - written);
        if (result < 0)
        {
           return -1;
        }
        written += result;
    }

    return 0;
}
int read_serial(handle_t handle, size_t buffer_size, uint8_t* pBuffer, size_t* bytes_read)
{
    SerialFifoData* data = static_cast<SerialFifoData*>(handle);

    int return_val = read(data->readFd, pBuffer, buffer_size);

    if (return_val < 0)
    {
        if (errno == EAGAIN || errno == EWOULDBLOCK) // Non-blocking, no data
                                                     // which flag is raised
                                                     // varies between POSIX
                                                     // implementations
        {
            *bytes_read = 0;
            return -2;
        }
        return -1;
    }

    *bytes_read = return_val;
    return 0;
}
int write\u serial(句柄、大小、长度、常量8*pData)
{
SerialFifoData*数据=静态转换(句柄);
写入的大小=0;
while(书写<长度)
{
int result=write(数据->writeFd,pData+writed,长度-writed);
如果(结果<0)
{
返回-1;
}
书面+=结果;
}
返回0;
}
最后,请阅读使用此函数:

int createOpenFifo(const std::string& path, int flags)
{
   int fd = open(path.c_str(), flags);
   if (fd < 0)
   {
      mkfifo(path.c_str(), 0777);
      fd = open(path.c_str(), flags);
      if (fd < 0)
      {
         return -1;
      }
   }
   return fd;
}
int write_serial(handle_t handle, size_t length, const uint8_t* pData)
{
    SerialFifoData* data = static_cast<SerialFifoData*>(handle);

    size_t written = 0;
    while (written < length)
    {
        int result = write(data->writeFd, pData + written, length - written);
        if (result < 0)
        {
           return -1;
        }
        written += result;
    }

    return 0;
}
int read_serial(handle_t handle, size_t buffer_size, uint8_t* pBuffer, size_t* bytes_read)
{
    SerialFifoData* data = static_cast<SerialFifoData*>(handle);

    int return_val = read(data->readFd, pBuffer, buffer_size);

    if (return_val < 0)
    {
        if (errno == EAGAIN || errno == EWOULDBLOCK) // Non-blocking, no data
                                                     // which flag is raised
                                                     // varies between POSIX
                                                     // implementations
        {
            *bytes_read = 0;
            return -2;
        }
        return -1;
    }

    *bytes_read = return_val;
    return 0;
}
int read\u serial(句柄、大小、缓冲区大小、uint8\u t*pBuffer、大小、字节、读取)
{
SerialFifoData*数据=静态转换(句柄);
int return\u val=read(数据->readFd,pBuffer,缓冲区大小);
如果(返回值<0)
{
if(errno==EAGAIN | | errno==ewoodblock)//非阻塞,无数据
//升起的是哪面旗
//在POSIX之间变化
//实现
{
*字节读取=0;
返回-2;
}
返回-1;
}
*字节读取=返回值;
返回0;
}

我已经验证了每个函数都接收到正确的输入,并且读和写调用与实际串行端口代码使用的调用几乎相同(唯一的区别是如何从句柄中提取FD),它们工作得很好。

您需要打开fifo两次:一个FD用于写入,一个FD用于读取。为了澄清,我从不同的位置打开FIFO两次。但也注意到,如果我不将它们标记为读/写,则打开调用将不确定地阻塞。您注意到了正确的行为,如手册页中所述。您必须在两侧r/w打开它,或者在非阻塞模式下打开它。您还必须确保在尝试读取或写入之前,两端都已打开,并且(最重要的是,当两个fifo端处于同一过程中时),您从未尝试读取比最初写入fifo的数据更多的数据。