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

 
 
> А она всё равно виснет!, Помогите разобраться с прерываниями
Dmitrich
сообщение Dec 12 2011, 07:47
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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 );

Люди добрые, помогите, кто может!
Мне пока не нужны разные приоритеты, вполне достаточно, если все прерывания будут иметь одинаковый приоритет.









Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Ruslan-maniak
сообщение Aug 15 2014, 08:22
Сообщение #2


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

Группа: Участник
Сообщений: 92
Регистрация: 27-12-12
Из: Томск
Пользователь №: 74 999



Хочу поднять эту тему. У меня так-же возникли проблемы с использованием очередей Фриртоса в обработчиках прерывания. В сообщении выше настройки в принципе не могут работать, так как приоритет configMAX_SYSCALL_INTERRUPT_PRIORITY = 191 ниже NVIC_IRQChannelPreemptionPriority = 14. А должно быть наоборот. Если настроить как надо то через некоторое время вываливаемся в ХАРДФОЛТ. Всё перепробовал - ничего не помогает. Кто ещё сталкивался с такой проблемой и как решил?

А если например сделать такую нехорошую вещь, как закоментировать строки
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
в функции void vPortValidateInterruptPriority( void ) то всё работает как часы, когда NVIC_IRQChannelPreemptionPriority настроен ниже configMAX_SYSCALL_INTERRUPT_PRIORITY как в посте выше.
Значит вывод напрашивается следующий - неправильно расставляю приоритеты. Но как правильно - информации найти не могу.


Сообщение отредактировал Ruslan-maniak - Aug 15 2014, 09:27
Go to the top of the page
 
+Quote Post
LightElf
сообщение Aug 16 2014, 12:49
Сообщение #3


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

Группа: Участник
Сообщений: 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.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 18th August 2025 - 05:28
Рейтинг@Mail.ru


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