Russian Qt Forum

Qt => Вопросы новичков => Тема начата: rain62ster от Сентябрь 04, 2017, 02:20



Название: QSerialPort чтение только блоками по 256 байт
Отправлено: rain62ster от Сентябрь 04, 2017, 02:20
Есть задача управлять девайсом на STM32F401 c компьютера с ОС Linux используя протокол Wake. Со стороны дивайса софт был более менее отлажен ранее, когда он управлялся Виндовым компом. Реализацию Wake со стороны PC с Линуксом пишу сам. Одновременно пишу программку позволяющую отправлять фреймы Wake на дивайс и получать ответные фреймы от него. Все оправленные и принятые фреймы пишутся в лог, и отображаются в ListWiget,
  Полная функциональность пока не получена. Исходяшие от РС фреймы - OK. А ответные фреймы(их я пытаюсь получить спустя 100 мс после отправки) не считываются. Не считываются до тех пор, пока суммарное количество принятых байтов не достигнет 256(вероятно такой объем буфера приемника). После этого они вываливаются все разом. То есть я щелкаю мышкой по ПушБуттону отправки фрейма, наблюдаю прохождение исходящих фреймов, на дивайсе мигают соотв. светодиодики. А ответных фреймов нет. После 10-15 нажатий(в зависимости от размера ответного фрейма) приходит блок байтов размером 256, содержащий все ранее отправленые дивайсом фреймы.
  FEND и FESC это коды для стаффинга, выводятся в мнемоническом виде для большей наглядности.
Привожу процедуру считывания отклика.

Код:
void QMainWidget::AnswerTimeout(){
  uint32_t count;
  char buf[512];
  do{
    count = serial.read(buf, 1);
    if(count){
      uint8_t a = (uint8_t)buf[0];
      switch(a){
      case 0xC0:
        rxstr = rxstr + QString("FEND") + QString(" ");
        break;
      case 0xDB:
        rxstr = rxstr + QString("FESC") + QString(" ");
        break;
      default:
        rxstr = rxstr + ByteToHex(a) + QString(" ");
      break;}}}
    while(count);
  qDebug() << "AnswerTimeout  " << rxstr;
}

Вот так выглядит отладочный вывод приема. Количество FEND равно количеству фреймов.

AnswerTimeout   "RX1 <- 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 21 34 56 78 FESC DC 4F FEND 80 08 05 "


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: Bepec от Сентябрь 04, 2017, 02:36
Ну, такая проблема у меня была только с конвертерами USB-Устройство. Там буферизацию приходилось отключать. Но если он у вас напрямую соединён, я хз.
В линуксе не шарю.

PS а скорость передачи какая?

PPS а почему так топорно, а не на сигнал-слотах? Тогда б вам не пришлось заморачиваться данной проблемой?


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: rain62ster от Сентябрь 04, 2017, 02:39
Именно USB/CDC... Где Вы увидели топорность? Все на сигнал-слотах. Приведенная процедура - слот сигнала таймера, например.


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: kuzulis от Сентябрь 04, 2017, 10:18
Цитировать
приходит блок байтов размером 256

Значит криво реализован CDC ACM в STM32F401.


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: rain62ster от Сентябрь 04, 2017, 10:24
Реализация CDC в составе HAL ChibiOS от Jiovanni di Sirio. Пользуюсь этой RTOS и ее HAL не первый год. Всегда без нареканий. Кроме того это же дивайс в паре с виндовым компьютером работает также без проблем. Засада, похоже где в линухе.


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: qate от Сентябрь 04, 2017, 10:24
Управляю железякой через usb-rs232 преобразователь, никаких проблем, пакеты приходят сразу
Проблема или в программе или в железяке
Для начала читай порт через minicom и смотри правильно ли работает железяка


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: Bepec от Сентябрь 04, 2017, 11:55
Вы чтение реализуете через timeout таймера. Почему не через QIODevice::readyRead(), который избавит вас от проблем с ожиданием?


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: rain62ster от Сентябрь 04, 2017, 13:01
Похоже нашел причину. Я перешел на последнюю версию ChibiOS/HAL а конфигурация USB осталась от прежнего HAL. Использовать readyRead() пытался, но видимо по той же причине успеха не получил.


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: rain62ster от Сентябрь 04, 2017, 16:43
Окончательно проверил, все работает как надо. С использованием readyRead() .


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: titan83 от Сентябрь 05, 2017, 18:05
Рад, что у вас все получилось, но можно я чуть-чуть пофлужу?))
Мне интересны мотивы выбора протокола Wake, ведь устройство вы разрабатывали сами и выбор протокола был чем-то обоснован.
Просто я вкратце прочитал описание, и пока не вижу каких-то преимуществ по сравнению, например, с modbus rtu. Я что-то упускаю?
Спасибо.


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: Bepec от Сентябрь 05, 2017, 19:59
Если почитать внимательнее, то у него стоит такая задача. Либо требование контрольной системы, либо ТЗ :)


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: rain62ster от Сентябрь 05, 2017, 20:04
Наверное потому что исторически так сложилось. А потом должны были бы появиться веские мотивы для перехода на другой протокол. Этот уже привычен и обкатан, прост в реализации. Как то так..
    А Вы как то можете обосновать бОльшую предпочтительность Modbus?


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: titan83 от Сентябрь 05, 2017, 20:52
Наверное потому что исторически так сложилось. А потом должны были бы появиться веские мотивы для перехода на другой протокол. Этот уже привычен и обкатан, прост в реализации. Как то так..
    А Вы как то можете обосновать бОльшую предпочтительность Modbus?
Спасибо.
В том-то и дело, что я не увидел принципиальной разницы, но про модбас слышали (как минимум) все, а про wake я впервые узнал от вас) Правда я уже пару лет чуть-чуть в другой области, но все же.


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: rain62ster от Сентябрь 06, 2017, 12:17
Ха! Проблема получила неожиданное продолжение. Вроде се хорошо. Для тестирования забил в железяку программку, которая отвечает на ЛЮБОЙ фрейм его полным эхом.На стороне  РС/Линкус программа гененрирует фреймы случайной длины со случайным кодом опрерции и случайными данными и с интервалом 50 мс отправляет их на железяку и прежде чем отправит следующий фрейм, ждет ответа на текущий. Обмен регулярно останавливается, - по причине отсутствия ответа. Стал разбираться. Оказалось, что  ситуевина зависит от длины фрейма и больше ни от чего.  Скажем при максимальной длине фрейма(255 байт данных, все данные - случайные числа - qrand()) обмен длится часами безостановочно. А, скажем при длине блока данных 0x39, 0xBA, 0xF9  - обмен останавливается по причине отсутствия ответа. Но, как выяснилось при такой длине фрейма нет ПЕРЕДАЧИ со стороны РС/Линукс.
     Создаю фиксированный фрейм проблемной длины и отправляю его несколько раз, на каком то шаге происходит массовая отсылка всех накопившихся исходящих фреймов, и приходит столько же ответов. >:( >:(

PS: все случайные числа ранжируются , то есть не выходят за выходят за границы допустимых значений


Название: Re: QSerialPort чтение только блоками по 256 байт
Отправлено: Bepec от Сентябрь 06, 2017, 15:09
У вас видимо там буферок какой то. На стороне устройства.