Jump to content
    

Вопрос со звёздочкой по программным таймерам

Приветствую,

Объясните пожалуйста странное поведение программных таймеров, их полное отключение если в одной из задач есть такой код

		flag = 0;
		HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc, ADC_CYCLES);  // Запускаем ADC на 13мсек
		while( flag == 0 ) {};  // Ждем когда flag = 1 выставит прерывание

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

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

result = xTimerChangePeriod( myTimer02Handle, 2000, 100 ); // Запуск таймера

А коллбэк никогда не срабатывает. И xTimerIsTimerActive() всегда показывает, что таймер не активен.

Лечится проблема

		while( flag == 0 )
			osDelay(1);

 

Share this post


Link to post
Share on other sites

Что-то я ничего не понял, причем тут программные таймеры. 

Если 

 // Ждем когда flag = 1 выставит прерывание

тогда надо, чтобы flag был объявлен как volatile , иначе оптимизация просто выбросит этот цикл while.

 

Share this post


Link to post
Share on other sites

37 minutes ago, Mty said:

Планировщик должен отобрать управление

С какого счастья? Нету в коде на то никакой причины.

Share this post


Link to post
Share on other sites

1 hour ago, EdgeAligned said:

Что-то я ничего не понял, причем тут программные таймеры. 

Если 

 // Ждем когда flag = 1 выставит прерывание

тогда надо, чтобы flag был объявлен как volatile , иначе оптимизация просто выбросит этот цикл while.

 

Да, так и есть
volatile uint8_t flag = 0;

В этом и вопрос - при чем тут таймеры, и почему они гаснут.

23 minutes ago, rkit said:

С какого счастья? Нету в коде на то никакой причины.

Так планировщик отбирает управление по таймеру каждые 1мс.
Вот сейчас сделал пустую задачу.

for(;;)
  {
  }

Все остальные задачи прекрасно работают.

UPD: Все кроме программных таймеров!

Share this post


Link to post
Share on other sites

Таймеры же из какой-то одной задачи обрабатываются во FreeRTOS если правильно помню. Ничего удивительного, что все обработчики останавливаются если в одном безвыходный цикл.

https://www.freertos.org/RTOS-software-timer.html

Quote

Important information on writing timer callback functions

Timer callback functions execute in the context of the timer service task. It is therefore essential that timer callback functions never attempt to block. For example, a timer callback function must not call vTaskDelay(), vTaskDelayUntil(), or specify a non zero block time when accessing a queue or a semaphore.

 

 

Edited by amaora

Share this post


Link to post
Share on other sites

Нет, почему же, все задачи во FreeRTOS должны быть реализованы как безвыходный цикл типа for(;;).

А какие настройки таймеров в системе? То есть, как дефайны прописаны? Ну и мануал на FreeRTOS фпомощь! Free RTOS Book and Reference Manual

Share this post


Link to post
Share on other sites

3 hours ago, amaora said:

Таймеры же из какой-то одной задачи обрабатываются во FreeRTOS если правильно помню. Ничего удивительного, что все обработчики останавливаются если в одном безвыходный цикл.

https://www.freertos.org/RTOS-software-timer.html

 

 

В колбеке нет циклов. Только мигание светодиодом.

1 hour ago, EdgeAligned said:

Нет, почему же, все задачи во FreeRTOS должны быть реализованы как безвыходный цикл типа for(;;).

А какие настройки таймеров в системе? То есть, как дефайны прописаны? Ну и мануал на FreeRTOS фпомощь! Free RTOS Book and Reference Manual

За ссылку спасибо.

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

Share this post


Link to post
Share on other sites

59 minutes ago, Mty said:

В колбеке нет циклов. Только мигание светодиодом.

Тогда сравните приоритет задачи таймеров (configTIMER_TASK_PRIORITY) и приоритет своей задачи с циклом.

Share this post


Link to post
Share on other sites

12 hours ago, amaora said:

Тогда сравните приоритет задачи таймеров (configTIMER_TASK_PRIORITY) и приоритет своей задачи с циклом.

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

