Easyelectronics.ru • Просмотр темы - FreeRTOS STM32F4 и внешние прерывания

Easyelectronics.ru

Электроника для всех
Текущее время: 16 авг 2018, 10:51

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 18 ноя 2017, 17:50 
Только пришел

Зарегистрирован: 30 сен 2016, 14:09
Сообщения: 8
Добрый день!
Возникла проблема. Имеется плата STM32F4Disc и датчик. на плате развернут RTOS с помощью CubeMX. Датчик генерирует аппаратные прерывания, скажем, на 1кгц, в теле прерывания
Код:
void EXTI1_IRQHandler(void)
выставляется семафор
Код:
   static portBASE_TYPE xHigherPriorityTaskWoken;
   xHigherPriorityTaskWoken = pdFALSE;

   xSemaphoreGiveFromISR(ISRFromSensorHandle, &xHigherPriorityTaskWoken);

   if( xHigherPriorityTaskWoken == pdTRUE )
   {
      taskYIELD();
   }

Соответственно запущены две задачи - первая с приоритетом HIGH, которая считывает данные семафора и запускает обработку данных с датчика и печатает их в UART(с частотой 100 Гц, - каждая десятая посылка), вторая с приоритетом NORMAL просто мигает светодиодом раз в секунду.
Код:
void StartDefaultTask(void const * argument)
{
   for(;;)
   {
      HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
      osDelay(1000);
   }
   vTaskDelete(NULL);
}

void StartReadingSensorTask(void const * argument)
{
   for(;;)
   {
      xSemaphoreTakeFromISR(ISRFromSensorHandle, portMAX_DELAY);
      getSensorData();
      osDelay(1);
   }
   vTaskDelete(NULL);
}

Спустя какое то время (может быть 10 секунд, может минута, каждый раз по-разному) все отваливается, светодиод перестает мигать и данные не печатаются.
Подозреваю что дело в том, что наступает момент, когда аппаратное прерывание случается в тот момент, когда RTOS что то критическое выполняет, и из за этого все отваливается. Вопрос - в какую сторону стоит копать?
Второй вопрос - насколько это вообще оправдано, читать датчик с такой скоростью используя RTOS? Или же дело в настройках приоритетов прерываний?
Датчик инициализируется после инициализации переферии, перед запуском планировщика.

Заранее благодарю,
С уважением, Максим.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 18 ноя 2017, 18:09 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Что такое osDelay(1000)? Если нужна некая задержка, лучше отправить задачу в ожидание с помощью vTaskDelay().
SemaphoreTakeFromISR - может использоваться только в обработчике аппаратного прерывания. У вас же - в обычной задаче.
vTaskDelete(NULL) - лишнее, потому что цикл for(;;) - не имеет параметров и не имеет выхода. При компиляции преобразуетя в инструкцию безусловного перехода в начало цикла.
По поводу прерываний - у NVIC есть флаги ожидающих прерываний, и если в момент обработки одного прерывания пришло другое, то оно никуда не пропадет, а будет обработано, в зависимости от их приоритетов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 18 ноя 2017, 18:45 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 1860
99% - не правильно настроена FreeRTOS!
Прерывания, из которых вызываются функции rtos должны иметь приоритет ниже, чем у шулдера (или как его там...)
Иначе просто однажды одно такое прерывание прервёт планировщик задач и все рухнет.
Жёванно-пережёвано уже 10 раз все это, ищите тут на форуме.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 18 ноя 2017, 19:29 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Да нет, у него ошибка - вместо xSemaphoreTake написано xSemaphoreTakeFromISR, а второй параметр у этих функций - разный.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 18 ноя 2017, 19:57 
Только пришел

Зарегистрирован: 30 сен 2016, 14:09
Сообщения: 8
osDelay сгенерировал сам CubeMX в defaultTask, потому и стал его использовать.

SemaphoreTakeFromISR и SemaphoreTakeFromISR использовал из-за того что использую аппаратное прерывание EXT1 на пине PA1, думал так и надо делать.

Поясните, пожалуйста, по-подробнее что Вы имеете ввиду? Я изучал статью по прерываниям "FreeRTOS: практическое применение, часть 3 (управление прерываниями)", там действительно в самой задаче используется xSemaphoreTake, но никак не могу понять как это связано с самим обработчиком.

Если я правильно понял, - необходимо в обработчик прерывания поместить
Код:
void EXTI1_IRQHandler(void)
{
   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);

   static portBASE_TYPE xHigherPriorityTaskWoken;
   xHigherPriorityTaskWoken = pdFALSE;

   xSemaphoreGiveFromISR(ISRFromSensorHandle, &xHigherPriorityTaskWoken);

   if( xHigherPriorityTaskWoken == pdTRUE )
   {
      portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
   }
}


А в задачу поместить
Код:
void StartReadingSensorTask(void const * argument)
{
   for(;;)
   {
      xSemaphoreTake(ISRFromSensorHandle, portMAX_DELAY);
      SensorData();

   }
}

Но оно все равно так не работает, обрывается работа еще быстрее, как мне показалось.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 19 ноя 2017, 00:06 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Так а кто ж будет сбрасывать в обработчике флаг прерывания от EXTI то?
Что такое HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1) - я не знаю, потому что не работаю с HAL-ом


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 20 ноя 2017, 17:06 
Старожил
Аватара пользователя

Зарегистрирован: 01 ноя 2011, 23:51
Сообщения: 532
BusMaster писал(а):
Так а кто ж будет сбрасывать в обработчике флаг прерывания от EXTI то?
Что такое HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1) - я не знаю, потому что не работаю с HAL-ом

osDelay==vTaskDelay
это обертка которую делает Cube для этой ф-ции. Исключительно для унификации.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 20 ноя 2017, 18:13 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 1860
Проблемы с прерываниями во FreeRtos и STM32Fxxx.
Эта проблема описана уже везде (даже на заборе), но повторюсь, т.к. на эти грабли я тоже наступил.
1. Во FreeRTOS чем выше число приоритета, тем выше приоритет, а у STM32 наоборот. И FreeRTOS использует только 4 бита для установки приоритета. От этого все проблемы и недопонимания.
2. В фале конфига написано:
Код:
InterruptPriority

/* The highest interrupt priority that can be used by any interrupt service

routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL

INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER

PRIORITY THAN THIS! (higher priorities are lower numeric values. */

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY   5


Что означает, что самые высокие приоритеты в классификации STM32, заняты RTOS ( от 0 до 4). А мы можем использовать только от 5 до 15. Т.е. правильно писать присвоение приоритетов в своих прогах как:
Код:
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

    //Important for FreeRtos. You should use 4 bit for priority

    NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPriority =

        configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


и не превышать числа 15, Ну и естественно 15 это самый низший приоритет.

http://www.asobol.ru/software/freertos


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 02:21 
Только пришел

Зарегистрирован: 30 сен 2016, 14:09
Сообщения: 8
В функции HAL_Init() обнаружил данную строку :
Код:
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

Подозреваю что это и есть то, о чем Вы говорили выше:
Код:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);


В файле gpio.c имеются настройки для прерываний, указал так:
Код:
  HAL_NVIC_SetPriority(EXTI1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1, 0);
  HAL_NVIC_EnableIRQ(EXTI1_IRQn);


Результат, к сожалению, тот же. А что касается сброса флага прерывания - в Cube, как я понял, он автоматически сбрасывается. Причем программа работает крайне странно - сначала выплевывает пачку данных с датчика, потом останавливается, а после начинает выдавать данные примерно на 1Гц. Приоритеты так же настроены как на скрине


Вложения:
priority.png
priority.png [ 67.23 Кб | Просмотров: 1645 ]


