Dmitrich 0 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба Имеем: - Процессор 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 ); Люди добрые, помогите, кто может! Мне пока не нужны разные приоритеты, вполне достаточно, если все прерывания будут иметь одинаковый приоритет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба а сваливается в hard fault exeption? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dmitrich 0 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба а сваливается в hard fault exeption? Зависает в цикле в функции vListInsert, как раз там, где перечислены возможные причины зависания. Но в процессе попыток решения проблемы в hard fault exeption я её тоже "видел" часто. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
shmur 0 12 декабря, 2011 Опубликовано 12 декабря, 2011 (изменено) · Жалоба Дак там же где у вас виснет описаны возможный причины, мне кажется у вас 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 там по-моему самый низкий приоритет. Ну и соответственно проверьте все критический секции. Изменено 12 декабря, 2011 пользователем shmur Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба такое может так же быть если в прерывании используются не ISR-ные функции операционки для очередей и всего такого. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dmitrich 0 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба такое может так же быть если в прерывании используются не 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 там по-моему самый низкий приоритет. Ну и соответственно проверьте все критический секции. Методом "пробования" я уже приблизился к состоянию биения головой об стену... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
shmur 0 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба Посмотрите кэлстек, откуда валится, посмотрите на список задач, все ли в порядке у них со стеком (в IAR можно через FreeRTOS plugin). И кстати исходя из того, что вы тут показали, у вас приоритет FreeRTOS равен приоритету UART'ов и равняется 15, а должен быть ниже. Что за (configKERNEL_INTERRUPT_PRIORITY >> 4), почему просто не присваивать число? Была у меня еще похожая проблема с библиотекой, поставляемой ST, там драйвера по нескольку раз выставляли разную NVIC_PriorityGroupConfig. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба #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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба Тут Уровни приоритетов прерываний, Cortex-M3... смотрели? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 12 декабря, 2011 Опубликовано 12 декабря, 2011 · Жалоба Пробуйте трассировку. Как минимум трассировку в буфер, или сразу с помощью макросов трассировки. Подробно процесс трассировки описан в КиТ №11 2011 Можно определить макросы по входу и выходу задачи, на тик, на изменение приоритета, а также если запись по xQueueSendFromISR провалилась. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dmitrich 0 13 декабря, 2011 Опубликовано 13 декабря, 2011 · Жалоба Большое спасибо всем, кто откликнулся. Коллективный разум победил! Проект пере - собран с библиотекой 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 Ещё раз спасибо всем! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan-maniak 0 15 августа, 2014 Опубликовано 15 августа, 2014 (изменено) · Жалоба Хочу поднять эту тему. У меня так-же возникли проблемы с использованием очередей Фриртоса в обработчиках прерывания. В сообщении выше настройки в принципе не могут работать, так как приоритет 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 как в посте выше. Значит вывод напрашивается следующий - неправильно расставляю приоритеты. Но как правильно - информации найти не могу. Изменено 15 августа, 2014 пользователем Ruslan-maniak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LightElf 0 16 августа, 2014 Опубликовано 16 августа, 2014 · Жалоба так как приоритет 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться