barabek 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба У вас идеология неверная. Уарт заполняет фифо и только. Фоновая программа выгребает фифо и парсит фреймы. В таком варианте будет достаточным иметь размер фифо байт на 16-64.. А парсер фреймов (собственно протокол) может иметь свой буфер на максимальный размер пакета. Как-то так обычно делается. Благодаря чему выполняется парадигма минимизации времени обработки прерываний... Более того некоторые протоколы регламентируют максимальный размер фифо канала связи. Так например modbus имеет пожелания на размер фифо в 32 байта... А если пример с NMEA? Там остановить передачу нельзя. В этом случае нужно иметь буфер на максимальную посылку. Ну а как обрабатывать - уже выше описали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба А если пример с NMEA?Тем более. В 90% случаев цикл основной программы отрабатывается быстрее чем несколько мс. Только исходя из этого и выбирается размер фифо (чтобы не переполнился за эти пару мс). Например на скорости 115200 один байт передаётся за ~90мкс, а цикл фоновой программы 2мс. Следовательно минимальный размер фифо будет 2000мкс/90мкс = 22 байта. Округлим до ближайшего кратного 2 и получим 32. ЧИТД. Вот такая простая арифметика. А то, что вам написали (ловить старт-стоп) нужно делать в фоновой программе (в модуле протокола NMEA например медленно и печально искать пакеты и сверять crc) а не в ISR уарта. Тем самым вы рассекаете на независимые логические модули свою программу. Я вам дельный совет даю - прислушайтесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба При желании разбирать входные данные можно вообще безо всяких буферов, исключительно на конечных автоматах. Объем кода получится приличный, зато без затрат памяти и быстро - можно отрабатывать не выходя из прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба При желании разбирать входные данные можно вообще безо всяких буферов, исключительно на конечных автоматах. Объем кода получится приличный, зато без затрат памяти и быстро - можно отрабатывать не выходя из прерывания.Дилетантский подход в подавляющем большинстве случаев, ИМХО. Долго сидеть в прерывании - зло. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Все относительно и ситуационно. Дилетантский подход в подавляющем большинстве случае - это возводить в абсолют время сидения в прерывании, ИМХО :) Часто минимизировать нужно именно время реакции системы, а перекладывание из буфера в буфер скорости не добавит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DpInRock 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Для простых программ (относительно простых), с крайне малым числом конкурирующих процессов можно вообще всю программу запихать в прерывание. И в этом нет никакого зла. Но такой подход плох только одним. Появляется привычка. И в следующих, настоящих сложных проектах не будет опыта распределять нагрузку, работать с буферами и прочим. В данном же случае, очевидно, что NMEA не имеет никакой возможности загрузить контроллер до упора. Посему можно создавать кучу буферов и сделать программу более понятной для самого себя. Как бэ потренироваться в создании уровней обработки. На простом примере. Ибо также очевидно, что если чел не знаком с кольцевыми буферами, то ему самое время начать тренировки... Времена, когда на IBM PC экономили память и оптимизировали код ассемблером канули в вечность. Времена, когда нечего экономить и в микроконтроллерах - уже наступили. Только еще не все в курсе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Все относительно и ситуационно. Дилетантский подход в подавляющем большинстве случае - это возводить в абсолют время сидения в прерывании, ИМХО :) Часто минимизировать нужно именно время реакции системы, а перекладывание из буфера в буфер скорости не добавит. А собственно чего сидеть в прерывании USART, что Вам это даст ? У него самая тупая задача , принял (запихнул в буфер) - передал. На это он и расчитан. Другую Вы ему даже предложить не сможете. В лучшем случае в прерывании одна команда - вон туда положить. Никаких предворительных ласк делать не надо , как в случае - ВСЁ обрабатывать в прерывании (запихивать в стек регистры ,SREG и прочее, прочее, тратя на эту хрень время) . Вышли и всё остальное время можете тратить на разбор "полётов" . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Часто минимизировать нужно именно время реакции системы, а перекладывание из буфера в буфер скорости не добавит.Оценим на пальцах ДОБАВОЧНУЮ латентность, возникающую при использовании фифо. Максимум один цикл основной программы в случае ТУПОГО суперлупа, а при использовании планировщика или чуть более внятного суперлупа много меньше. Большая задержка? С Вас примеры где это действительно важно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Автору уже советовали конечный автомат - так как он На флажках это дело решать муторно. упёрся в сложность программы. Если он перенесёт "работу с флажками" во внешнюю (по отношению к прерыванию) программы - не поможет... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Но такой подход плох только одним. Появляется привычка. И в следующих, настоящих сложных проектах не будет опыта распределять нагрузку, работать с буферами и прочим. Как это? Все равно ведь работа по прерываниям получше, чем по триггерам и использует ресурсы идеально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Оценим на пальцах ДОБАВОЧНУЮ латентность, возникающую при использовании фифо. Максимум один цикл основной программы в случае ТУПОГО суперлупа, а при использовании планировщика или чуть более внятного суперлупа много меньше. Большая задержка? С Вас примеры где это действительно важно... что, как других дилетантами обзывать так запросто, а как вас, так и обиделись? :) Примеры, да пожалуста: 1. Принимаем команды по наложению OSD, шина RS485 абонентов много, при получении команды не позже чем через нцать мкс (точное число ен помню больше 100 но меньше 500) следует отправить подтверждение приема. Других задач не выполняем. Формирование картинки работает не быстро - суперлуп длинный. Ну и? ради великой самоцели "малосидения в прерывании" делать еще и планировщик с тиком 100мкс? 2. Резервное устройство на батарейном питании, по команде дергаем клапан. Тут ключевой момент даже не время реакции, а потребление, проц работает ТОЛЬКО в прерывании, остальное время дрыхнет, вынос обработки в суперлуп увеличит потребление на величину отличную от нуля. Реальные примеры из практики, а не тупые суперлупы в вакууме. PS продолжим холивар или дадим ТСу решать свою задачу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Demeny 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Размер кольцевого буфера лучше иметь кратным степени 2... А можно пояснить подробнее - в чём преимущество кольцевого буфера с размером, кратным степени 2 ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 4 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Проще закруглять. Одной командой &. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба что, как других дилетантами обзывать так запросто, а как вас, так и обиделись? :)Вовсе нет. Вас лично я и не пытался задеть. PS продолжим холивар или дадим ТСу решать свою задачу?Можем продолжить. 1. У ТС протокол без жёских временных ограничений (и таких протоколов несоизмеримо больше). 2. Кто мешает поставить команду sleep в тело суперлупа и просыпаться по тем же прерываниям уарта? Проще закруглять. Одной командой &. Или % что современные компиляторы хорошо оптимизируют. #define FIFO_SIZE 32 i = (i+1) % FIFO_SIZE; // никремент индекса fifo что будет эквивалентно i = (i+1) & (FIFO_SIZE-1); // никремент индекса fifo в случае когда FIFO_SIZE кратно степени 2. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alt.F4 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 (изменено) · Жалоба Обрабатываю NMEA. Сделал следующим образом: В памяти программ создал таблицу с адресами 25 подпрограмм (из них 16 уникальных), каждая из которых занимается отлавливанием определенного символа или сохранением данных. В прерывании UART запускаем одну из этих подпрограмм по маркеру, который инкрементируется при успешном выполнении подпрограммы, тем самым указывая, что в следующий раз надо будет выполнить другую подпрограмму. Если подпрограмма возвращает ложь, то маркер сбрасывается и в следующий раз будем начинать все сначала. В итоге SRAM - 2 байта (один маркер, другой счетчик символов при сохранении данных), и скорость максимальная. =) Изменено 11 ноября, 2011 пользователем Alt.F4 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться