Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Время срабатывания таймеров и их точность

Ср авг 31, 2022 13:32:05

Добрый день, довольно простая и обыденная задача вызвала большие затруднения с ее решением. Надо от одного таймера запустить 3 других и получить результат, как на рисунке 1.

TIM4 просто циклично задает начало отсчета (зеленая линия) с постоянной частотой. Далее мне надо получить картину как на рисунке, где все параметры (T1, T2, T3, P1, P2, P3) динамически могу меняться путем задания их длительности с ПК.

Основная проблема в том, что я не могу добиться нужной мне точности срабатывания таймеров и установки логических уровней на пинах мк. Для этого попробовал разные подходы:

1. Изначально была идея сделать на прерываниях. Довольно банально, от TIM4 стартуем все таймеры и в их прерываниях выставляем логические уровни и делаем их перезапуск.

Запускаем все таймеры
Спойлер
Код:
void TIM4_Callback(void)
{
   if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
   {
      // START
      GPIOC->BSRR = GPIO_BSRR_BS0;

      // START TIMER 7
      TIM7->ARR = SetTime7 - 1;
      TIM7->SR &= ~ TIM_SR_UIF;
      TIM7->CNT = 0;
      TIM7->DIER = TIM_DIER_UIE;
      LL_TIM_EnableCounter(TIM7);

      // START TIMER 3
      TIM3->ARR = SeеTime3 - 1;
      TIM3->EGR = TIM_EGR_UG;
      TIM3 ->SR &= ~ TIM_SR_UIF;
      TIM3->CNT = 0;
      TIM3->DIER = TIM_DIER_UIE;
      LL_TIM_EnableCounter(TIM3);

      // START TIMER 5
      TIM5->ARR = SetTime5 - 1;
      TIM5->EGR = TIM_EGR_UG;
      LL_TIM_ClearFlag_UPDATE(TIM5);
      TIM5->CNT = 0;
      TIM5->DIER = TIM_DIER_UIE;
      LL_TIM_EnableCounter(TIM5);
   }
   else
   {
      __NOP();
   }

   LL_TIM_ClearFlag_UPDATE(TIM4);
}

Коллбек всех 3х таймеров делаем по такому примеру:
Спойлер
Код:
void TIM7_Callback(void)
{
   if(LL_TIM_IsActiveFlag_UPDATE(TIM7))
   {
      switch (StateTim7)
      {
         case 0:
            StateTim7 = 1;
            // SET PIN LEVEL HIGH
            GPIOC->BSRR = GPIO_BSRR_BS3;
            TIM7->ARR = SetPeriod7 - 1;
            break;

         case 1:
            StateTim7 = 0;
            // SET PIN LEVEL LOW
            GPIOC->BSRR = GPIO_BSRR_BR3;
            LL_TIM_DisableCounter(TIM7);
            break;
      }
   }
   else
   {
      __NOP();
   }

   LL_TIM_ClearFlag_UPDATE(TIM7);
}


В таком виде это работает, но с ошибками. Если выставить тайминги довольно большими, например T7 = 29 мк сек, то в целом картина более менее стабильна (на логическом анализаторе он будет 31.75), т.е. все тайминги по факту будут больше на порядка 1.5 - 2 мк сек, полагаю из за задержки на время запуска таймеров. Хотя такая задержка вызывает вопросы, не много ли?
Но когда я уменьшаю время срабатывания таймера допустим T7 до 0.1 мк сек от старта, то тут во-первых этот тайминг не выставится меньше 2.5 мк сек (Рисунок 2), во вторых почему-то начинает сильно ошибаться величина P7, может уменьшиться в 1.5 раза и тд, происходит какое-то влияние одной величины на другую.
Такая не предсказуемость меня не сильно устроила, поэтому попробовал второй вариант.

2. Решил я переделать все на one pulse mode. В целом идея та же в коллбеке TIM4 стартуем 3 таймера, но уже настроенные в этом режиме. Для эксперимента взял TIM11 и TIM12
Спойлер
Код:
void TIM4_Callback(void)
{
   if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
   {

       TIM11->ARR = 4000;
       TIM11->CCR1 = 1000;
       TIM11->EGR = TIM_EGR_UG;

      TIM11->CNT = 0;
      TIM11->SR &= ~ TIM_SR_UIF;
      TIM11->DIER = TIM_DIER_UIE;

      HAL_TIM_Base_Start(&htim11);
      HAL_TIM_PWM_Start(&htim11, TIM_CHANNEL_1);


       TIM12->ARR = 4000;
       TIM12->CCR2 = 1000;
       TIM12->EGR = TIM_EGR_UG;

      TIM12->CNT = 0;
      TIM12->SR &= ~ TIM_SR_UIF;
      TIM12->DIER = TIM_DIER_UIE;

      HAL_TIM_Base_Start(&htim12);
      HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_2);
   }
   else
   {
      __NOP();
   }

   LL_TIM_ClearFlag_UPDATE(TIM4);
}

Запускаю я их вместе, времена у них заданы одинаковые, а срабатывают они в разное время. А именно таймер 12 опаздывает на 2.5 мк сек. Измерил я, ради интереса, этот участок кода:
Код:
       TIM11->ARR = 4000;
       TIM11->CCR1 = 1000;
       TIM11->EGR = TIM_EGR_UG;

      TIM11->CNT = 0;
      TIM11->SR &= ~ TIM_SR_UIF;
      TIM11->DIER = TIM_DIER_UIE;

      HAL_TIM_Base_Start(&htim11);
      HAL_TIM_PWM_Start(&htim11, TIM_CHANNEL_1);


По длительности он как раз занимает порядка 2.2 мк сек. Отсюда следует, если таким образом запускать 3 таймера подряд, то 3й будет отставать от первого на 5 мк сек. Это трындец будет. Ну и вопрос, опять, почему так много уходит времени на запуск таймера?

3. Третьей моей идеей является взять один таймер с 4мя каналами, запустить его в коллбеке TIM4 и в прерывании от каждого канала запускать еще по одному таймеру, чтобы выдержать необходимые длительности импульсов (P1, P2, P3). Берем пока TIM12 на 2 канала.
Ставлю такие параметры:
Для канала 1 - TIM_OC_InitStruct.CompareValue = 1;
Для канала 2 - TIM_OC_InitStruct.CompareValue = 2500;
Т.е. при запуске в том же самом коллбеке TIM4
Код:
      TIM12->EGR = TIM_EGR_UG;
      LL_TIM_EnableIT_CC1(TIM12);
      LL_TIM_EnableIT_CC2(TIM12);
      LL_TIM_EnableCounter(TIM12);

Спойлер
Код:
void TIM12_Callback(void)
{
   if(LL_TIM_IsActiveFlag_UPDATE(TIM12))
   {
      if(LL_TIM_IsActiveFlag_CC1(TIM12))
      {
         LL_TIM_ClearFlag_CC1(TIM12);
         HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_2);      // Test
         LL_TIM_DisableIT_CC1(TIM12);
      }
      else if(LL_TIM_IsActiveFlag_CC2(TIM12))
      {
         LL_TIM_ClearFlag_CC2(TIM12);
         HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_2);      // Test
         LL_TIM_DisableIT_CC2(TIM12);

         LL_TIM_DisableCounter(TIM12);
      }
      else
      {
         __NOP();
      }
   }
   else
   {
      __NOP();
   }
}


Я должен получить, что первый канал сработает сразу же, а второй как отсчитает 2500 тиков, что равно 25 мксек.
По факту первый стартует спустя 1.5 мк сек, а второй 25 + 1.5 мк сек. Т.е. опять задержка от времени старта единицы мк секунд.

Исходя из этого:
1) Почему такие большие задержки запуска таймеров?
2) Какой подход для решения данной задачи будет самым правильным?
3) Может просто я что-то делаю не так?

Буду благодарен за любые подсказки, ибо не понимаю причину такой работы мк.

Лирическое отступление: мк - stm32f746. Настройка в CubeMX (для таймеров LL), так как используется FreeRTOS, но приоритет таймеров выше чем у любой задачи ОС. Таймеры функции ОС не используют
Вложения
3.png
Рисунок 3
(74.25 KiB) Скачиваний: 62
2.png
Рисунок 2
(27.46 KiB) Скачиваний: 58
1.png
Рисунок 1
(9.92 KiB) Скачиваний: 69

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 12:42:29

Контроллер-то какой?

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 13:03:56

stm32f746

нехилый, однако...

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 13:10:14

Контроллер-то какой?

stm32f746 на плате nucleo

Добавлено after 1 minute 31 second:
Martian, да, на 200 MHz частота, а на запуск таймера уходит 1.5 - 2 мксек, и побороть пока не могу...

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 14:17:13

DmitryR писал(а):stm32f746

Действительно, проморгал.

Посмотрите, например, на странице 794 документа RM0385 табличку с внутренними сигналами промежтаймерными. Можно ведомые таймеры настроить так, чтобы они запускались от события ведущего без участия ядра. Ну и в том же документе конечно написано как это сделать. Может быть придётся использовать не именно те таймеры, что у вас сейчас, но главное, что принцип организации аппаратного взаимодействия таймеров будет понятен.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 14:47:08

