C не записывает все данные в порт UART

#c #wiringpi

Вопрос:

Я тестировал связь UART на C с помощью WiringPi.

Проблема:

Похоже, что C не выводит все данные в порт UART /dev/ttyAMA0 . Может быть, я делаю это неправильно?

Расследования:

Примечание : Я использую миником, minicom --baudrate 57600 --noinit --displayhex --device /dev/ttyAMA0 чтобы проверить полученные данные.

И еще! Контакты порта UART, RX и TX закорочены вместе.

Код python работал отлично, однако, когда я попытался реализовать его на C , полученные данные отличались.

Ожидаемые полученные данные должны быть: ef 01 ff ff ff ff 01 00 07 13 00 00 00 00 00 1b .

Сравнение Полученных Данных:

Используемый язык Данные, полученные от Minicom
Питон ef 01 ff ff ff ff 01 00 07 13 00 00 00 00 00 1b
C эф 01 фф фф фф фф 01

Используемый код

Питон:

 import serial
from time import sleep

uart = serial.Serial("/dev/ttyAMA0", baudrate=57600, timeout=1)

packet = [239, 1, 255, 255, 255, 255, 1, 0, 7, 19, 0, 0, 0, 0, 0, 27]

uart.write(bytearray(packet))
 

C :

Примечание: Код, скомпилированный с g -Wall -O3 -o test hello.cpp -lwiringPi

 #include <iostream>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>

using namespace std;

int main()
{

      int serial_port;

      if (wiringPiSetup() == -1)
            exit(1);

      if ((serial_port = serialOpen("/dev/ttyAMA0", 57600)) < 0)
      {
            fprintf(stderr, "Unable to open serial device: %sn", strerror(errno));
            return 1;
      }

      cout << "Sending data to UART" << std::endl;

      serialPuts(serial_port, "xefx01xffxffxffxffx01x00x07x13x00x00x00x00x00x1b");

      return 0;
}
 

Ответ №1:

Вы не можете использовать serialPuts для отправки нулевого терминатора. Как и во всех подобных функциях, он остановится, когда в строке будет обнаружен нулевой терминатор. В этом случае я думаю, что ваш лучший вариант-добавить функцию, которая использует обычную write функцию, которая используется внутри собственных функций WiringPi.

Вы можете создать функцию-оболочку, чтобы она выглядела аналогично другим вызовам:

 #include <cstddef>

void serialWrite(const int fd, const char* data, size_t length) {
    write(fd, data, length);
}
 

и, возможно, шаблон функции, чтобы не приходилось вручную подсчитывать длину данных в фиксированных массивах данных:

 template<size_t N>
void serialWrite(const int fd, const char(amp;data)[N], bool strip_last = true) {
    serialWrite(fd, data, N - strip_last);
}
 

Теперь вы можете использовать его так:

 serialWrite(serial_port, "xefx01xffxffxffxffx01x00x07x13x00x00x00x00x00x1b");
 

Примечание.Существует запрос на добавление аналогичной функции (вызываемой serialPut ) в библиотеку WiringPi, которую вы можете загрузить вместо использования официальной версии из основной версии ветви, если вы не хотите создавать свою собственную функцию.

Комментарии:

1. Это сделало свое дело! Однако мне потребовалось некоторое время, чтобы перекомпилировать всю библиотеку. Большое вам спасибо!

2. @Justsomesailboat Добро пожаловать! Рад, что все получилось!