Spider 0 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба Всем привет. Столкнулся со странной фигнёй. Пытаюсь заставить freeRTOS работать в режиме TickLess на базе её собственного кода для SysTick процессоров ARM M4F (в частности STM32F401CC). Создаю по сути пустой проект с 1 таском, настраиваю и запускаю. И что же я вижу? Что, сразу после wfi продолжается исполнение кода без каких-то намёков на сон. Что может его будить? Дано: 1. gcc компилятор 2. Процессор STM32F401CC 3. абсолютно пустой проект 3.a freeRTOS TICKLESS 3.b GPIO все в Analog 3.c Task с wile loop vTaskDelay(pvMAX_DELAY); из коробки у freeRTOS есть порт под GCC CM4F с функцией vPortSuppressTicksAndSleep() внутри которой настраивается SYSTICK на нужную длительность (до 200ms макс) и засыпаем по wfi. Но вот тут то он и не засыпает, а продолжает работать дальше. При этом флага прерывания в SYSTICK->CSR нет. Значение счётчика сдвинулось на крупицу. Как узнать кто нас разбудил?! И засыпали ли? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба 4 часа назад, Spider сказал: Создаю по сути пустой проект с 1 таском, настраиваю и запускаю. И что же я вижу? Что, сразу после wfi продолжается исполнение кода без каких-то намёков на сон. Что может его будить? И каким же образом Вы это видите? Уж не под отладчиком ли? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spider 0 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба 58 minutes ago, jcxz said: И каким же образом Вы это видите? Уж не под отладчиком ли? Ногодрыгом на осциле. ЗЫ. Я тут кое чего достиг, и даже под отладчиком! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spider 0 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба Методом проб и ошибок выяснил, что wfi теряет свой функционал, если freeRTOS вызывает portENTER_CRITICAL(), в частности влияет конкретно вызов portDISABLE_INTERRUPTS(), маскирует прерывания по приоритетам. А freeRTOS именно это и делает перед тем как уйти в сон по wfi. И вот тут какая то странность. В результате наличия маски по прерываниям wfi начинает СРАЗУ же выходить из сна, если вообще входит в него.... Если же сделать portEXIT_CRITICAL() перед тем как выполнить wfi, то всё работает. Но! Разве так должно быть? Или я что-то не так делаю? Или не понимаю чего-то? Хотелось бы понять что я упускаю..... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба 27 минут назад, Spider сказал: Хотелось бы понять что я упускаю..... Упускаете чтение документации на используемый процессор и его систему команд. Если бы прочитали её, то узнали бы, что: "An asynchronous exception at a priority that, if PRIMASK was set to 0, would preempt any currently active exceptions. The processor ignores the value of PRIMASK in determining whether an asynchronous exception is a WFI wakeup event." "A processor can exit the low-power state spuriously, or because of debug, or for some IMPLEMENTATION-DEFINED reason." PS: Разбирайтесь с активными запросами прерываний. Которые у вас торчат в NVIC и заставляют CPU пробуждаться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spider 0 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба Это как раз я и прочитал. Но активных прерываний то нет. Вот в чём беда. А он всё равно выходит из сна. Сейчас попробовал сделать вместо primask запрет прерываний по cpsid и ровно та же ситуация - выход из wfi мгновенный. Как так? В то же время, если разрешить ВСЕ прерывания или же размаскировать ВСЕ прерыавания, то и прерываний не вызывается и WFI работает. Я ещё что-то не прочитал что бы это означало? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба 7 минут назад, Spider сказал: Как так? В то же время, если разрешить ВСЕ прерывания или же размаскировать ВСЕ прерыавания, то и прерываний не вызывается и WFI работает. Я ещё что-то не прочитал что бы это означало? Так а зачем их запрещать? Какой смысл? WFI/WFE как правило - должна выполняться в самом низкоприоритетном процессе. Idle-процессе. Нет никакого смысла запрещать там прерывания. PS: И почему используете WFI, а не WFE? Я всегда использую WFE. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spider 0 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба Ну так оно написано в freeRTOS. Думалось, что это написано знающими людьми и оно написано так давно, что наверное работает раз имеет место быть. Вот тут, если быть точнее: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/d5a10e45958148d437ae5096835a118be58e6df9/portable/GCC/ARM_CM4F/port.c#L593 а вот тут они запрещают прерывания https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/d5a10e45958148d437ae5096835a118be58e6df9/portable/GCC/ARM_CM4F/port.c#L547 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба 7 minutes ago, jcxz said: Я всегда использую WFE. Почему? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба потому что работает как надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба 2 minutes ago, jcxz said: потому что работает как надо. Как надо - это засыпает через раз, потому что ивент уже взведен на момент выполнения WFE, или что? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба 2 минуты назад, aaarrr сказал: Как надо - это засыпает через раз, потому что ивент уже взведен на момент выполнения WFE, или что? Какая разница "через раз засыпает" или сразу? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба Так почему WFE-то? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spider 0 26 марта, 2022 Опубликовано 26 марта, 2022 · Жалоба Ой ой ой, не ссортесь :) Так что у меня получается. И не должно работать wfi с отключеными прерываниями? Косяк у фриртоса? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Spider 0 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба И всё? Вариантов больше нет? А можно как-то узнать какие прерывания стоят? Тупо перебирать все IFx биты во всех ->SR ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться