串口ReadFile读取0字节,returns为真
Serial port ReadFile reads 0 bytes and returns true
我正在尝试使用 Windows API 从 Windows 7 中的串行端口读取数据。当我尝试读入数据时,WaitCommEvent()
触发得很好并且 ReadFile()
调用 returns 1 作为状态,但没有读入数据。在 ReadFile documentation它说:
When a synchronous read operation reaches the end of a file, ReadFile
returns TRUE
and sets *lpNumberOfBytesRead
to zero.
但是,我确定通过串行端口发送的数据中没有 EOT
个字符。
我目前有两根 USB 电缆插入我的计算机并相互连接。我知道它们可以发送和接收数据,因为我已经用 Putty 对它们进行了测试。
为什么 ReadFile()
不读入任何数据?
我的代码如下。
Header:
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;
}
输出:
Serial port COM9 opened successfully.
Recieved characters.
Status: 1
Num bytes read: 0
Message:
Read finished.
显示的代码在 未初始化的 句柄上调用 GetCommState()
:
status = GetCommState(uart->handle, &uart_params);
挑衅UB这样做。其 returned 状态未经测试。
因此 uart_params
可能包含 BS 没有有用的数据。
帮自己一个忙: 永远检查所有相关函数的return值调用(并让代码相应地执行)! 将所有这些功能视为 "relevant" returning 或更改之后使用的数据。
我正在尝试使用 Windows API 从 Windows 7 中的串行端口读取数据。当我尝试读入数据时,WaitCommEvent()
触发得很好并且 ReadFile()
调用 returns 1 作为状态,但没有读入数据。在 ReadFile documentation它说:
When a synchronous read operation reaches the end of a file,
ReadFile
returnsTRUE
and sets*lpNumberOfBytesRead
to zero.
但是,我确定通过串行端口发送的数据中没有 EOT
个字符。
我目前有两根 USB 电缆插入我的计算机并相互连接。我知道它们可以发送和接收数据,因为我已经用 Putty 对它们进行了测试。
为什么 ReadFile()
不读入任何数据?
我的代码如下。
Header:
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;
}
输出:
Serial port COM9 opened successfully.
Recieved characters.
Status: 1
Num bytes read: 0
Message:
Read finished.
显示的代码在 未初始化的 句柄上调用 GetCommState()
:
status = GetCommState(uart->handle, &uart_params);
挑衅UB这样做。其 returned 状态未经测试。
因此 uart_params
可能包含 BS 没有有用的数据。
帮自己一个忙: 永远检查所有相关函数的return值调用(并让代码相应地执行)! 将所有这些功能视为 "relevant" returning 或更改之后使用的数据。