Перейти к содержанию
    

Работа с медленной периферией

Использую микроконтроллер на процессорном ядре Cortex-M4F - STM32F429.

Программа построена на основе ОСРВ FreeRTOS.

Есть 5 независимых задач, внутри которых обрабатываются некоторые массивы данных.

Есть аппаратные прерывания от таймеров с жесткой временной диаграммой, нарушать которую нельзя: через равные отрезки времени считываются данные с полутора десятков внешних АЦП по SPI, при этом сами таймеры формируют управление CS этих АЦП, а также сам цикл чтения из SPI данных. По завершению сканирования (около 200 выборок) выдается семафор в приоритетную задачу FreeRTOS о готовности результата.

Одна из задач отвечает за опрос датчиков температуры DS18B20, подключенной к обычной линии GPIO (не к UART-у), т.е. вся организация протокола 1-Wire программная. Я решил, что настраивать прерывания для временных параметров таймслотов слишком накладно и непроизводительно, поэтому сделал опрос флагов совпадения таймера и рулил ножкой GPIO в низкоприоритетной задаче RTOS. Однако логично было предположить (а позже и убедиться на отладочной плате), что высокоприоритетные задачи могут перебить эту задачу, например, в момент таймслота чтения, и целостность временного отрезка таймслота будет нарушена - считаются неправильные данные.

Поместил обращения с датчиком в критическую секцию, но сам понимаю что это так себе выход - времянка более приоритетных прерываний таймера для АЦП куда важнее, поэтому никаких критических секций быть не должно. И тут я задумался: а как вообще в таких ситуациях поступать? То есть как обслуживать низкоскоростной интерфейс, временную диаграмму которого нельзя перебивать для корректной работы, в то же время не повышая приоритет задачи, в которой работает опрос датчиков, и тем более, не вводя критические секции? Ведь как бы получается самоблокирующие критерии расстановки приоритетов задач...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Если не переписывать сильно код, то как вариант: снять статистику всех происходящих событий (например, бесплатная SystemView от Segger) и оптимизировать код под эти данные.

Другой вариант: для медленных программных интерфейсов использовать аппаратные таймеры, благо в таких толстых камнях таймеров выше крыши.

Ну и классический совет для любой системы - убирать из обработчиков прерываний длительные расчеты и действия, вынося их в фон задач, "пробуждая" их соотв. сервисами ОС.

Нельзя забывать про DMA, которая, например, отлично подходит для опроса кучи каналов АЦП.

Т.е. в сильно перегруженной системе нужно переносить программные дела в аппаратные по максимуму.

 

через равные отрезки времени считываются данные с полутора десятков внешних АЦП по SPI, при этом сами таймеры формируют управление CS этих АЦП, а также сам цикл чтения из SPI данных.

В данном случае скорее всего подключать схемотехников для переделки платы. Я бы ставил отдельный дешевый контроллер, который бы делал подобную "тупую" работу.

Как вариант, возможно, стоило сразу ставить двухядерный Cortex, например от NXP.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно, времени, чтобы прочитать все данные с внешних устройств, обработать их и выдать результат, куда надо, должно хватать. Если так, проблемы нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По АЦП в принципе согласен. У меня примерно та же картина была и я расчитывал, оказалось, что при spi 2MHz нет смысла городить огород. Накладные расходы по усложнению обработки режут всё в 0. То есть придётся смирится. Можно попробовать организовать аппаратно... Я не пробовал, если честно. У меня правда лишь один АЦП. Это упрощает.

По 1820 картина попроще на самом деле. Если почитаете, то там диаграмма по всем слотам может в 2 раза отличаться, так что там критичного ничего нет. Формируйте диаграмму по прерыванию от таймера.

1820 уже не рекомендуют к применению. Это раньше был чудо прибор. Лет 10 назад. А сейчас лучше применять TI. И дешевле и точнее и удобнее.

 

А в целом, тоже склоняюсь к варианту с периферийным процессором. Такие решения делал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Другой вариант: для медленных программных интерфейсов использовать аппаратные таймеры, благо в таких толстых камнях таймеров выше крыши.

Один аппаратный таймер задействован как раз для формирования временной диаграммы опроса АЦП. В обработчиках прерываний по совпадению и переполнению построена логика небольшого конечного автомата, который:

1) опускает линии CS необходимых АЦП;

2) выжидает минимальное допустимое время между активизацией CS и первым импульсом синхронизации SCK;

3) отправляет посылку по SPI в АЦП (при этом предполагая, что посылка точно отправится за конечное время);

4) читает данные в буфер;

5) выжидает минимальное допустимое время между последним синхроимпульсом SCK и деактивацией CS АЦП;

6) выдает семафор в приоритетную задачу о том, что можно производить расчет на текущем шаге (заложено математикой процесса).

 

Последний пункт как раз и гарантирует, что вычисление (как времязатратный процесс) производится не в прерывании (на самом деле это довольно очевидные вещи).

