|
|
|
Работа с медленной периферией |
|
|
|
Dec 28 2017, 17:52
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Использую микроконтроллер на процессорном ядре Cortex-M4F - STM32F429. Программа построена на основе ОСРВ FreeRTOS. Есть 5 независимых задач, внутри которых обрабатываются некоторые массивы данных. Есть аппаратные прерывания от таймеров с жесткой временной диаграммой, нарушать которую нельзя: через равные отрезки времени считываются данные с полутора десятков внешних АЦП по SPI, при этом сами таймеры формируют управление CS этих АЦП, а также сам цикл чтения из SPI данных. По завершению сканирования (около 200 выборок) выдается семафор в приоритетную задачу FreeRTOS о готовности результата. Одна из задач отвечает за опрос датчиков температуры DS18B20, подключенной к обычной линии GPIO (не к UART-у), т.е. вся организация протокола 1-Wire программная. Я решил, что настраивать прерывания для временных параметров таймслотов слишком накладно и непроизводительно, поэтому сделал опрос флагов совпадения таймера и рулил ножкой GPIO в низкоприоритетной задаче RTOS. Однако логично было предположить (а позже и убедиться на отладочной плате), что высокоприоритетные задачи могут перебить эту задачу, например, в момент таймслота чтения, и целостность временного отрезка таймслота будет нарушена - считаются неправильные данные. Поместил обращения с датчиком в критическую секцию, но сам понимаю что это так себе выход - времянка более приоритетных прерываний таймера для АЦП куда важнее, поэтому никаких критических секций быть не должно. И тут я задумался: а как вообще в таких ситуациях поступать? То есть как обслуживать низкоскоростной интерфейс, временную диаграмму которого нельзя перебивать для корректной работы, в то же время не повышая приоритет задачи, в которой работает опрос датчиков, и тем более, не вводя критические секции? Ведь как бы получается самоблокирующие критерии расстановки приоритетов задач...
|
|
|
|
|
Dec 28 2017, 18:17
|
Профессионал
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831
|
Цитата(Arlleex @ Dec 28 2017, 20:52) То есть как обслуживать низкоскоростной интерфейс, временную диаграмму которого нельзя перебивать для корректной работы, в то же время не повышая приоритет задачи, в которой работает опрос датчиков, и тем более, не вводя критические секции? Если не переписывать сильно код, то как вариант: снять статистику всех происходящих событий (например, бесплатная SystemView от Segger) и оптимизировать код под эти данные. Другой вариант: для медленных программных интерфейсов использовать аппаратные таймеры, благо в таких толстых камнях таймеров выше крыши. Ну и классический совет для любой системы - убирать из обработчиков прерываний длительные расчеты и действия, вынося их в фон задач, "пробуждая" их соотв. сервисами ОС. Нельзя забывать про DMA, которая, например, отлично подходит для опроса кучи каналов АЦП. Т.е. в сильно перегруженной системе нужно переносить программные дела в аппаратные по максимуму. Цитата(Arlleex @ Dec 28 2017, 20:52) через равные отрезки времени считываются данные с полутора десятков внешних АЦП по SPI, при этом сами таймеры формируют управление CS этих АЦП, а также сам цикл чтения из SPI данных. В данном случае скорее всего подключать схемотехников для переделки платы. Я бы ставил отдельный дешевый контроллер, который бы делал подобную "тупую" работу. Как вариант, возможно, стоило сразу ставить двухядерный Cortex, например от NXP.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Dec 28 2017, 20:26
|
Местный
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264
|
Цитата Другой вариант: для медленных программных интерфейсов использовать аппаратные таймеры, благо в таких толстых камнях таймеров выше крыши. Один аппаратный таймер задействован как раз для формирования временной диаграммы опроса АЦП. В обработчиках прерываний по совпадению и переполнению построена логика небольшого конечного автомата, который: 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 - Dec 28 2017, 20:32
|
|
|
|
|
Dec 28 2017, 20:53
|
Профессионал
Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831
|
Цитата(Arlleex @ Dec 28 2017, 23:26) - для DS18B20 характерны времена, кратные 1мкс, поэтому в худшем случае получаем 1/0,133(3) = 7,5 полезных команд в теле обработчика прерывания. Зачем дергать прерывания раз в 1мкс? У 1-wire все времена указаны как минимум от 15мкс. Таймер можно перенастраивать "на ходу", используя, конечно, "теневые" регистры. Поищите исходники готового 1wire на одном аппаратном таймере, благо, тема избитая и обсосанная неоднократно. Интерфейс этот действительно очень архаичный.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Dec 28 2017, 21:06
|
практикующий тех. волшебник
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417
|
Цитата(Arlleex @ Dec 28 2017, 20:52) ..задач отвечает за опрос датчиков температуры DS18B20.. Если Вы внимательно посмотрите на диаграммы данного датчика, то 1) нет необходимости все времена чего то ждать. достаточно выделить критичные ко времени участки выполнения и засунуть их в обработчик таймера. 2) из опыта - всего таких критичных участка два. время между стробом чтения и самим чтением слота. и время между началом формирования и выхода из записи единички при записи в слот. всё остальное, даже если будет немного плавать не критично. 3) вычисление результата делаете в задаче, а не в обработчике. 4) все обработчики делаете лаконичными. удачи вам (круглый) ЗЫ у меня в проекте на F4 крутиться ниток 15, и датчиков сканируется штук 8 постоянно. проблем нет...
|
|
|
|
|
Dec 29 2017, 07:36
|
практикующий тех. волшебник
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417
|
Цитата(scifi @ Dec 29 2017, 10:01) 1-wire удобно делается на уарте... если поделка, типа померять температуру любимого проца - то да. если надо каждую секунду иметь картину по нескольким точкам сразу - то юарт мягко говоря убогость... (круглый)
|
|
|
|
|
Dec 29 2017, 07:50
|
Ally
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050
|
Цитата(kolobok0 @ Dec 29 2017, 09:36) .... юарт мягко говоря убогость... (круглый) Не, ошибкой было назвать 1Wire медленной периферией, а потом выводить ее на GPIO. После чего героически бороться за прерывания в контексте RTOS, где их цена выше чем на bare metal. Самое гибкое ИМХО решение - это использовать capture/compare функции таймеров и DMA Тут надо помнить, что прывания не поддаются планировке на подобии задач и для них не действует правило 70% Прерывания все надо профайлить до такта чтобы узнать бюджет задержек, что автор как бы и начал делать, но видимо решил, что и так сойдёт. Т.е. продолжает цепь ошибок.
|
|
|
|
|
Dec 29 2017, 08:26
|
практикующий тех. волшебник
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417
|
Цитата(AlexandrY @ Dec 29 2017, 11:10) Я же написал ИМХО, ... а я было возбудился - думал ышо какой хитропопный способ можно придумать для оптимальности... 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 серии. Изменен код только с учётом скорострельности камней. с новым годом (круглый) Цитата(scifi @ Dec 29 2017, 11:12) Зачем мне вечная игла .. ну вот таки да - заказчик с примусами больше.
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|