Последний раз редактировалось maxbelyx 21 ноя 2017, 03:02, всего редактировалось 1 раз.
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 02:44 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1125
Откуда: Германия
А какой компилятор, если не секрет?
Если ГЦЦ, у него есть "интересная особенность" - функции, которые используются в качестве обработчиков прерываний имеют пролог и эпилог. И ГЦЦ в этих прологах сохраняет в стеке только первые 5, кажется, регистров. Остальные игнорирует, но активно использует в самой функции, что, само собой не очень хорошо сказывается на дальнейшей работе после выхода из обработчика.
Я потому для всех своих обработчиков прерываний сделал свои прологи и эпилоги.
Как именно, я подробно описал тут около года назад.

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 09:49 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Регистры R0-R4, R12, SP, LR, PC, xPSR - сохраняются Ав-то-ма-ти-чес-ки! :) Автоматически, без вмешательства кода GCC. Автоматически, за 12 тактов работой самого NVIC. Это опять же к вопросу о разнице между прерываниями и остальными функциями. Эх, как бы не хотелось снова поднимать срачный старый вопрос, но, к сожалению, некоторые люди упорно не хотят изучать работу МК на аппаратном уровне, хоть и твердят, что якобы знают, как это работает. А на любые доводы из документов отвечают истеричным потоком херни не по теме. Ну нельзя же так...
Хотите сохранить и остальные регистры? Окей, используйте ассемблерную команду push и затем сдвиг указателя стека на число сохраненных регистров:
asm("push {r5, r6, r7"\n"
"sub sp, #12");
Только не забудьте их обратно вытолкнуть командой pop.
Для сомневающихся - докум Programming manual, глава Exception entry and return. Это же так просто!
Регистры выше R7 (кроме R12) начинают использоваться только при высоком уровне оптимизации. А в остальном - они почти не используются, из-за ограничений доступа к ним со стороны 16-битных инструкций.

Здесь была правильная подсказка - приоритеты NVIC - приоритет численно больше 5. Ну и плюс сброс флага прерывания, разумеется.
Только следует учесть, что приоритеты в RTOS - в возрастающем порядке, а приоритеты NVIC - в убывающем.
Я не знаю, чего там генерирует HAL, не пользуюсь им, поэтому мне не понятны константы и функции HAL_NVIC...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 11:20 
Старожил
Аватара пользователя

Зарегистрирован: 01 ноя 2011, 23:51
Сообщения: 532
Pingvin писал(а):
Проблемы с прерываниями во FreeRtos и STM32Fxxx.
Эта проблема описана уже везде (даже на заборе), но повторюсь, т.к. на эти грабли я тоже наступил.
1. Во FreeRTOS чем выше число приоритета, тем выше приоритет, а у STM32 наоборот. И FreeRTOS использует только 4 бита для установки приоритета. От этого все проблемы и недопонимания.
2. В фале конфига написано:
Код:
InterruptPriority

/* The highest interrupt priority that can be used by any interrupt service

routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL

INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER

PRIORITY THAN THIS! (higher priorities are lower numeric values. */

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY   5


Что означает, что самые высокие приоритеты в классификации STM32, заняты RTOS ( от 0 до 4). А мы можем использовать только от 5 до 15.


Я немного не согласен с данной постановкой вопроса. Я б сказал так что мы можем использовать ЛЮБЫЕ прерывания и приоритеты. НО!!! Если вы используете приоритет более чем какой-то(это можно настроить в данном случае пятый) то вы НЕ ИМЕЕТЕ права использовать там ф-ции FreeRTOS. Или вернее права то имеете - но результат может быть непредсказуем.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 11:59 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1125
Откуда: Германия
BusMaster писал(а):
Регистры R0-R4, R12, SP, LR, PC, xPSR - сохраняются Ав-то-ма-ти-чес-ки! :) Автоматически, без вмешательства кода GCC. Автоматически, за 12 тактов работой самого NVIC. Это опять же к вопросу о разнице между прерываниями и остальными функциями. Эх, как бы не хотелось снова поднимать срачный старый вопрос, но, к сожалению, некоторые люди упорно не хотят изучать работу МК на аппаратном уровне, хоть и твердят, что якобы знают, как это работает. А на любые доводы из документов отвечают истеричным потоком херни не по теме. Ну нельзя же так...

Мы уже выяснили, что мы с вам с разных точек зрения смотрели на этот вопрос. Или вам все мало и хочется почесать свое ЧСВ? Или вы не злопамятный, а просто злой и у вас память хорошая? Выдыхайте уже. Все уже всё поняли.

Кстати, вам на заметку - не всегда проц сохраняет регистры. Поглядите на такие слова как Tail-chaining и Late-arriving. В принципе для основной проги это не должно быть критично. Теоретически.
Ну и потом, как вы уже заметили - всего то первые 4 регистра сохраняются. А прога использует большее количество регистров. И у меня они использовались НЕ только при высоком уровне оптимизации (я обычно не использую оптимизацию совсем, только в некоторых местах) но и без оной, но оставим это на совести программеров ГЦЦ и просто будем иметь ввиду такую его особенность. На IAR компиляторе я такого поведения не заметил. Но у него есть свои особенности.

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 12:17 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Да с каких точек не смотри, работа проца то не меняется.
Давайте вы сначала от 0 до 4 сосчитаете правильно (это 5 штук выходит - 0, 1, 2, 3, 4), а уж потом конечно же мы вас с удовольствием выслушаем :)))

Да нет, я не злопамятный, совсем даже добрый... местами... Просто есть здоровый сарказьмъ.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 12:23 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1125
Откуда: Германия
BusMaster писал(а):
Да с каких точек не смотри, работа проца то не меняется.
Давайте вы сначала от 0 до 4 сосчитаете правильно (это 5 штук выходит - 0, 1, 2, 3, 4), а уж потом конечно же мы вас с удовольствием выслушаем :)))

Да нет, я не злопамятный, совсем даже добрый... местами... Просто есть здоровый сарказьмъ.

Давайте посчитаем:


Вложения:
RegistersInStack.PNG
RegistersInStack.PNG [ 26.24 Кб | Просмотров: 1521 ]

_________________
Мои поделки
http://www.fun-electronic.net/
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 12:32 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Ай молодэц! :))) Это была проверка на вшивость :))) Я рад, что вы начинаете интересоваться доками. А то пишете "первые 5, кажется". Я вам и нарисовал - "первые пять", а это как раз от r0 до r4 :) зато теперь вы знаете


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 12:44 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1125
Откуда: Германия
BusMaster писал(а):
Ай молодэц! :))) Это была проверка на вшивость :))) Я рад, что вы начинаете интересоваться доками. А то пишете "первые 5, кажется". Я вам и нарисовал - "первые пять", а это как раз от r0 до r4 :) зато теперь вы знаете

Вот вы блин придираетесь к каждой запятой. Аккуратней. Вас за это будут (если уже не) люто ненавидеть ваши непосредственные коллеги. Таких не любят и старятся всячески выжить из коллектива.
"Кажется" было в первом моем посте тут и в том же посте было то, что это было год назад.

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 12:52 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Мы с коллегами прекрасно ладим. А рабочие моменты в виде придирания к запятым - никак не мешают атмосфере в коллективе. Потому что один чел может что-то не заметить, зато другой увидит и поправит. Это нормально. Меня тоже поправляют коллеги, я тоже ошибаюсь или чего-то пропускаю.
Так что расслабьтесь :))) Всё нормуль


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 13:21 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 601
MasterAlexei писал(а):
Кстати, вам на заметку - не всегда проц сохраняет регистры. Поглядите на такие слова как Tail-chaining и Late-arriving. В принципе для основной проги это не должно быть критично. Теоретически.
Ну и потом, как вы уже заметили - всего то первые 4 регистра сохраняются. А прога использует большее количество регистров. И у меня они использовались НЕ только при высоком уровне оптимизации (я обычно не использую оптимизацию совсем, только в некоторых местах) но и без оной, но оставим это на совести программеров ГЦЦ и просто будем иметь ввиду такую его особенность. На IAR компиляторе я такого поведения не заметил. Но у него есть свои особенности.

BusMaster прав, я сам вчера хотел написать... Есть такое понятие как calling convention - соглашение о вызове функций и оно одинаковое для всех 32-х битных ARM, не зависимо от компилятора(если нет дополнительных указаний, типа fastcall). Согласно ему в r0-r3 передаются аргументы и возвращается результат, остальные регистры функция обязана сохранять сама. При прерывании сохраняются и эти r0-r3, т.е. суммарно сохраняется все и никаких проблем быть не должно. У обработчиков прерываний ведь даже никакого атрибута нет, для компилятора они обычные функции без параметров. Если gcc не сохраняет какие-то регистры во время прерываний, то следовательно он их не сохраняет и во время обычных вызовов и полностью поломан...
А при Tail-chaining и Late-arriving r0-r3 уже сохранены, потому сохраняя их повторно и потом дважды доставая обратно только зря потратишь время, результат от этого не поменяется.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 21 ноя 2017, 23:51 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Слава богу, что есть еще знающие люди :))

