Easyelectronics.ru

Электроника для всех
Текущее время: 27 сен 2020, 03:21

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
 Заголовок сообщения: Фильтр приема данных
СообщениеДобавлено: 23 апр 2015, 19:49 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
Добрый день, к МК по UART подключено устройство от которого по запросу приходят следующего вида сообщения:
#HEADER,<NUM>,<TYPE>\r\n
<DATA произвольные данные>\r\n

Кол-во таких посылок заранее не известно. Время между выдачей посылок 100-200 мс.
После того как все посылки были выгружены приходит сообщение END_DATA.

Соответственно длина блока данных тоже заранее неизвестна.
Задача состоит в том чтобы сначала разобрать заголовок, вытащить оттуда номер сообщения <NUM> и его тип <TYPE>. И потом уже в зависимости от его типа производить дальнейшие действия.

В прерывании думаю делать разбор не совсем верное решение будет. Пробовал все данные сначала писать в буфер и потом этот буфер передавать программе и уже в ней разбирать строчку, но так в буфер будут попадать и данные <DATA>, что на первом этапе не желательно, т.к размер данных в посылке может доходить до 300 байтов и таких посылок может быть от 20 до 30 шт.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 23 апр 2015, 20:10 
Старожил
Аватара пользователя

Зарегистрирован: 10 фев 2012, 18:04
Сообщения: 827
Откуда: Україна
организуйте кольцевой буфер. пусть прерывание просто ложит туда приходящие данные, а основной код будет на лету эти данные забирать и обрабатывать.

_________________
"Если вы такие умные, что ж вы строем не ходите?"

Легче зажечь одну маленькую свечу, чем постоянно жаловаться на тьму...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 23 апр 2015, 20:18 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
DOOMSDAY писал(а):
организуйте кольцевой буфер. пусть прерывание просто ложит туда приходящие данные, а основной код будет на лету эти данные забирать и обрабатывать.

Так получится, что сообщения <data> тоже в буфер будут попадать и могут начать затирать данные заголовков.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 23 апр 2015, 22:17 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
А если сделать 2 буфера?
1-ый основной (сделать его длинною, например 1024 байта)
2-ой короткий (24 байта, к примеру)

В самом прерывании складываем данные во 2-ой буфер.
Код:
char buffer_main[1024];
char buffer_tmp[24];
uint8_t pos;

void irq_handler(char c) {

  if (c == '\n') {
    if (strncmp(buffer_tmp, "#HEADER", 7) == 0) {
       /* Копируем эту строку в буфер buffer_main
       и потом выставляем флаг/отправляем queue в основную программу*/
    }
    if (strncmp(buffer_tmp, "END_DATA", 8) == 0) {
      /* строка END_DATA означает, что данные все получены
          так же копируем эту строку в buffer_main */
    }
  }

  buffer_tmp[pos] = c;
  pos++;
  if (pos >= 24) pos = 0;
}


И в основной программе обрабатываем полученные заголовки по очереди пока не пришло сообщение END_DATA.

На сколько такой вариант "корявый"?

И еще дальше надо предпринимать некоторые действия в зависимости от типа посылки.
Например, если тип 1, то повторно получить именно этот пакет и разбирать уже данные в нем.
Как-то так:
#HEADER,2,1\r\n
123456QWERTASDFGZCCV\r\n

После получения такого пакета, нужно будет запросить его повторно и уже разбирать сами данные...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 23 апр 2015, 22:57 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 835
mounty
У меня немного проще пакеты.
Стартовая посылка(32бит)/пауза - тип сообщения(8бит)/кому (прямой или символьный адрес 32бит)/размер (16бит)/контрольная сумма(32бит)/ пауза - данные/стоп = контрольная сумма.
И того, в прерывании сначала идёт проверка на первый байт старта - совпало на второй и так далее. Потом запуск дма, размер данных известен. После запуск дма натравленный в нужную область памяти, потом проверка контрольной суммы и выдача результата - повторить или следующий. Паузы необходимы для успевания натравливания дма, со стороны источника это байт 0х00.
И ещё, для варта нужно задействовать rts-cts , иначе будет очень грустно с большими скоростями.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 23 апр 2015, 23:24 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
AVI-crak писал(а):
mounty
У меня немного проще пакеты.
Стартовая посылка(32бит)/пауза - тип сообщения(8бит)/кому (прямой или символьный адрес 32бит)/размер (16бит)/контрольная сумма(32бит)/ пауза - данные/стоп = контрольная сумма.
И того, в прерывании сначала идёт проверка на первый байт старта - совпало на второй и так далее. Потом запуск дма, размер данных известен. После запуск дма натравленный в нужную область памяти, потом проверка контрольной суммы и выдача результата - повторить или следующий. Паузы необходимы для успевания натравливания дма, со стороны источника это байт 0х00.
И ещё, для варта нужно задействовать rts-cts , иначе будет очень грустно с большими скоростями.