Насчет DMA - к сожалению это не вариант, поскольку АЦП - внешние микросхемы (если Вы, конечно, имели в виду внутренний АЦП МК - то там да, я бы задействовал DMA и только).

 

Таким же образом хотел сделать конечный автомат обслуживания таймслотов 1-Wire на прерываниях аппаратного таймера: но тут есть но - можно прикинуть накладные расходы по времени входа в прерывание по отношению к полезному времени:

- частота работы МК - 180МГц; значит на вход/выход в/из прерывания будет составлять 0,133(3)мкс (24 такта);

- для DS18B20 характерны времена, кратные 1мкс, поэтому в худшем случае получаем 1/0,133(3) = 7,5 полезных команд в теле обработчика прерывания.

Короче говоря, не густо, микросекундные прерывания в топку сразу (хотя это тоже понятно на самом деле, микросекундные прерывания это верх кощунства по отношению к МК).

 

В общем, скорее всего, я думаю, что я растяну таймслоты для 1-Wire, немного потеряется скорость обмена (но это не критично). Благо интерфейс позволяет забить на шину пока там лог. 1 - то есть все подчиненные ждут следующего пинка.

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

- для DS18B20 характерны времена, кратные 1мкс, поэтому в худшем случае получаем 1/0,133(3) = 7,5 полезных команд в теле обработчика прерывания.

Зачем дергать прерывания раз в 1мкс? :01:

У 1-wire все времена указаны как минимум от 15мкс.

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

Поищите исходники готового 1wire на одном аппаратном таймере, благо, тема избитая и обсосанная неоднократно. Интерфейс этот действительно очень архаичный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

..задач отвечает за опрос датчиков температуры DS18B20..

 

Если Вы внимательно посмотрите на диаграммы данного датчика, то

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

2) из опыта - всего таких критичных участка два. время между стробом чтения и самим чтением слота. и время между началом формирования и выхода из записи единички при записи в слот. всё остальное,

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

3) вычисление результата делаете в задаче, а не в обработчике.

4) все обработчики делаете лаконичными.

 

 

удачи вам

(круглый)

ЗЫ

у меня в проекте на F4 крутиться ниток 15, и датчиков сканируется штук 8 постоянно. проблем нет...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1-wire удобно делается на уарте...

 

если поделка, типа померять температуру любимого проца - то да.

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

 

(круглый)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

.... юарт мягко говоря убогость...

(круглый)

Не, ошибкой было назвать 1Wire медленной периферией, а потом выводить ее на GPIO.

После чего героически бороться за прерывания в контексте RTOS, где их цена выше чем на bare metal.

Самое гибкое ИМХО решение - это использовать capture/compare функции таймеров и DMA

Тут надо помнить, что прывания не поддаются планировке на подобии задач и для них не действует правило 70%

Прерывания все надо профайлить до такта чтобы узнать бюджет задержек, что автор как бы и начал делать, но видимо решил, что и так сойдёт. Т.е. продолжает цепь ошибок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Самое гибкое ИМХО решение - это использовать capture/compare функции таймеров и DMA ..

 

в плоскости сканирования за одно обращение сразу X (скажем 8) датчиков - раскройте тему... как будет выглядеть реализация захвата? или это такой тонкий стёб? :)

Изменено пользователем kolobok0

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в плоскости сканирования за одно обращение сразу X (скажем 8) датчиков - раскройте тему... как будет выглядеть реализация захвата? или это такой тонкий стёб? :)

Я же написал ИМХО, т.е. утверждение не предусматривает доказательств.

Хотите , можете опровергнуть. :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Зачем мне вечная игла для примуса? :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я же написал ИМХО, ...

 

а я было возбудился - думал ышо какой хитропопный способ можно придумать для оптимальности... DMA - да заманчиво. но протокол двунаправленный и имхо - в конечном счёте всё выливается опять в обработку на прерывании.

 

у мну прописаны

reset - 3 фазы

read - 3 фазы

write - 3 фазы

wait - 1 фаза

loop - 1 фаза

stop - 1 фаза

start calculated - 1 фаза

wait calculated - 1 фаза

 

ну и чистые замороты для ds1821

изменение направления - 1 фаза

выключение питания - 1 фаза

сброс логики термостата - 3 фазы

включение питалова - 1 фаза

 

ну и далее тупо набираем под нужный сценарий нужные команды.

прерывание от таймера тупо отрабатывает очередную команду.

кол-во датчиков определяется дефайнами (от 1 до 8 штук, но можно на все лапы мк)

 

по такой схеме работает не только на stm-ках, но и на avr, 51 серии. Изменен код только с учётом скорострельности камней.

 

с новым годом

(круглый)

 

 

Зачем мне вечная игла ..

 

ну вот таки да - заказчик с примусами больше.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну вот таки да - заказчик с примусами больше.

Фу, грубиян.

Хотя да, я бы попроще сделал...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...