Касательно задачи топикстартера, вообще-то, довольно легко проблема решается вот так:
(вместо чтения датчика и передачи по UART-у - пара миганий светодиодами через каждые 10 разблокировок задачи, ибо тут важен общий принцип, а не конкретные детали)

Код:
  /*-- Создание задач  ------------------------*/
   //------- задача мигающего светодиода -------------
   error = xTaskCreate(prvTask_LED,
            "Task LED",
            configMINIMAL_STACK_SIZE,
            NULL,
            (tskIDLE_PRIORITY + 1),   // приоритет Idle+1
            &xTaskLED_Handle);
   //------- задача датчика --------------------
   error = xTaskCreate(prvTask_Sensor,
            "Task Sensor",
            configMINIMAL_STACK_SIZE,
            NULL,
            (tskIDLE_PRIORITY + 1),   // приоритет Idle+1
            &xTaskSensor_Handle);
//================================
....

/*-----------------------------------------------
* @brief:   задача LED. Мигает с частотой 1 Гц, как и заказывал ТС
* @param:   *pvParameters
* @retval:   нет
*/
void prvTask_LED(void *pvParameters)
{
   for (;;)
   {
      GREENLED_ON;
      vTaskDelay(500);
      GREENLED_OFF;
      vTaskDelay(500);
   }
}//----------------------------------------------

/*-----------------------------------------------
* @brief:   задача Sensor.
* @param:   *pvParameters
* @retval:   нет
*/
void prvTask_Sensor(void *pvParameters)
{
/*-- Подготовка к реакции на EXTI --*/
   EXTI->IMR |= EXTI_IMR_MR0;         // EXTI c PA0
   EXTI->RTSR |= EXTI_RTSR_TR0;      //   _/-
   NVIC_SetPriority(EXTI0_IRQn, 7);   // ПРИОРИТЕТ NVIC = 7 > 5 (миним)!
   NVIC_EnableIRQ(EXTI0_IRQn);         // включен вектор

   uint8_t count = 0;

/*-- Функционал задачи ---------- ----------------------------*/
   for (;;)
   {
      count++;
      if(count == 9)
      {
         REDLED_ON;     // блям-блям красным светодиодом
         sDelay(500);    // имитация работы UART
         REDLED_OFF;
         sDelay(250);
         REDLED_ON;
         sDelay(800);
         REDLED_OFF;
         count = 0;
      }
      vTaskSuspend(xTaskSensor_Handle);   // остановка этой задачи
   }
}//----------------------------------------------
//=================================

/*-----------------------------------------------
* @brief:   Обработчик прерывания от EXTI0.
* @param:   
* @retval:   
*/
void EXTI0_IRQHandler(void)
{
   EXTI->PR = EXTI_PR_PR0;                  // сброс флага этого прерывания
   xTaskResumeFromISR(xTaskSensor_Handle);   // возобновление задачи Sensor
   portEND_SWITCHING_ISR(pdTRUE);         //  и переключение на нее
}

при этом можно обходиться без семафоров. Задача останавливается и не работает до ее разблокировки из прерывания.
PS. Там наоборот надо было сделать - в начале цикла заблокировать ее, а потом уже выполнять действия... а то при старте операционки и первом запуске задачи она нежелательно сработает.

А вот тут - тест на ошибки. Внешние прерывания следуют с частотой 1 кГц, как и заказывал ТС. Системная частота 16 МГц, частота тиков RTOS = 1 кГц.
Как видно, захвачено Total = 31000 осциллограмм (это 25 минут непрерывно!) - и ни одной ошибки, ни одного сбоя (Fail = 0), всё четко.