Не знаю на сколько тут оправданно будет использование DMA. Как мне кажется только усложнение алгоритма.
Ну ладно, если оставить вариант с копированием из временного буфера в основной.
Псевдокод основной программы:
Код:
while (1) {
  <ожидание очереди>

  // queue - строка из буфера.
  if (strncmp(queue, "#HEADER", 7) == 0) {
    // Разбираем заголовок
    number = get_number(queue);
    type = get_type(queue);
  }
  if (strcnmp(queue, "END_DATA", 8) == 0) {
    // Все посылки получены
    break;
  }
}


И вот после этого цикла нам нужно, как уже писал, предпринять какие-то действия.
Как лучше в таком случае поступить? В каком видео лучше хранить номер и тип сообщения?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 23 апр 2015, 23:51 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 835
Опрашивать буфер в цикле - не очень хорошо. Лучше делать все телодвижения в нужный для этого момент, у меня целиком и полностью в прерываниях. Результат пинает зависящий от даты процесс, причём разные нитки.
Применимо к "#HEADER" , слово бьётся на буквы. И проверяется на совпадения по порядку. Совпал первый символ , замечательно, в следующем прерывании проверяем второй символ и так далее, при сбое - начинаем проверять первый символ, и так до усрачки.
У меня таким образом проверяется стартовая пачка.
Применять дма имеет смысл про наличии данных более 8 символов, варт вещь жутко тормозная, и может тормозить зависящие процессы.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 24 апр 2015, 00:13 
Старожил
Аватара пользователя

Зарегистрирован: 26 янв 2010, 21:48
Сообщения: 3965
Откуда: Звенигород
Я делал кольцевой буфер. В него складываю все подряд, но в прерывании проверял на признаки конца посылки. И если встречал, то увеличивал переменную сообщений на 1. А в основной программе проверял эту переменную и начинал разбор.

_________________
От Парижа до Находки с водкой лучше, чем без водки!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 24 апр 2015, 00:13 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
Почему в цикле не очень хорошо?
Зато так не будет тормозить в прерываниях, просто под работу с этим устройством выделить отдельный таск и в нем производить разбор посылок.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 24 апр 2015, 00:17 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
PRC писал(а):
Я делал кольцевой буфер. В него складываю все подряд, но в прерывании проверял на признаки конца посылки. И если встречал, то увеличивал переменную сообщений на 1. А в основной программе проверял эту переменную и начинал разбор.

Так в том то и дело, что не вижу смысла в самом начале все складывать в буфер, т.к. посылок может быть много и данные, которые идут после HEADER могут быть длинной до 500 байтов, а если делать кольцевой буфер и все в него складывать, то заголовки в этом буфере могут затираться.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 24 апр 2015, 00:33 
Старожил
Аватара пользователя

Зарегистрирован: 26 янв 2010, 21:48
Сообщения: 3965
Откуда: Звенигород
Сделать буфер на 3-4 сообщения. И по приему первого сообщения начинать разбор. При этом размер буфера будет увеличиваться.
И вообще под какой проц это пишется? Я на стм8с обрабатывал строки от тех. модема спокойно.

_________________
От Парижа до Находки с водкой лучше, чем без водки!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 24 апр 2015, 00:49 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
PRC писал(а):
Сделать буфер на 3-4 сообщения. И по приему первого сообщения начинать разбор. При этом размер буфера будет увеличиваться.
И вообще под какой проц это пишется? Я на стм8с обрабатывал строки от тех. модема спокойно.

Проц stm32 100-ый.
Смущает если честно разбор в прерывании делать...а чем вариант с временным буфером и копированием его в основной плох?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 24 апр 2015, 02:53 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 835
mounty писал(а):
Смущает если честно разбор в прерывании делать...а чем вариант с временным буфером и копированием его в основной плох?


Дык количеством телодвижений.
Для прерывания это будет примерно так:
Show

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Фильтр приема данных
СообщениеДобавлено: 24 апр 2015, 12:56 
Заглядывает иногда

Зарегистрирован: 13 фев 2015, 22:59
Сообщения: 35
AVI-crak, разве так меньше телодвижений?
Условия в прерывании и т.п

Ну ладно, допустим заголовки мы все прочитали.
Дальше в этой программе нам нужно выполнить дополнительные действия в зависимости от типа посылки (отправить команды этому устройству с номером посылки, команды будут различаться в зависимости от типа посылки).
Складывать номера и типы в какой-то массив и после цикла его перебирать? Или можно сделать более "грамотно"?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB