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

Всем привет.

Столкнулся со странной фигнёй. Пытаюсь заставить 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 нет. Значение счётчика сдвинулось на крупицу. 

Как узнать кто нас разбудил?! И засыпали ли?

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


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

4 часа назад, Spider сказал:

Создаю по сути пустой проект с 1 таском, настраиваю и запускаю. И что же я вижу? Что, сразу после wfi продолжается исполнение кода без каких-то намёков на сон. Что может его будить?

И каким же образом Вы это видите? Уж не под отладчиком ли?  :wink:

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


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

58 minutes ago, jcxz said:

И каким же образом Вы это видите? Уж не под отладчиком ли?  :wink:

Ногодрыгом на осциле.

 

ЗЫ. Я тут кое чего достиг, и даже под отладчиком!

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


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

Методом проб и ошибок выяснил, что wfi теряет свой функционал, если freeRTOS вызывает portENTER_CRITICAL(), в частности влияет конкретно вызов  portDISABLE_INTERRUPTS(), маскирует прерывания по приоритетам. А freeRTOS именно это и делает перед тем как уйти в сон по wfi. И вот тут какая то странность. В результате наличия маски по прерываниям wfi начинает СРАЗУ же выходить из сна, если вообще входит в него....

Если же сделать portEXIT_CRITICAL() перед тем как выполнить wfi, то всё работает. Но! Разве так должно быть? Или я что-то не так делаю? Или не понимаю чего-то? Хотелось бы понять что я упускаю.....

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


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

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 пробуждаться.

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


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

Это как раз я и прочитал. Но активных прерываний то нет. Вот в чём беда. А он всё равно выходит из сна.
Сейчас попробовал сделать вместо primask запрет прерываний по cpsid и ровно та же ситуация - выход из wfi мгновенный.
Как так?  В то же время, если разрешить ВСЕ прерывания или же размаскировать ВСЕ прерыавания, то и прерываний не вызывается и WFI работает.
Я ещё что-то не прочитал что бы это означало?

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


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

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

Как так?  В то же время, если разрешить ВСЕ прерывания или же размаскировать ВСЕ прерыавания, то и прерываний не вызывается и WFI работает.
Я ещё что-то не прочитал что бы это означало?

Так а зачем их запрещать? Какой смысл?

WFI/WFE как правило - должна выполняться в самом низкоприоритетном процессе. Idle-процессе. Нет никакого смысла запрещать там прерывания.

 

PS: И почему используете WFI, а не WFE?

Я всегда использую WFE.

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


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

Ну так оно написано в 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

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


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

2 minutes ago, jcxz said:

потому что работает как надо.

Как надо - это засыпает через раз, потому что ивент уже взведен на момент выполнения WFE, или что?

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


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

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

Как надо - это засыпает через раз, потому что ивент уже взведен на момент выполнения WFE, или что?

Какая разница "через раз засыпает" или сразу?

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


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

Ой ой ой, не ссортесь :)

Так что у меня получается. И не должно работать wfi с отключеными прерываниями? Косяк у фриртоса? 

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


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

И всё? Вариантов больше нет? А можно как-то узнать какие прерывания стоят? Тупо перебирать все IFx биты во всех ->SR ?

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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