Вложения:
DS1Z_QuickPrint33.png
DS1Z_QuickPrint33.png [ 25.21 Кб | Просмотров: 1437 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 22 ноя 2017, 16:07 
Только пришел

Зарегистрирован: 30 сен 2016, 14:09
Сообщения: 8
Благодарю всех за ответы.

Попробовал еще несколько вариантов, - в том числе тот, что предложил BusMaster - ситуация снова повторилась, причем работает через раз - подключаешь раз - сразу зависает, - подключаешь второй раз - "выплевывает" примерно сотню данных, зависает, и потом, спустя минуту снова начинает выдавать данные, но на частоте около 5Гц. Видимо у меня проблема в чем-то другом. Грешу на то, что слишком много обработок использую данных. Наверное стоит как-то замерить скорость выполнения всех этих обработок и думать дальше. Во всяком случае узнал много нового и полезного.

Сейчас, в задачу входило считать данные с сенсора, преобразовать их до нужного формата, отправить в математический фильтр и после отправить в UART (аналогично Вашему счетчику в последней задаче, - каждую сотую посылку). Возможно все эти преобразования и обработки занимают больше времени чем приходит новое прерывание, - потому все рушится. Хотя этот же проект работает без RTOS идеально, ничего не зависает и не тормозит. Частота к слову выставлена максимальная, - 168Мгц.

UPD: Попробовал просто подавать статичные числа в фильтр (без чтения датчика,- закоментировал) -ничего не виснет, работает отлично. Возможна ли проблема в том, что я читаю датчик по I2c и надо ли как-то по особенному настраивать i2c для RTOS?
Сейчас так:
Код:
void MX_I2C1_Init(void)
{
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}

Читаю датчик так:
Код:
HAL_I2C_Mem_Read(&hi2c1, (uint16_t)Sensor_ADDRESS << 1, Start_Reg, 1, Buf, 14, 0xFFFF);

Использую Mem_Read из за того что регистры датчика расположены последовательно - читаю их сразу пачкой.
С уважением,
Максим


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 22 ноя 2017, 18:42 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2103
Ааа, HAL.... нууу тогда не удивительно, что 168 МГц - и не хватает... Такое впечатление, что HAL изобрели специально, чтобы у юзеров ниче не получалось.
При 400 кГц I2C, и если запросы по шине идут с частотой 1 кГц, то за этот интервал чисто физически можно передать порядка 40 байт. У вас сколько байт в каждом запросе? Я не знаю, как реализована эта функция в HAL, поэтому учитывая дикие лаги HAL-а, количество байт может быть раза в два меньше.

Там еще следовало бы разобраться с получившейся структурой RTOS. Посмотреть, разобраться с приоритетами задач. Посмотреть, хватает ли стека в каждой задаче. При нехватке стека задачи, данные внутри нее могут запросто портиться, что как раз и будет приводить к остановке работы.
Ненужные задачи нужно останавливать (vTaskSuspend), чтобы они не мешались и не тратили системное время.
И конечно же внимательно относиться к использованию ...fromISR-функций RTOS - неправильное применение способно наглухо подвесить операционку.
И если вообще дело может быть решено без RTOS, то ставить RTOS - излишне. То есть, считать данные с датчика, отфильтровать из и передать по UART-у - тут RTOS просто не нужна, потому что выполнение всего потока - последовательное: получили-посчитали-передали.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 22 ноя 2017, 21:28 
Только пришел

Зарегистрирован: 30 сен 2016, 14:09
Сообщения: 8
Если я не разучился считать, я считываю 14 регистров в каждом прерывании, каждый регистр имеет тип uint8_t, т.е. 1 байт, т.е. целиком я считываю 14 байт, вроде помещаюсь в рамки.

На данный момент в RTOS нет ничего кроме двух задач - мигающий светодиод и вторая задача, в которой вызывается функция, в которой все и происходит. Использование RTOS для себя объяснил тем, что впоследствии, возможно, будут добавляться различные задачи, и их достаточно удобно добавлять используя RTOS (если, конечно, наконец разобраться, как и что правильно использовать в нем). Да и просто очень хотелось бы наконец разобраться со столь полезной штукой, чтобы в дальнейшем ее применять правильно.

Попробую просмотреть вопрос со стеком, спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 22 ноя 2017, 21:32 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 1375
А взять SystemView и посмотреть что происходит в этой сложной программе ?
Хоть с RTOS, хоть без.
Ну или на крайний случай RTT использовать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS STM32F4 и внешние прерывания
СообщениеДобавлено: 22 ноя 2017, 22:34 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1125
Откуда: Германия
maxbelyx писал(а):
Если я не разучился считать, я считываю 14 регистров в каждом прерывании, каждый регистр имеет тип uint8_t, т.е. 1 байт, т.е. целиком я считываю 14 байт, вроде помещаюсь в рамки.

У вас STM32F4, что означает, что это 32-х битный процессор, что, в свою очередь означает, что один регистр имеет тип uint32_t, т.е. 32 бита.
А Вы из I2C считываете. Тогда может быть и да

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB