Mty 0 8 июня Опубликовано 8 июня · Жалоба Приветствую, Объясните пожалуйста странное поведение программных таймеров, их полное отключение если в одной из задач есть такой код 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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 85 8 июня Опубликовано 8 июня · Жалоба Что-то я ничего не понял, причем тут программные таймеры. Если // Ждем когда flag = 1 выставит прерывание тогда надо, чтобы flag был объявлен как volatile , иначе оптимизация просто выбросит этот цикл while. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rkit 4 8 июня Опубликовано 8 июня · Жалоба 37 minutes ago, Mty said: Планировщик должен отобрать управление С какого счастья? Нету в коде на то никакой причины. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mty 0 8 июня Опубликовано 8 июня · Жалоба 1 hour ago, EdgeAligned said: Что-то я ничего не понял, причем тут программные таймеры. Если // Ждем когда flag = 1 выставит прерывание тогда надо, чтобы flag был объявлен как volatile , иначе оптимизация просто выбросит этот цикл while. Да, так и есть volatile uint8_t flag = 0; В этом и вопрос - при чем тут таймеры, и почему они гаснут. 23 minutes ago, rkit said: С какого счастья? Нету в коде на то никакой причины. Так планировщик отбирает управление по таймеру каждые 1мс. Вот сейчас сделал пустую задачу. for(;;) { } Все остальные задачи прекрасно работают. UPD: Все кроме программных таймеров! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 24 8 июня Опубликовано 8 июня (изменено) · Жалоба Таймеры же из какой-то одной задачи обрабатываются во 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. Изменено 8 июня пользователем amaora Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
EdgeAligned 85 8 июня Опубликовано 8 июня · Жалоба Нет, почему же, все задачи во FreeRTOS должны быть реализованы как безвыходный цикл типа for(;;). А какие настройки таймеров в системе? То есть, как дефайны прописаны? Ну и мануал на FreeRTOS фпомощь! Free RTOS Book and Reference Manual Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mty 0 8 июня Опубликовано 8 июня · Жалоба 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 не запускается. В колбэке для теста только мигание светодиодом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 24 8 июня Опубликовано 8 июня · Жалоба 59 minutes ago, Mty said: В колбеке нет циклов. Только мигание светодиодом. Тогда сравните приоритет задачи таймеров (configTIMER_TASK_PRIORITY) и приоритет своей задачи с циклом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 43 9 июня Опубликовано 9 июня (изменено) · Жалоба 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 часов ждать срабатывания ваших колбэков. Изменено 9 июня пользователем tonyk_av Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 56 9 июня Опубликовано 9 июня · Жалоба 1 hour ago, tonyk_av said: у знакомых кубопограмистов была такая же фигня . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 9 июня Опубликовано 9 июня · Жалоба 3 часа назад, tonyk_av сказал: Безумный Куб с перепугу создал для STM32F769 аж 57 приоритетов для задач, видимо, обнаружив жирный кристалл. Безумство заключалось в том, что приоритет задачи FreeRTOS, обслуживающей таймеры, был значительно ниже задач пользователя, поэтому задача таймеров срабатывала один раз в 10 минут(!). Количество реально работающих задач может быть намного меньше максимально разрешённого количества приоритетов задач в OS. И не то (количество реально работающих задач) ни другое (количество приоритетов задач) не имеют никакого отношения к частоте вызова каких-либо задач или сервисов ОС. Пусть будет хоть 200 приоритетов - это не причина срабатывания "раз в 10 минут". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 9 июня Опубликовано 9 июня · Жалоба 7 минут назад, jcxz сказал: Количество реально работающих задач может быть намного меньше максимально разрешённого количества приоритетов задач в OS. И не то (количество реально работающих задач) ни другое (количество приоритетов задач) не имеют никакого отношения к частоте вызова каких-либо задач или сервисов ОС. Пусть будет хоть 200 приоритетов - это не причина срабатывания "раз в 10 минут". Это да, но и плодить приоритеты не стоит - как-никак, для кадого приоритета создается своя очередь в ядре ОС, по которым шедулер будет пробегаться - а это время/такты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 9 июня Опубликовано 9 июня · Жалоба 2 минуты назад, Arlleex сказал: Это да, но и плодить приоритеты не стоит - как-никак, для кадого приоритета создается своя очередь в ядре ОС, по которым шедулер будет пробегаться - а это время/такты. Приоритеты не занятые задачами имеете в виду? Разве имеет большое значение - сколько их? Не знаю как там устроено во FreeRTOS, но у меня, в моей ОС очередь приоритетов = это одно 32-битное значение. С битиками установленными в лог.1 в позициях задач, готовых выполняться. Соответственно - выбор шедулером задачи на выполнение - одна команда CLZ. Скорость выполнения которой всегда одинакова. Конечно - если надо больше задач, то надо будет несколько 32-битных слов. Но рост затрат времени шедулера с ростом числа приоритетов - будет довольно медленный (через каждые 32 приоритета). И я ограничил число задач в своей ОС <= 31 задача(или приоритет) (32-я задача - системная idle-задача). Исходя из моего многолетнего опыта с МК - этого вполне достаточно. Ни разу не встречалось программ, требующих более 31-го приоритета задач. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 43 9 июня Опубликовано 9 июня · Жалоба 32 minutes ago, jcxz said: Пусть будет хоть 200 приоритетов - это не причина срабатывания "раз в 10 минут". Так я писал о том, что задача таймера ОС имела значительно, в разы меньший приоритет поэтому очередь до её запуска доходила редко. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 9 июня Опубликовано 9 июня · Жалоба 19 минут назад, jcxz сказал: Не знаю как там устроено во FreeRTOS... Во FreeRTOS под каждый приоритет создается двусвязный список. Туда добавляются/удаляются задачи соответствующих приоритетов при их готовности к обслуживанию шедулером. Шедулер пробегается по массиву списков - поэтому чем больше приоритетов, тем массив имеет большую размерность. Цитата Ни разу не встречалось программ, требующих более 31-го приоритета задач. Мне тоже. В Вашем случае, получается, не может быть >1 задач с одинаковыми приоритетами. У всех разные? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться