Jump to content

    
Sign in to follow this  
jenya7

Как лучше оформить таск?

Recommended Posts

Вопрос наверно надо перефразировать так: 
Как сделать инициализацию периферии в RTOS и не убиться об неявные зависимости.?  

Надо думать, что скопление всей инициализации в одном месте это такой способ не забыть про зависимости. 
Но на мой взгляд ничего лучше комментариев для учета зависмостей не придумано. 
Поэтому если в сорсах нет комментариев или какой-то другой метаинформации, то никакие перетасовки не помогут. Грабли все равно автора найдут.   

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

Share this post


Link to post
Share on other sites
8 hours ago, AlexandrY said:

Поэтому профессионалы инициализируют не последовательно, а параллельно в разных задачах.

Сколько людей, столько и гуру программирования.

Share this post


Link to post
Share on other sites

Инициализация периферии, используемой задачей, непосредственно в задаче, по моему опыту, упрощает последующий librarianing и повторное использование кода. 

1. main инициализирует общие (тактирование, ДМА...) блоки, создает задачу-демона с приоритетом Idle , стартует шедулер.

2. задача-демон создает остальные задачи (уже в контексте ОС) по зависимостям, а потом либо умирает, либо работает (у меня обычно обрабатывает статистику работы устройства).

3. каждая задача инициализирует под свои нужды аппаратуру.

Share this post


Link to post
Share on other sites
7 minutes ago, Andrew_Q said:

1. main инициализирует общие (тактирование, ДМА...)

У меня эту периферию инициализируют те драйвера, которые используют тот же ПДП. Т.е. драйвера инициализируют друг-друга при необходимости.

8 minutes ago, Andrew_Q said:

либо работает (у меня обычно обрабатывает статистику работы устройства).

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

8 minutes ago, Andrew_Q said:

каждая задача инициализирует под свои нужды аппаратуру.

Да, всё так)

Share this post


Link to post
Share on other sites
8 минут назад, haker_fox сказал:

У меня эту периферию инициализируют те драйвера, которые используют тот же ПДП. Т.е. драйвера инициализируют друг-друга при необходимости.

Я говорю о настройке самого модуля ПДП (он у меня один на три ядра), а каналы да, в задачах. Хотя да, можно проверять в драйвере поднят ли ПДП... Надо это поносить в голове.

10 минут назад, haker_fox сказал:

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

Да, есть такой хук, но как-то исторически сложилось... Да и своя задача на приоритете Idle всегда находит много "бестолковой" работы. :-)

Share this post


Link to post
Share on other sites
10 minutes ago, Andrew_Q said:

Я говорю о настройке самого модуля ПДП (он у меня один на три ядра)

Да хоть на десять ядер) Зато драйвер универсальный будет. Вызвали init или open в одном месте, и точно знаете, что он у вас открыт или нет. И таких место может быть несколько.

10 minutes ago, Andrew_Q said:

а каналы да, в задачах.

У меня так.

13 minutes ago, Andrew_Q said:

но как-то исторически сложилось..

Понятно)

Share this post


Link to post
Share on other sites

Мне одно интересно...
Неужто под МК проекты настолько толстые пишутся, что перенос инициализации периферии в задачи RTOS существенно влияет на восприятие кода и его фактическую эффективность? ИМХО, в большинстве случаев проект не реализует больше десятка задач, а круг используемой периферии ограничивается тем же десятком... Исходя из чисто моего опыта скажу, что мне крайне редко приходилось работать с периферией так, что ее нужно переинициализировать глобально, требуя thread-safety кода при работе с ней. GPIO с атомарным доступом - тема отдельная и ее в расчет не берем. Но, Карл! Вот, висит на SPI какой-нибудь дисплейчик. Ну неужели драйвер этого дисплея должен каким-то образом (на лету) изменить настройки этого SPI? Именно поэтому считаю, что в 99.9% случаев всю периферию можно настроить в main(), оформив только вызовом единственной функции. А если периферия пользуется сервисами RTOS, то, как уже заметили, достаточно перетащить вызов функции инициализации всего железа в демон.
Мне подход с инициализацией конкретной периферии под нужды конкретного потока нравится духом модульности и законченности. И синтаксически.
Но грешу, бывает, и тупым init()-ом прямо в main(), и не вижу в этом ничего плохого.

Share this post


Link to post
Share on other sites
2 минуты назад, Arlleex сказал:

Мне одно интересно...

