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

А она всё равно виснет!

Имеем:

 

- Процессор 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 );

 

Люди добрые, помогите, кто может!

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

 

 

 

 

 

 

 

 

 

 

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


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

а сваливается в hard fault exeption?

Зависает в цикле в функции vListInsert, как раз там, где перечислены возможные причины зависания.

Но в процессе попыток решения проблемы в hard fault exeption я её тоже "видел" часто.

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


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

Дак там же где у вас виснет описаны возможный причины, мне кажется у вас 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.html

3) Calling an API function from within a critical section or when

the scheduler is suspended.

 

Попробуйте приоритет FreeRTOS, который configKERNEL_INTERRUPT_PRIORITY, поставить ниже чем остальные приоритеты, точнее остальные поставить выше, так как 15 там по-моему самый низкий приоритет. Ну и соответственно проверьте все критический секции.

Изменено пользователем shmur

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


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

такое может так же быть если в прерывании используются не ISR-ные функции операционки для очередей и всего такого.

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


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

такое может так же быть если в прерывании используются не ISR-ные функции операционки для очередей и всего такого.

Я уже написал, что из прерываний вызываются ТОЛЬКО xQueueSendFromISR().

 

Если у Вас есть работающий проект - покажите мне, пожалуйста, Ваши установки

 

#define configKERNEL_INTERRUPT_PRIORITY 255

#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191

#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15

 

и настройку прерываний NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =

 

Это будет реальная помощь.

 

 

 

 

Дак там же где у вас виснет описаны возможный причины, мне кажется у вас 2 или 3:

Я уже проверил, всё что мог. Купил мануал, разобрался со стеками. Сомнения только в прерываниях.

Попробуйте приоритет FreeRTOS, который configKERNEL_INTERRUPT_PRIORITY, поставить ниже чем остальные приоритеты, точнее остальные поставить выше, так как 15 там по-моему самый низкий приоритет. Ну и соответственно проверьте все критический секции.

Методом "пробования" я уже приблизился к состоянию биения головой об стену...

 

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


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

Посмотрите кэлстек, откуда валится, посмотрите на список задач, все ли в порядке у них со стеком (в IAR можно через FreeRTOS plugin).

И кстати исходя из того, что вы тут показали, у вас приоритет FreeRTOS равен приоритету UART'ов и равняется 15, а должен быть ниже. Что за (configKERNEL_INTERRUPT_PRIORITY >> 4), почему просто не присваивать число?

Была у меня еще похожая проблема с библиотекой, поставляемой ST, там драйвера по нескольку раз выставляли разную NVIC_PriorityGroupConfig.

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


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

#define configPRIO_BITS       4
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5

/* The lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY     ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Priority 5, or 160 as only the top three bits are implemented. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
    

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

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


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

Пробуйте трассировку. Как минимум трассировку в буфер, или сразу с помощью макросов трассировки. Подробно процесс трассировки описан в КиТ №11 2011

Можно определить макросы по входу и выходу задачи, на тик, на изменение приоритета, а также если запись по xQueueSendFromISR провалилась.

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


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

Большое спасибо всем, кто откликнулся.

Коллективный разум победил!

Проект пере - собран с библиотекой 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

 

Ещё раз спасибо всем!

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


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

Хочу поднять эту тему. У меня так-же возникли проблемы с использованием очередей Фриртоса в обработчиках прерывания. В сообщении выше настройки в принципе не могут работать, так как приоритет 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

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


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

так как приоритет 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.

 

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


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

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

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

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

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

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

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

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

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

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