>TEHb<, Благодарю, тоже подумал про настройку ведомых таймеров в режиме one pulse mode. В целом сделал, есть одна загвоздка.
Динамически задаю тайминги:
Код:
                    TIM3->ARR = 2000;
                    TIM3->CCR2 = Timer3;
                    TIM3->EGR = TIM_EGR_UG;

                    TIM5->ARR = 2000;
                    TIM5->CCR1 = Timer5;
                    TIM5->EGR = TIM_EGR_UG;

Так как в этом режиме задаются 2 точки, меняю пока только первую - время срабатывания таймера.
Если выставляю величину 250 тиков таймера (2500 нс) и более, то все нормально, тайминги хорошие, таймер, который запустили вторым, отстает от первого на 750 нс (Рис. 1).
Если же поставить CCR1 и CCR2 меньше, например 100 (1000 нс), то сигнал искажается, как на рис. 2 Такое поведение не понятно. Либо что-то не так с настройками, либо все-таки есть минимальный предел, меньше которого таймер не может нормально функционировать, но думаю, что это не так.

Код:
void TIM4_Callback(void)
{
   if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
   {
       TIM3->CNT = 0;
      HAL_TIM_Base_Start(&htim3);
      HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);

      TIM5->CNT = 0;
      HAL_TIM_Base_Start(&htim5);
      HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
   }
   else
   {
      __NOP();
   }

   LL_TIM_ClearFlag_UPDATE(TIM4);
}
Вложения
3.png
(66.78 KiB) Скачиваний: 43
2.png
(62.81 KiB) Скачиваний: 46
1.png
(63.7 KiB) Скачиваний: 47

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 15:16:01

Классическая проблема. Решается включением буферизацией регистров. Если ничего не путаю, то бит ARPE в регистре TIMx_CR1 как раз за это и отвечает.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 15:31:00

У таймеров есть slave-mode с одновременным запуском по мастер-таймеру, либо с запуском по событиям триггеров.
ARPE в CR1 буферизует только ARR регистр. Если надо буферизовать CCRx регистры, биты её разрешения находится в регистрах CCMRx. Буферизация - это загрузка записанных в регистры значений только после наступления события Update, то есть в начале нового цикла счета.

RTOS и HAL могут вносить значительные задержки в доступе непосредственно к регистрам таймера, просто по причине очень длинного кода. И даже если вы назначили высокий приоритет задаче работы с таймерами, она все равно будет на короткое время прерываться с интервалом каждого системного тика, но возвращаться назад, если более приоритетных нет. Системные события никуда не деваются ведь, планировщик не остановлен.
Последний раз редактировалось MLX90640 Чт сен 01, 2022 15:41:16, всего редактировалось 1 раз.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 15:40:47

Если выкинуть калокуб, задержка будет меньше.
Но все-таки, правильней сделать, как советовали: использовать связанные таймеры. Таймер-господин по определенному событию будет пинать своих рабов.
P.S. DmitryR, а что за задача-то? Это случаем не генерирование трех синусоид со сдвигом в 120°?

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 16:36:10

Eddy_Em писал(а):Если выкинуть калокуб, задержка будет меньше.
Eddy_Em, много ли у вас проектов на регистрах для STM32F7?

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 16:43:28

Мурик, если надо будет - будут. Пока мне F7 не нужен. Я вообще не понимаю, честно говоря, для каких целей такую жиробасину можно использовать. Да и дорого ужасно. Дешевле же сделать связку из orange pi + STM32F072 или F103.
Но уж вляпываться в калокод — ну это совсем буээ.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 16:44:18

Кстати, F7 ничем особым не отличается от того же F4 или даже F0 в этом плане. Если писали "на регистрах" для F0, то для F7 точно напишите таймеры. Они не отличаются, за исключением двух дополнительных каналов.
Разве что частота до 216 МГц и расширенный набор инструкций позволяют быстрее "проглатывать" портянки HAL.
Нынче F746 очень дорог. Иной раз H743 может оказаться дешевле.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 18:08:51

>TEHb<, MLX90640, никогда не пользовался буферизацией, надо будет попробовать, спасибо за совет, только я не совсем понял какой регистр за это отвечает.
OC1PE: Output Compare 1 preload enable
Бит для управления буферизацией регистра TIMx_CCR1.
0: буферизация регистра TIMx_CCR1 не используется; запись в регистр TIMx_CCR1 может быть произведена в любой момент и новое значение начнёт использоваться немедленно.
1: используется буферизация регистра TIMx_CCR1; операции чтения/записи выполняются с буферным регистром, новое значение из буфера передаётся в активный регистр (который и управляет работой таймера) при каждом событии обновления.