Тут дело не только в сложности периферии, хотя это сегодня тоже имеет значение если Вы пишите для контроллеров с сильно навороченной периферией, а, в основном, если Вы работаете над проектом в команде, либо экспортируете свое ПО в другие проекты. Время!!!

Share this post


Link to post
Share on other sites
6 minutes ago, Arlleex said:

Ну неужели драйвер этого дисплея должен каким-то образом (на лету) изменить настройки этого SPI?

Да, может) Если на этой же шине висит другой приёмник SPI, имеющий либо другие скоростные характеристики, либо другой режим работы.

7 minutes ago, Arlleex said:

RTOS существенно влияет на восприятие кода и его фактическую эффективность?

Ну и дело привычки ещё)

Share this post


Link to post
Share on other sites
17 минут назад, haker_fox сказал:

Да, может) Если на этой же шине висит другой приёмник SPI, имеющий либо другие скоростные характеристики, либо другой режим работы.

Я понимаю, что это вполне корректный пример.
Но я, например, всегда старался и стараюсь такого избегать на аппаратном уровне.
При возможности, цепляю внешнюю периферию на разные интерфейсы.
Если это сделать невозможно, цепляю на один ту периферию, которая имеет одинаковые режимы и сопоставимые скорости.
Если и это невозможно - тогда да, драйвер должен быть довольно умным и переинициализировать все при необходимости.
Ну а I2C? В большинстве случаев все, что может поменяться - это скорость. А почти все устройства ныне поддерживают 400кГц.

Share this post


Link to post
Share on other sites
3 minutes ago, Arlleex said:

и стараюсь такого избегать на аппаратном уровне.

Ну так этим и различаются настоящие мастера своего дела: разными подходами, дающими превосходный результат)))

4 minutes ago, Arlleex said:

Если и это невозможно - тогда да, драйвер должен быть довольно умным и переинициализировать все при необходимости.

Конкретно в SPI, создаётся базовый класс, от него наследуются реальный драйвер, работающий с рельным железом. И виртуальные драйвера, которые работают с одним железным (переключая CS и другие настройки). Вся периферия работает с виртуальными драйверами. Ну это я так делаю)

5 minutes ago, Arlleex said:

Ну а I2C?

У неё ничего не меняется в наших проектах. Но инициализируется всё равно в каждом драйвере, который работает с шиной: драйвер часов, драйвер расширителя портов, драйвер зарядника и т.п.

Share this post


Link to post
Share on other sites
5 минут назад, Arlleex сказал:

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

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

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

Share this post


Link to post
Share on other sites
1 minute ago, Andrew_Q said:

а то что подключается к плате? 

О, у меня на длиннющей колбасе из SPI (дислпей, два NOR, два АЦП) ещё висел разъём для микросд) Помню натра проявлял смекалку, чтобы всё это надёжно работало)

2 minutes ago, Andrew_Q said:

который выбирается при конфигурировании устройства

Ещё был случай, когда в одноу и ту же плату с одним и тем же ПО запаявали на производстве разные микросхемы памяти (ну так вышло из-за снаблжения), при загрузке прибора как в виндах определялся тип памяти, объём и т.п., и загружался нужный драйвер.

Share this post


Link to post
Share on other sites
1 hour ago, Arlleex said:

Мне одно интересно...
Неужто под МК проекты настолько толстые пишутся, что перенос инициализации периферии в задачи RTOS существенно влияет на восприятие кода и его фактическую эффективность? ИМХО, в большинстве случаев проект не реализует больше десятка задач, а круг используемой периферии ограничивается тем же десятком... 

Откуда так мало периферии? 
Не в самом крутом uC на Cortex-M4 не меньше 50 разных периферий.
Тот же DMA имеет зависимости от DMA MUX, AIPS, MCG, AXBS и т.д. Многие зависимости даже неочевидны их приходится исследовать. 
Среднее количество файлов в проекте с развитой RTOS не менее 1000. Так что заблудиться есть где. 

А по поводу SPI, то выбирать uC надо с умом. Не сидеть на одном STM-е. 
Есть чипы где автоматом на SPI переключается формат, битность и скорость  фрейма  в зависимости от активного CS. Ничего програмить не надо.  

 

 

Share this post


Link to post
Share on other sites
6 minutes ago, AlexandrY said:

меньше 50 разных периферий

Огласите весь список, пожалуйста)

6 minutes ago, AlexandrY said:

Есть чипы где автоматом на SPI переключается формат

Renesas или Kinetic?:dance3:

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this