реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> зацикливается freertos
jeka
сообщение Jun 24 2018, 12:47
Сообщение #1


Administrator
***

Группа: Свой
Сообщений: 400
Регистрация: 10-05-04
Пользователь №: 1



Пробую freertos в действии. Простейшая задача - прерывание таймера (10 кГц) асинхронно периодически толкает процесс. stm32f205.
от 0.1 до 2-3 секунд работает, далее зацикливается в недрах RTOS на функции vListInsert (которой передается управления при вызове ulTaskNotifyTake), на этой строчке:
Код
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */


было подозрение на порчу памяти, но после перемещения памяти rtos в другие адреса эффект не изменился.
Не пойму, что за чудеса такие. Переполнение буферов? race condition? Копать глубже исходники rtos?

Функция ожидания, вызываемая процессом в цикле:
Код
void wait_tick() {
  rmotion_go=2;// включение долбилки из ISR
wt=1;// для отслеживания входа в notifytake. при зацикливании равен единице.
  int id=ulTaskNotifyTake( pdTRUE, 2 );
wt=0;
  }



ISR (10 кГц):
Код
  if (rmotion_go==2) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    vTaskNotifyGiveFromISR(Motion_task_handle, &xHigherPriorityTaskWoken );
//    xTaskNotifyFromISR( Motion_task_handle, 2, eNoAction/*eSetValueWithoutOverwrite*/, &xHigherPriorityTaskWoken );
//    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );// need realtime process
    }

соответственно, ISR долбит notify постоянно после того как процесс включит долбёжку (т.е. долбёжка не останавливается). Приоритет ISR таймера 7, приоритет супервизора 15 (судя по конфигу).
Замена vTaskNotifyGiveFromISR на xTaskNotifyFromISR с опцией eSetValueWithoutOverwrite ничего не меняет.




call stack:
Код
vListInsert
prvAddCurrentTaskToDelayedList
ulTaskNotifyTake
wait_tick


Конфиг:
CODE
FreeRTOS Kernel V10.0.1

#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 120000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 512 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1

/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY 255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */


/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15. This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15


#define xPortSysTickHandler SysTick_Handler
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
Go to the top of the page
 
+Quote Post
juvf
сообщение Jun 24 2018, 16:18
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(jeka @ Jun 24 2018, 17:47) *
Пробую freertos в действии...
А с прерываниями в freertos на кортексе точно у вас всё в порядке?

В двух словах...
Для Cortex-M3-M4 в фрииртос есть засада: в конфиге указывается максимальный приоритет, в обработчике которого будут вызываться API фриртоса.
Вроде как #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */
Т.е. у вас в конфиге указанно, что приоритет прерывания, в котором будут вызываться API не должен быть выше 11. У вас приоритет ISR таймера 7. Либо в конфиге укажите configMAX_SYSCALL_INTERRUPT_PRIORITY больше 7 (или "больше либо равно 7"), либо понижайте ISR таймера до 11.... Более точно про приоритеты сказать не могу... не помню уже... гуглите, .... тут поднималась эта тема и там расписано с точностью до запятой, что да как.


ps Может у вас не в этом проблема, но описанное поведение/зависание freertos именно такое, когда в прерывании выше configMAX_SYSCALL_INTERRUPT_PRIORITY дергают API.... ртос работает... и нормально работают все прерывания, но рано или позно ртос где-то в недрах зависает.

pps Это вызов АПИ с нарушением приоритета положит ось не всегда. Может раз 100-10000 нормально сработает, а потом ось ляжет. Как-то это асертом ловилось. Если не ошибаюсь в конфиге нужно ассерт определить. Он в целом тормозит ОС, но после того, как проверите правильность прерываний его можно/нужно отключить закоментировать. Вроде с ассертом при первом вызове из "неправильного" прерывания апи ось сразу встанет. И вроде это так делается
Код
/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY    15

#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for(;; ); }
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jun 24 2018, 16:40
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



- проверить что CPU реально работает на 120 МГц
- уменьшить частоту прерываний таймера (тот что 10000) до 100 Гц и проверить что это так.
- вместо кода во все задачи поставить "пустышки", и убедиться что планировщик переключает задачи.
(и вообще, что управление передается планировщику, есть прерывания тиков в #define xPortSysTickHandler SysTick_Handler ).
- далее - последовательно увеличивать частоту таймера для ISR до 10000 и подключать свой код.
- размер стека(ов) я бы увеличил. В конфиге есть configCHECK_FOR_STACK_OVERFLOW для его контроля.
может проблема и не так глубоко.

Go to the top of the page
 
+Quote Post
uriy
сообщение Jun 24 2018, 17:16
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Вы уверены что вызывать vTaskNotifyGiveFromISR 10000 раз в секунду это правильный подход?
Может вам стоит пересмотреть логику работы вашей программы.
Go to the top of the page
 
+Quote Post
Serge V Iz
сообщение Jun 25 2018, 02:40
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 3-05-18
Пользователь №: 103 639



Про допустимый уровень приоритета для xxxFromISR выше уже написали. Поскольку IDLE_SHOULD_YIELD, вероятность прерывания инициированной IdleTask модификации списка задач другой, конкурирующей, модификацией, инициированной обработчиком прерывания, достаточно высока. Похоже, иногда это происходит в ломающем логику модификации списка месте. )

А так, пропускную способность 10к событий/с эта структура программы обеспечит с запасом. Только, присоединюсь к предыдущему оратору - зачем? )
Go to the top of the page
 
+Quote Post
jeka
сообщение Jun 25 2018, 08:36
Сообщение #6


Administrator
***

Группа: Свой
Сообщений: 400
Регистрация: 10-05-04
Пользователь №: 1



Да, слона то я и не приметил... Не думал что максимальный приоритет вызовов ограничен. Спасибо sm.gif Похоже действительно switch_context прерывался, и я давал Notify в это время.

По поводу 10 кГц - это во-первых испытания на пригодность работы в жестком реалтайме, во-вторых задачи бывают разыне и иногда требуется большую и сложную state машину крутить в жестком реалтайме. Код существенно нагляднее получается когда написан в виде процесса, а не обработчика прерывания с кучей ветвей state машины.
Как альтернативу я как-то делал микро-запоминалку-востанавливалку контекста/стека в конкретном ISR для таких целей (т.е. в обработчике ISR я могу вызвать функцию "ждать следующего ISR", которое сохранит контекст и выйдет из прерывания, а следующее прерывание продолжит исполненеия обработчика с этого места), но это не практично т.к. контекст для экономии ресурсов обычно сохраняется-восстанавливается с ограничениями и другим людям в таких вещах зачастую сложно разобраться.
Go to the top of the page
 
+Quote Post
Serge V Iz
сообщение Jun 25 2018, 14:46
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 3-05-18
Пользователь №: 103 639



Ну, мы занимаемся (одним конкретным из множества разнообразных видов) "жестким реалтаймом". ) Так для нас "жесткий реалтайм" - это когда еще при проектировании определенные гарантированные запасы времени на решение задач заложены. Если с самого начала ходить по пути "на весь цикл работы системы отводится всего около 10 тыс тактов машины" можно попасть в... неудобное положение.

"Для оценочного тестирования задействованных механизмов ОС" - я бы еще понял. )
Go to the top of the page
 
+Quote Post
jeka
сообщение Jun 25 2018, 17:53
Сообщение #8


Administrator
***

Группа: Свой
Сообщений: 400
Регистрация: 10-05-04
Пользователь №: 1



Цитата
на весь цикл работы системы отводится всего около 10 тыс тактов машины" можно попасть в... неудобное положение.

Это я прекрасно понимаю, но в данной задаче таких проблем нет, и интересно посмотреть как поведет себя RTOS при таких нагрузках. Знать и правильно использовать пределы возможностей RTOS полезно.
По результатам сегодняшнего эксперимента отлично работает, я доволен. Появился некритичный джиттер по времени, что логично.
Go to the top of the page
 
+Quote Post
Serge V Iz
сообщение Jun 25 2018, 19:02
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 3-05-18
Пользователь №: 103 639



А. Ну, то есть, все-таки для оценки механизмов сигнализации/переключения. Кстати, этот джиттер, в абсолютных микро/наносекундах и есть ценный результат - он показывает границы неопределенности во времени, затрачиваемом на выполнение всех этих телодвижений ОС. ) По хорошему, к нему еще нужно среднее и максимальное время, затраченное на переключение. Методом подбора "ломающей систему частоты" это все равно неудобно делать )
Go to the top of the page
 
+Quote Post
uriy
сообщение Jun 26 2018, 04:27
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Цитата
По поводу 10 кГц - это во-первых испытания на пригодность работы в жестком реалтайме,
Для реалтайма такой подоход не годится. Надо это делать подобные вещи мимо ОС. Через DMA, двойные буферы и прочее. Чтобы джиттер переключения контекста не оказывал никакого влияния.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 26 2018, 09:18
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(uriy @ Jun 26 2018, 07:27) *
Для реалтайма такой подоход не годится. Надо это делать подобные вещи мимо ОС. Через DMA, двойные буферы и прочее. Чтобы джиттер переключения контекста не оказывал никакого влияния.

Для Cortex-M с тактовой >=100МГц переключение контекста RTOS с частотой 10кГц не должно быть проблемой. Загрузка CPU таким переключением должна быть не более пары процентов.
Но конечно лучше использовать частоты переключения как можно ниже.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th April 2024 - 09:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01522 секунд с 7
ELECTRONIX ©2004-2016