|
|
  |
А она всё равно виснет!, Помогите разобраться с прерываниями |
|
|
|
Dec 12 2011, 07:47
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 15-02-05
Пользователь №: 2 663

|
Имеем:
- Процессор STM32F103RCT6 - Тактовая - 72Мгц. - FreeRTOS v7.02 - Небольшой проект с 7 задачами.
Проект сделан на основе "Demo" из дистрибутива FreeRTOS. Все опции проекта и основные настройки взяты оттуда. Все задачи созданы с одинаковым приоритетом, равным 1.
Используются 3 UARTa, для них разрешены прерывания.
Программа в целом работает, все функции выполняет. Есть тольк одно "но": - Через произвольный промежуток времени, от минут до часов, ОСь виснет!
Использование стека ежесекундно контролируется функцией uxTaskGetStackHighWaterMark во всех задачах. Размер кучи ежесекундно контролируется функцией xPortGetFreeHeapSize. Включен механизм контроля переполнения стека vApplicationStackOverflowHook.
Всего хватает с большим запасом, и увеличение всех размеров ситуацию не изменяет.
Все ресурсы (семафоры, очереди) - созданы до создания задач. В процессе работы никакие ресурсы не удаляются и не создаются. Из прерываний вызываются ТОЛЬКО xQueueSendFromISR().
Так что наиболее вероятная причина - неправильная настройка приоритетов прерываний. И тут я уже окончательно запутался, прошу помощи.
Сейчас настройки у меня такие (взяты из демо):
Определения:
#define configKERNEL_INTERRUPT_PRIORITY 255 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
Настройки:
Один раз: NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 ); NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
Для UART-ов:
NVIC_InitStructure.NVIC_IRQChannel = UART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = (uint8_t)(configKERNEL_INTERRUPT_PRIORITY >> 4); NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure );
NVIC_InitStructure.NVIC_IRQChannel = UART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = (uint8_t)(configKERNEL_INTERRUPT_PRIORITY >> 4); NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure );
NVIC_InitStructure.NVIC_IRQChannel = UART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = (uint8_t)(configKERNEL_INTERRUPT_PRIORITY >> 4); NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure );
Люди добрые, помогите, кто может! Мне пока не нужны разные приоритеты, вполне достаточно, если все прерывания будут иметь одинаковый приоритет.
|
|
|
|
|
Dec 12 2011, 08:51
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 15-02-05
Пользователь №: 2 663

|
Цитата(kan35 @ Dec 12 2011, 11:59)  а сваливается в hard fault exeption? Зависает в цикле в функции vListInsert, как раз там, где перечислены возможные причины зависания. Но в процессе попыток решения проблемы в hard fault exeption я её тоже "видел" часто.
|
|
|
|
|
Dec 12 2011, 09:11
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 28-11-11
Пользователь №: 68 553

|
Дак там же где у вас виснет описаны возможный причины, мне кажется у вас 2 или 3: 2) Incorrect interrupt priority assignment, especially on Cortex-M3 arts where numerically high priority values denote low actual interrupt priories, which can seem counter intuitive. See configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html3) Calling an API function from within a critical section or when the scheduler is suspended. Попробуйте приоритет FreeRTOS, который configKERNEL_INTERRUPT_PRIORITY, поставить ниже чем остальные приоритеты, точнее остальные поставить выше, так как 15 там по-моему самый низкий приоритет. Ну и соответственно проверьте все критический секции.
Сообщение отредактировал shmur - Dec 12 2011, 09:14
|
|
|
|
|
Dec 12 2011, 10:11
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 15-02-05
Пользователь №: 2 663

|
Цитата(kan35 @ Dec 12 2011, 13:52)  такое может так же быть если в прерывании используются не ISR-ные функции операционки для очередей и всего такого. Я уже написал, что из прерываний вызываются ТОЛЬКО xQueueSendFromISR(). Если у Вас есть работающий проект - покажите мне, пожалуйста, Ваши установки #define configKERNEL_INTERRUPT_PRIORITY 255 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 и настройку прерываний NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = Это будет реальная помощь. Цитата(shmur @ Dec 12 2011, 13:11)  Дак там же где у вас виснет описаны возможный причины, мне кажется у вас 2 или 3: Я уже проверил, всё что мог. Купил мануал, разобрался со стеками. Сомнения только в прерываниях. Цитата Попробуйте приоритет FreeRTOS, который configKERNEL_INTERRUPT_PRIORITY, поставить ниже чем остальные приоритеты, точнее остальные поставить выше, так как 15 там по-моему самый низкий приоритет. Ну и соответственно проверьте все критический секции. Методом "пробования" я уже приблизился к состоянию биения головой об стену...
|
|
|
|
|
Dec 12 2011, 10:21
|
Участник

Группа: Участник
Сообщений: 55
Регистрация: 28-11-11
Пользователь №: 68 553

|
Посмотрите кэлстек, откуда валится, посмотрите на список задач, все ли в порядке у них со стеком (в IAR можно через FreeRTOS plugin). И кстати исходя из того, что вы тут показали, у вас приоритет FreeRTOS равен приоритету UART'ов и равняется 15, а должен быть ниже. Что за (configKERNEL_INTERRUPT_PRIORITY >> 4), почему просто не присваивать число? Была у меня еще похожая проблема с библиотекой, поставляемой ST, там драйвера по нескольку раз выставляли разную NVIC_PriorityGroupConfig.
|
|
|
|
|
Dec 13 2011, 01:22
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 15-02-05
Пользователь №: 2 663

|
Большое спасибо всем, кто откликнулся. Коллективный разум победил! Проект пере - собран с библиотекой STM32F10x_StdPeriph_Lib_V3.5.0 Сейчас ОСь стабильно работает с такими настройками:
Определения в "FreeRTOSConfig.h": #define configKERNEL_INTERRUPT_PRIORITY 255 #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
Один раз при настройке процессора:
NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 ); NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
Прерывания всех USART-ов настроены одинаково:
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 14; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure );
Естественно, в настройках других USART подставлены соотв. USART1_IRQn
Ещё раз спасибо всем!
|
|
|
|
|
Aug 16 2014, 12:49
|
Частый гость
 
Группа: Участник
Сообщений: 180
Регистрация: 5-04-09
Пользователь №: 47 205

|
QUOTE (Ruslan-maniak @ Aug 15 2014, 12:22)  так как приоритет configMAX_SYSCALL_INTERRUPT_PRIORITY = 191 ниже NVIC_IRQChannelPreemptionPriority = 14. А должно быть наоборот. Приоритет configMAX_SYSCALL_INTERRUPT_PRIORITY = 191 выше, чем NVIC_IRQChannelPreemptionPriority = 14. Потому что у процессора реализованы только 4 _старших_ бита приоритета. Совместными усилиями ARM и Richard Barry запутали тему. Регистр приоритета прерывания 8-битный, но в зависимости от модели процессора и настроек PriorityGrouping реализованы только несколько старших битов. NVIC_IRQChannelPreemptionPriority = 14 задает "сдвинутый" приоритет, который в регистр записывается как (14<<4) = 224. configMAX_SYSCALL_INTERRUPT_PRIORITY = 191 задает актуальное значение регистра, который в сдвинутом виде равен 11.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|