Вот, вроде, подходит, или все-таки CCMRx?

RTOS и HAL могут вносить значительные задержки в доступе непосредственно к регистрам таймера, просто по причине очень длинного кода. И даже если вы назначили высокий приоритет задаче работы с таймерами, она все равно будет на короткое время прерываться с интервалом каждого системного тика, но возвращаться назад, если более приоритетных нет. Системные события никуда не деваются ведь, планировщик не остановлен.


Там у FreeRTOS максимальный приоритет 5, у всех этих таймеров задан приоритет 3, функции ОС они не используют, по идее ОС не должна влиять, но точно утверждать не могу...

Eddy_Em,
Если выкинуть калокуб, задержка будет меньше.
Ну про куб и HAL... Там ОС и Ethernet (LwIP), писать это на регистрах точно нет, поэтому какой выход я тут пытаюсь найти: настройка периферии на HAL или LL, далее все, что не имеет критическое значение и может работать медленно и не очень эффективно на HAL или том же LL, все, что критически важно на CMSIS. Ну как-то так... Благо ресурсы контроллера позволяют.

а что за задача-то? Это случаем не генерирование трех синусоид со сдвигом в 120°?

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

Я вообще не понимаю, честно говоря, для каких целей такую жиробасину можно использовать. Да и дорого ужасно.

Ну я привожу же не весь проект, а только его конкретную часть, где возникли проблемы, но на самом деле там можно обойтись более простым контроллером, не 103 конечно, но каким-нибудь 407. Просто у меня отладочная плата nucleo c ethernet, мне удобно пользоваться такой, а там уже как проект готов, можно думать какой мк взять. А стоимость, стоимость такой платы месяца 3-4 назад около 3-4 тыс, с алиэкспресс приехали абсолютно нормальные платы один в один как в чип и дипе

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 18:18:20

CCMR1 и CCMR2, биты OC1PE, OC2PE, OC3PE, OC4PE (расшифровывается как Output compare 1(2,3,4) preload enable, capture/compare mode register)

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 18:21:23

А стоимость, стоимость такой платы месяца 3-4 назад около 3-4 тыс, с алиэкспресс приехали абсолютно нормальные платы один в один как в чип и дипе

Ну вот. А в случае с orange pi + дешевый МК вышло бы 2.5-3.5тыр. И на нормальном линуксе писать, а не извращаться с говеным lwip в убогой RTOS! И можно спокойно будет по ssh работать с железом (чего нельзя в случае МК)...

P.S. Получается, нужно сгенерировать три импульса строго определенной длительности, идущие через строго определенные промежутки времени? А обязательно отсчитывать прямо от общего начала? Ведь можно отсчитывать от времени подачи первого импульса. Тогда нужно будет использовать один таймер в режиме господина и два таймера в режиме раба. У первого CC1 будет определять длительность импульса, а CC2 и CC3 - пинать подчиненные таймеры. У тех же CC1 будет определять длительность.
Иначе придется задействовать четыре таймера: один господин и три раба.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 18:30:15

DmitryR писал(а):Там у FreeRTOS максимальный приоритет 5, у всех этих таймеров задан приоритет 3

Это всё внутри операционки, а ей самой ещё нужно с железом и задачами цацкаться. Systick, например, какой-нибудь может кааак сработать и всё, времена уплыли. Если временные интервалы и формировать на ядре, то нужно чертовски точно до такта понимать что и как там работает. Во всех смыслах ловчее получается таки аппаратными средствами периферии, благо таковые средства имеются.
Конкретный бит конкретного регистра не подскажу, я больше по HRTIM, но направление задали куда надо. Читайте, пробуйте.

Eddy_Em писал(а):orange pi + дешевый МК

Можно ещё ноутбук старый прикупить за такие деньги и не караться с этим одноплатником. Тут и экран, и клавиатура и всё такое. Лично я бы для точных временных интервалов и вовсе 334 контроллер бы взял.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 19:44:52

Eddy_Em,
А в случае с orange pi + дешевый МК вышло бы 2.5-3.5тыр

Ну это довольно сомнительная выгода, чтобы так заморачиваться)
На счет LWIP согласен, с ним тяжко, особенно когда была задача разогнать максимальную скорость передачи данных, он явно не для этого (хотя на форуме st есть серия постов, где этот стек разогнали до 90-95 Мбит/сек).
К ОС особо претензий нет, но если бы LWIP (HTTP) не требовало бы ее, то и смысла в ней тоже нет для этой задачи.

