Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.76/25: Рейтинг темы: голосов - 25, средняя оценка - 4.76
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511

Время переключения между задачами и прерываниями в FreeRTOS

12.04.2021, 14:24. Показов 5682. Ответов 36

Студворк — интернет-сервис помощи студентам
Решил сделать новую тему, так как вопрос выходит за рамки рассмотрения прошлой темы
Получить заданную тактовую частоту на пин мк
Вопрос возник с временем переключения между прерываниями/задачами в FreeRTOS.
Один пин настроен на внешнее прерывание, при наступлении высокого уровня на этом пине вызывается это прерывание, в котором запускается 4 канала таймера. Соответственно как только таймеры будут запущены и начнут отсчет, то каждый из каналов будет вызывать свое прерывание, в котором будет "дергаться" другой пин. Первое прерывание таймера начинается сразу же с 0.
По-сути пока что код больше ничего не делает. Проблема заключается в том, что начиная с момента запуска каналов таймера, до наступления прерывания первого из каналов проходит порядка 45 мксек. Что все это время делает код непонятно, отладчик постоянно попадает в прерывание системного таймера. Хотя сам системный таймер работает раз в млсек. "Игра" с приоритетами результата не дает.
Внешнее прерывание, которое срабатывает по входящему уровню на пин:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == GPIO_PIN_4)      
    {
        HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_1);
        HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_2);
        HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_3);
        HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_4);
        }
    else
    {
        __NOP();
    }
}
Завели каналы таймера, первый канал настроен на срабатывание сразу же, т.е. на первом же тике (период таймера 1 мксек), последующие с интервалом десятки мксек
Прерывание от таймера:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM4)
    {
        if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
        {
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);              
        }
        else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
        {
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);             
        }
        else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
        {
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);              
        }
        else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
        {
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);            
 
            HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_1);
            HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_2);
            HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_3);
            HAL_TIM_OC_Stop_IT(&htim4, TIM_CHANNEL_4);
                }
Вот по сути и основное, что хотелось бы получить на данном этапе. Думал с FreeRTOS сделаю все лаконично и быстро. А без ОС тоже особо не получится, там еще http и ajax будут. Переключение между потоками ОС еще не оценивал по времени, но судя по всему там будет еще больше. Может есть у кого-нибудь идеи, что тут не так, где идет потеря времени?
Миниатюры
Время переключения между задачами и прерываниями в FreeRTOS  
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.04.2021, 14:24
Ответы с готовыми решениями:

Как измерить время между прерываниями по USART
Есть входящий поток данных от устройства по USORT. Динные передаются пакетами по 13 байт, между которыми интервал 28..30 мкс (битрейт...

Относительное время между прерываниями таймеров в МК за день
Возник следующий вопрос: Имеется три таймера. Второй и третий таймер запускаются с помощью первого. Например, TYM1 прерывание раз в...

Непонятки с FreeRTOS и прерываниями
Не работают прерывания при использовании FriiRTOS. Инициализация таймера. /* Включаем тактирование таймера 3*/ ...

36
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
13.04.2021, 11:57  [ТС]
Студворк — интернет-сервис помощи студентам
_SayHello, Отладчик меня почему-то периодически перебрасывает в эту фукнцию, несколько раз за цикл прерывание- таймер
C
1
2
3
4
5
6
7
8
9
10
void TIM1_UP_TIM10_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 0 */
  HAL_TIM_IRQHandler(&htim1);
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
Хотя это TIM1, он заведен как системный и срабатывает каждую миллисекунду. Его я анализатором смотрел, он нормально срабатывает. Сейчас еще раз пройдусь отладчиком
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
13.04.2021, 12:19
DmitryDDDD, а в прерывание TIM4 пападает вообще?
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
13.04.2021, 12:27  [ТС]
_SayHello, Да, после попадания в EXTI запускаются все каналы таймера, отсюда HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_1);
попадаю сюда
C
1
2
3
4
5
6
7
8
9
10
void TIM1_UP_TIM10_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 0 */
  HAL_TIM_IRQHandler(&htim1);
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
Дальше
C
1
HAL_TIM_PWM_PulseFinishedCallback(htim);
Потом опять
C
1
2
3
4
5
6
7
8
9
10
void TIM1_UP_TIM10_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 0 */
  HAL_TIM_IRQHandler(&htim1);
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
И вот уже попадаю в прерывание от таймера
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
13.04.2021, 12:40
DmitryDDDD, во время дебага надо фризить таймеры, иначе пока стоишь на точке останова аппаратный таймер считает
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
13.04.2021, 13:02  [ТС]
_SayHello, Не подскажите как это сделать? А то по дебагеру почти ничего не нашел полезного, а сам им пользуюсь скорее на интуитивном уровне и не часто
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
13.04.2021, 13:13
DmitryDDDD, поищите регистр Debug MCU APB2 Freeze register в RM
1
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
13.04.2021, 14:30  [ТС]
_SayHello,
Сюда попадаю, долго тут кручусь, но не могу по тикам отследить
C
1
2
3
4
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}
У меня заведена переменная по которой отслеживаю сколько тиков где нахожусь в коде
char str_DWT[16] = {0,};
uint32_t count_tic = 0;
Как ее объявить правильно, чтобы она была доступна из всех участков программы?

Фриз сделал сразу после иницализации, вроде номрально работает
C
1
2
3
4
5
6
7
8
9
10
11
12
13
  RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
  RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
  HAL_DBGMCU_EnableDBGStandbyMode();
  HAL_DBGMCU_EnableDBGStopMode();
 
  DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM1_STOP;
  DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP;
  DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM3_STOP;
  DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM4_STOP;
  DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM5_STOP;
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
13.04.2021, 14:35
DmitryDDDD,
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
Как ее объявить правильно, чтобы она была доступна из всех участков программы?
Очевидно, объявить ее глобальной.

А в прерывание TIM4 то вообще залетает? Там ставили точку останова?
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
13.04.2021, 17:02  [ТС]
_SayHello, объявляю как extern, не получается
Цитата Сообщение от _SayHello Посмотреть сообщение
А в прерывание TIM4 то вообще залетает? Там ставили точку останова?
Да, в прерывание попадает, во все прерывания от 4х каналов таймера. Но уже с задержкой. Т.е. если например отслеживать по тикам, то после запуска всех каналов таймера
C
1
2
3
4
5
6
7
8
9
10
11
12
        // DWT counter START
        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
        DWT->LAR = 0xC5ACCE55;
        DWT->CYCCNT = 0;
        DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
 
        __HAL_TIM_CLEAR_FLAG(&htim4, TIM_SR_UIF);
 
        __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC2);
        __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC3);
        __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC4);
         HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_1);     // в этой точке DWT_CYCCNT = 430
DWT_CYCCNT равняется порядка 430, то в преывание от таймера попадаю уже с DWT_CYCCNT = 9070
C
1
2
3
4
5
6
7
        if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
        {
            // DWT counter result
            count_tic = DWT_CYCCNT;
 
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);               // тут DWT_CYCCNT = 9070
        }
Миниатюры
Время переключения между задачами и прерываниями в FreeRTOS  
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
14.04.2021, 07:26  [ТС]
_SayHello, ValeryS, Вот сколько не пробую, не могу глобально объявить нжную мне переменную DWT_CYCCNT
C
1
2
3
#define    DWT_CYCCNT    *(volatile uint32_t*)0xE0001004
#define    DWT_CONTROL   *(volatile uint32_t*)0xE0001000
#define    SCB_DEMCR     *(volatile uint32_t*)0xE000EDFC
На extern ругается компилятор
Без этого нормально по тикам не получается отследить маршрут от EXTI до прерывания таймера
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
14.04.2021, 09:18
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
объявить нжную мне переменную DWT_CYCCNT
вообще то это не переменная, это макрос
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
C
1
#define    DWT_CYCCNT    *(volatile uint32_t*)0xE0001004
опиши в отдельном файле например "MyMacro.h" и подключай этот файл где нужно
1
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
14.04.2021, 10:48  [ТС]
ValeryS, _SayHello, Сделал, описал, прошелся отладкой. Отладчик показывает, что большую часть времени код висит тут
C
1
2
3
4
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}
Примерно 4/5 от времени с момента запуска всех каналов таймера до наступления первого прерывания от канала таймера.
Миниатюры
Время переключения между задачами и прерываниями в FreeRTOS  
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
14.04.2021, 12:07  [ТС]
А попадаю я туда, насколько я понял, отсюда
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;
 
  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }
 
  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
Добавлено через 46 минут
Да, почему-то попадаю в функцию задержки и кручусь в цикле пока не выполнится условие
C
1
2
3
  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
14.04.2021, 13:07
DmitryDDDD, теперь вопрос, кто вызывает этот delay
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
14.04.2021, 13:13  [ТС]
_SayHello, По-моему сюда код перед этим попадал, сейчас еще раз пройдусь
C
1
2
3
4
5
6
7
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
          htim->OC_DelayElapsedCallback(htim);
          htim->PWM_PulseFinishedCallback(htim);
#else
          HAL_TIM_OC_DelayElapsedCallback(htim);
          HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
14.04.2021, 13:34  [ТС]
_SayHello,
Может что с настройками таймера?
Или все это переписать на регистры или LL, может поможет?
Потому что даже если запускать таймер не из прерывания, все равно такая же ерунда получается
Миниатюры
Время переключения между задачами и прерываниями в FreeRTOS   Время переключения между задачами и прерываниями в FreeRTOS  
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
15.04.2021, 13:01  [ТС]
_SayHello, ValeryS, Не знаю как это работает, а точнее до конца еще не разобрался, но помогло такое решение: добавить перед запуском таймера TIM4->EGR = TIM_EGR_UG;
C
1
2
3
4
5
6
7
        TIM4->EGR = TIM_EGR_UG;
        LL_TIM_EnableIT_CC1(TIM4);
        LL_TIM_EnableIT_CC2(TIM4);
        LL_TIM_EnableIT_CC3(TIM4);
        LL_TIM_EnableIT_CC4(TIM4);
        //LL_TIM_EnableIT_UPDATE(TIM4);
        LL_TIM_EnableCounter(TIM4);
Все-таки надо простые функции писать на cmsis, а hal оставить для ethernet и freertos, иначе отлавливание всех ошибок, задержек и прочего в нагенерированном коде сводит на нет весь смысл этой быстрой генерации
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.04.2021, 13:01

FreeRTOS - частота переключения больше 1KHz?
Приветствую! Вопрос вот в чем. Я использую STM32F4 с частотой 96MHz. Хотелось бы увеличить частоту переключения задач - скажем, 10 KHz,...

Связь в SQL между задачами MS Project Server и задачами Sharepoint
Добрый день всем. При создании задачи проекта на серверном MS Project 2013 создаются и синхронизируются задачи в связанном с этим проектом...

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

Многозадачность. Переключение между 3 задачами
не могу понять где ошибка в коде: хочу реализовать переключение между 3 задачами, компилю tasm-ом, запускаю на DOSbox-е, выдает ошибку:...

Переключения между формами
всем привет! вопрос: Form1 открывается при запуске программы, на Form1 нажимаю на кнопку, открывается Form2 (), в Form2 хочу изменить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru