2016-07-07 4 views
3

Я пытаюсь прочитать данные из последовательного порта в Windows 7 с помощью Windows API. . Когда я пытаюсь читать данные, то WaitCommEvent() пожаров просто отлично и ReadFile() возвращает 1, как статус, но нет данных считываются В в ReadFile documentation он говорит, что:Последовательный порт ReadFile читает 0 байт и возвращает true

когда операция достигает синхронное чтение конец файла, ReadFile возвращает TRUE и устанавливает *lpNumberOfBytesRead в ноль.

Однако, я уверен, что в данных, отправляемых через последовательный порт, нет символов EOT.

В настоящее время у меня есть два USB-кабеля, подключенные к компьютеру и подключенные друг к другу. Я знаю, что они могут отправлять и получать данные, поскольку я тестировал их с помощью Putty.

Почему не будет 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; 
} 

Выход:

Serial port COM9 opened successfully. 
Recieved characters. 
Status: 1 
Num bytes read: 0 
Message: 
Read finished. 
+0

Вы уверены, что 'msg_size' не 0? – ElderBug

+0

Примечание: 'port_num> 99' приводит к перезаписи' port_name [10] '. Должна быть шире. 'port_num' должен быть проверен на 0. Допустимые номера портов: 1-256. – chux

+0

Неясно о «Я уверен, что нет символов EOF» Что такое EOF _character_? – chux

ответ

3

код, показанный вызовы GetCommState() на неиницализированные ручка:

status = GetCommState(uart->handle, &uart_params); 

провоцирует UB, делая это. Его возвращенный статус не проверяется.

В связи с этим uart_params, вероятно, содержит BS нет полезных данных.


Сделайте себе одолжение:всегда и всегда проверять возвращаемое значение на все соответствующие вызовы функций (и пусть код действовать соответственно)! Рассмотрите как «соответствующие» все функции, возвращающие или изменяющие данные, используемые впоследствии.

Смежные вопросы