串口ReadFile读取0个字节并返回true

时间:2016-07-07 14:26:03

标签: c windows winapi serial-port initialization

我正在尝试使用Windows API从Windows 7中的串行端口读取数据。当我尝试读取数据时,retrieveDuration()触发就好了,WaitCommEvent()调用返回1作为状态,但没有读入数据。在ReadFile documentation中它表示:

  

当同步读取操作到达文件末尾时,ReadFile()返回ReadFile并将TRUE设置为零。

但是,我确信通过串口发送的数据中没有*lpNumberOfBytesRead个字符。

我目前有两条USB线插在电脑上并相互连接。我知道他们可以发送和接收数据,因为我用Putty测试了它们。

为什么EOT不读取任何数据?

我的代码如下。

部首:

ReadFile()

主档案:

typedef struct uart_handle
{
   uint8_t port_num;
   char port_name[10];
   uint32_t baud_rate;
   uint8_t byte_size;
   uint8_t stop;
   uint8_t parity;
   int32_t error;
   HANDLE handle;
} uart_handle;

输出:

uart_handle* serial_comm_init(uint8_t port_num, uint32_t baud_rate, uint8_t byte_size, uint8_t stop, uint8_t parity)
{
   uart_handle*  uart;
   DCB           uart_params = { 0 };
   COMMTIMEOUTS  timeouts    = { 0 };
   int           status;

   uart         = (uart_handle*) malloc(1 * sizeof(uart_handle));
   status       = 0;

   // Set port name
   if (port_num > 9)
   {
      sprintf(uart->port_name, "\\\\.\\COM%d", port_num);
   }
   else
   {
      sprintf(uart->port_name, "COM%d", port_num);
   }

   // Set baud rate
   uart->baud_rate = baud_rate;

   // Set byte size
   uart->byte_size = byte_size;

   // Set stop bit
   uart->stop = stop;

   // Set parity
   uart->parity = parity;

   // Set up comm state
   uart_params.DCBlength = sizeof(uart_params);
   status = GetCommState(uart->handle, &uart_params);
   uart_params.BaudRate = uart->baud_rate;
   uart_params.ByteSize = uart->byte_size;
   uart_params.StopBits = uart->stop;
   uart_params.Parity   = uart->parity;
   SetCommState(uart->handle, &uart_params);

   // Setup actual file handle
   uart->handle = CreateFile(uart->port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
   if (uart->handle == INVALID_HANDLE_VALUE) {
      printf("Error opening serial port %s.\n", uart->port_name);
      free(uart);
      return NULL;
   }
   else {
      printf("Serial port %s opened successfully.\n", uart->port_name);
   }

   // Set timeouts
   status = GetCommTimeouts(uart->handle, &timeouts);
   timeouts.ReadIntervalTimeout         = 50;
   timeouts.ReadTotalTimeoutConstant    = 50;
   timeouts.ReadTotalTimeoutMultiplier  = 10;
   timeouts.WriteTotalTimeoutConstant   = 50;
   timeouts.WriteTotalTimeoutMultiplier = 10;
   status = SetCommTimeouts(uart->handle, &timeouts);
   if (status == 0) {
      printf("Error setting comm timeouts: %d", GetLastError());
   }

   return uart;
}

int32_t serial_comm_read(void* handle, uint8_t* msg, uint32_t msg_size, uint32_t timeout_ms, uint32_t flag)
{
   uart_handle*  uart;
   uint32_t      num_bytes_read;
   uint32_t      event_mask;
   int32_t       status;

   uart            = (uart_handle*) handle;
   num_bytes_read  = 0;
   event_mask      = 0;
   status          = 0;

   memset(msg, 0, msg_size);

   // Register Event
   status = SetCommMask(uart->handle, EV_RXCHAR);

   // Wait for event
   status = WaitCommEvent(uart->handle, &event_mask, NULL);

   printf("Recieved characters.\n");

   do {
      status = ReadFile(uart->handle, msg, msg_size, &num_bytes_read, NULL);
      printf("Status: %d\n", status);
      printf("Num bytes read: %d\n", num_bytes_read);
      printf("Message: %s\n", msg);

   } while (num_bytes_read > 0);

   printf("Read finished.\n");

   return 0;
}

1 个答案:

答案 0 :(得分:3)

显示的代码在未初始化的句柄上调用GetCommState()

status = GetCommState(uart->handle, &uart_params); 
挑起UB这样做。其返回状态未经过测试。

由于这个uart_params可能包含 BS 没有有用的数据。

帮自己一个忙: 始终并检查所有相关函数调用的返回值(并让代码相应地执行操作)!将所有那些返回或更改之后使用的数据的函数视为“相关”。