Года три назад у знакомых кубопограмистов была такая же фигня, а ларчик открывался просто. Безумный Куб с перепугу создал для STM32F769 аж 57 приоритетов для задач, видимо, обнаружив жирный кристалл. Безумство заключалось в том, что приоритет задачи FreeRTOS, обслуживающей таймеры, был значительно ниже задач пользователя, поэтому задача таймеров срабатывала один раз в 10 минут(!).

20 hours ago, Mty said:
while( flag == 0 ) {};  // Ждем когда flag = 1 выставит прерывание

Будьте вежливы, вызывайте yeild(), а то будете не 10 минут, а 10 часов ждать срабатывания ваших колбэков.

Edited by tonyk_av

Share this post


Link to post
Share on other sites

1 hour ago, tonyk_av said:

у знакомых кубопограмистов была такая же фигня

.

Share this post


Link to post
Share on other sites

3 часа назад, tonyk_av сказал:

Безумный Куб с перепугу создал для STM32F769 аж 57 приоритетов для задач, видимо, обнаружив жирный кристалл. Безумство заключалось в том, что приоритет задачи FreeRTOS, обслуживающей таймеры, был значительно ниже задач пользователя, поэтому задача таймеров срабатывала один раз в 10 минут(!).

Количество реально работающих задач может быть намного меньше максимально разрешённого количества приоритетов задач в OS. И не то (количество реально работающих задач) ни другое (количество приоритетов задач) не имеют никакого отношения к частоте вызова каких-либо задач или сервисов ОС. Пусть будет хоть 200 приоритетов - это не причина срабатывания "раз в 10 минут".

Share this post


Link to post
Share on other sites

7 минут назад, jcxz сказал:

Количество реально работающих задач может быть намного меньше максимально разрешённого количества приоритетов задач в OS. И не то (количество реально работающих задач) ни другое (количество приоритетов задач) не имеют никакого отношения к частоте вызова каких-либо задач или сервисов ОС. Пусть будет хоть 200 приоритетов - это не причина срабатывания "раз в 10 минут".

Это да, но и плодить приоритеты не стоит - как-никак, для кадого приоритета создается своя очередь в ядре ОС, по которым шедулер будет пробегаться - а это время/такты.

Share this post


Link to post
Share on other sites

2 минуты назад, Arlleex сказал:

Это да, но и плодить приоритеты не стоит - как-никак, для кадого приоритета создается своя очередь в ядре ОС, по которым шедулер будет пробегаться - а это время/такты.

Приоритеты не занятые задачами имеете в виду? Разве имеет большое значение - сколько их?

Не знаю как там устроено во FreeRTOS, но у меня, в моей ОС очередь приоритетов = это одно 32-битное значение. С битиками установленными в лог.1 в позициях задач, готовых выполняться. Соответственно - выбор шедулером задачи на выполнение - одна команда CLZ. Скорость выполнения которой всегда одинакова. Конечно - если надо больше задач, то надо будет несколько 32-битных слов. Но рост затрат времени шедулера с ростом числа приоритетов - будет довольно медленный (через каждые 32 приоритета).

И я ограничил число задач в своей ОС <= 31 задача(или приоритет) (32-я задача - системная idle-задача). Исходя из моего многолетнего опыта с МК - этого вполне достаточно. Ни разу не встречалось программ, требующих более 31-го приоритета задач.

Share this post


Link to post
Share on other sites

32 minutes ago, jcxz said:

Пусть будет хоть 200 приоритетов - это не причина срабатывания "раз в 10 минут".

Так я писал о том, что задача таймера ОС имела значительно, в разы меньший приоритет поэтому очередь до её запуска доходила редко.

Share this post


Link to post
Share on other sites

19 минут назад, jcxz сказал:

Не знаю как там устроено во FreeRTOS...

Во FreeRTOS под каждый приоритет создается двусвязный список. Туда добавляются/удаляются задачи соответствующих приоритетов при их готовности к обслуживанию шедулером. Шедулер пробегается по массиву списков - поэтому чем больше приоритетов, тем массив имеет большую размерность.
 

Цитата

Ни разу не встречалось программ, требующих более 31-го приоритета задач.

Мне тоже.

В Вашем случае, получается, не может быть >1 задач с одинаковыми приоритетами. У всех разные?

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.

×
×
  • Create New...