Russian Qt Forum
Ноябрь 23, 2024, 08:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSerialPort чтение только блоками по 256 байт  (Прочитано 7277 раз)
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 "
« Последнее редактирование: Сентябрь 04, 2017, 02:30 от rain62ster » Записан
Bepec
Гость
« Ответ #1 : Сентябрь 04, 2017, 02:36 »

Ну, такая проблема у меня была только с конвертерами USB-Устройство. Там буферизацию приходилось отключать. Но если он у вас напрямую соединён, я хз.
В линуксе не шарю.

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

PPS а почему так топорно, а не на сигнал-слотах? Тогда б вам не пришлось заморачиваться данной проблемой?
« Последнее редактирование: Сентябрь 04, 2017, 02:38 от Bepec » Записан
rain62ster
Гость
« Ответ #2 : Сентябрь 04, 2017, 02:39 »

Именно USB/CDC... Где Вы увидели топорность? Все на сигнал-слотах. Приведенная процедура - слот сигнала таймера, например.
« Последнее редактирование: Сентябрь 04, 2017, 02:47 от rain62ster » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Сентябрь 04, 2017, 10:18 »

Цитировать
приходит блок байтов размером 256

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

ArchLinux x86_64 / Win10 64 bit
rain62ster
Гость
« Ответ #4 : Сентябрь 04, 2017, 10:24 »

Реализация CDC в составе HAL ChibiOS от Jiovanni di Sirio. Пользуюсь этой RTOS и ее HAL не первый год. Всегда без нареканий. Кроме того это же дивайс в паре с виндовым компьютером работает также без проблем. Засада, похоже где в линухе.
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #5 : Сентябрь 04, 2017, 10:24 »

Управляю железякой через usb-rs232 преобразователь, никаких проблем, пакеты приходят сразу
Проблема или в программе или в железяке
Для начала читай порт через minicom и смотри правильно ли работает железяка
Записан
Bepec
Гость
« Ответ #6 : Сентябрь 04, 2017, 11:55 »

Вы чтение реализуете через timeout таймера. Почему не через QIODevice::readyRead(), который избавит вас от проблем с ожиданием?
Записан
rain62ster
Гость
« Ответ #7 : Сентябрь 04, 2017, 13:01 »

Похоже нашел причину. Я перешел на последнюю версию ChibiOS/HAL а конфигурация USB осталась от прежнего HAL. Использовать readyRead() пытался, но видимо по той же причине успеха не получил.
Записан
rain62ster
Гость
« Ответ #8 : Сентябрь 04, 2017, 16:43 »

Окончательно проверил, все работает как надо. С использованием readyRead() .
Записан
titan83
Гость
« Ответ #9 : Сентябрь 05, 2017, 18:05 »

Рад, что у вас все получилось, но можно я чуть-чуть пофлужу?))
Мне интересны мотивы выбора протокола Wake, ведь устройство вы разрабатывали сами и выбор протокола был чем-то обоснован.
Просто я вкратце прочитал описание, и пока не вижу каких-то преимуществ по сравнению, например, с modbus rtu. Я что-то упускаю?
Спасибо.
Записан
Bepec
Гость
« Ответ #10 : Сентябрь 05, 2017, 19:59 »

Если почитать внимательнее, то у него стоит такая задача. Либо требование контрольной системы, либо ТЗ Улыбающийся
Записан
rain62ster
Гость
« Ответ #11 : Сентябрь 05, 2017, 20:04 »

Наверное потому что исторически так сложилось. А потом должны были бы появиться веские мотивы для перехода на другой протокол. Этот уже привычен и обкатан, прост в реализации. Как то так..
    А Вы как то можете обосновать бОльшую предпочтительность Modbus?
« Последнее редактирование: Сентябрь 05, 2017, 20:19 от rain62ster » Записан
titan83
Гость
« Ответ #12 : Сентябрь 05, 2017, 20:52 »

Наверное потому что исторически так сложилось. А потом должны были бы появиться веские мотивы для перехода на другой протокол. Этот уже привычен и обкатан, прост в реализации. Как то так..
    А Вы как то можете обосновать бОльшую предпочтительность Modbus?
Спасибо.
В том-то и дело, что я не увидел принципиальной разницы, но про модбас слышали (как минимум) все, а про wake я впервые узнал от вас) Правда я уже пару лет чуть-чуть в другой области, но все же.
Записан
rain62ster
Гость
« Ответ #13 : Сентябрь 06, 2017, 12:17 »

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

PS: все случайные числа ранжируются , то есть не выходят за выходят за границы допустимых значений
« Последнее редактирование: Сентябрь 06, 2017, 12:22 от rain62ster » Записан
Bepec
Гость
« Ответ #14 : Сентябрь 06, 2017, 15:09 »

У вас видимо там буферок какой то. На стороне устройства.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.096 секунд. Запросов: 23.