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

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

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

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

		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);

 

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


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

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

Если 

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

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

 

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


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

37 minutes ago, Mty said:

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

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

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


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

1 hour ago, EdgeAligned said:

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

Если 

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

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

 

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

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

23 minutes ago, rkit said:

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

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

for(;;)
  {
  }

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

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

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


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

Таймеры же из какой-то одной задачи обрабатываются во 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.

 

 

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

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


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

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

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

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


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

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 не запускается.
В колбэке для теста только мигание светодиодом.

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


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

59 minutes ago, Mty said:

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

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

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


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

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 часов ждать срабатывания ваших колбэков.

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

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


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

1 hour ago, tonyk_av said:

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

.

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


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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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


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

32 minutes ago, jcxz said:

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

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

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


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

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

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

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

Цитата

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

Мне тоже.

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

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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