И на нормальном линуксе писать
Все эти инструменты дело вкуса, навыков и времени на их осваивание. Raspberry pi еще есть)
Но если бы мк совсем не тянул задачу, лично я бы лучше взял связку мк + ПЛИС.
Как правило самые критичные функции они же и являются самыми простыми по функционалу, типа как здесь таймеры, а самое объемное и замороченное, типа как передача данных по Ethernet, не столь требовательны к скорости выполнения.

P.S. Получается, нужно сгенерировать три импульса строго определенной длительности, идущие через строго определенные промежутки времени? А обязательно отсчитывать прямо от общего начала? Ведь можно отсчитывать от времени подачи первого импульса.

Нуу, в идеале да, строго определенной длительности и в строго определенное время. Строгость тут относительная, например я готов понять, если я запущу таймер так, чтобы он сработал через 20 мксек, а он сработает через 20.25 это одно дело, а если он сработает через 23 мк сек, это дикость для таймера, который тактируется частотой 100 МГц.
Тут больше нюанс в том, что мне не нужны артефакты в работе кода, а именно ситуация как на приведенном выше скрине, когда я меняю время срабатывания таймера, а у меня появляются ложные срабатывания, либо была еще ситуация, когда мной изменялся только промежуток времени начала импульса, а его длительность сама изменилась в 1.5 раза, хотя этот параметр никто не трогал.
Такое поведение наблюдается, когда он старта до момента срабатывания таймера требуется меньше 1-5 мк секунд. В этом диапазоне наблюдается хаотичное поведение не соответствующее требуемому.

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

Но от первого таймера отталкиваться нельзя, так как все параметры (время старта и длительность импульса) могут быть и будут динамически меняться, не исключена ситуация, когда второй импульс, в какой-то момент, станет первым и тд.

Поэтому суть в том, чтобы все 3 таймера были привязаны к одному моменту старта, были довольно точны по своему срабатыванию (ну в пределах 100 нс) и таймеры могли иметь возможность сработать как можно раньше от своего запуска. Ну и, соответственно, не было ошибок в работе.

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

Ну вот получается сейчас так реализовано, с ведущим и ведомыми таймерами. Только один момент, сейчас я в прерывании от ведущего таймера запускаю ведомые в режиме one pulse mode:
Код:
void TIM4_Callback(void)
{
   if(LL_TIM_IsActiveFlag_UPDATE(TIM4))
   {
       TIM3->CNT = 0;
      HAL_TIM_Base_Start(&htim3);
      HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);

      TIM5->CNT = 0;
      HAL_TIM_Base_Start(&htim5);
      HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
   }
   else
   {
      __NOP();
   }

   LL_TIM_ClearFlag_UPDATE(TIM4);
}

А могу я как-то один раз запустить ведомые и ведущий таймер вместе, чтобы мне не надо было ведомые каждый раз в прерывании от ведущего запускать? Тогда это будет работать без участия процессора.

Код:
Systick, например, какой-нибудь может кааак сработать и всё

Если я не ошибаюсь, то и Systick имеет приоритет не выше 5го, т.е. эти таймеры с приоритетом 3 перебью все процессы ОС, именно поэтому я и не могу использовать в них функционал ОС

Добавлено after 8 minutes 10 seconds:
Я как-то даже не подумал попробовать запустить ведущие таймеры, а потом ведомый, интересно, как себя поведет мк

Добавлено after 11 minutes 1 second:
MLX90640,
где-нибудь перед запуском или в инициализации добавить
TIM3->CCMR1 |= TIM_CCMR1_OC1PE;
Правильно же понимаю?

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 19:49:31

Systick - это таймер системных тиков для RTOS, и он ну полюбасу будет вызываться вот как угодно, просто для того, чтобы сама операционка работала. Если его заблокировать, то операционка повиснет. Тут как бы не надо путать приоритеты задач внутри операционки и приоритеты прерываний микроконтроллера. Приоритеты задач - это очередность выполнения их и величина выделяемого на задачу времени.
Щас как бы нет особо времени вникнуть в суть проблемы вашей, я просто временно отвлекаюсь на форум.

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 19:58:39

MLX90640, Мои познания в работе FreeRTOS не так значительны, чтобы спорить на счет ее работы)
Я думал Systick нужен, чтобы в заданные промежутки времени пинать шедулер, который всех прерывает и передает управление, но может Вы и правы)

Re: Время срабатывания таймеров и их точность

Чт сен 01, 2022 20:18:53

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