Старт ARM. RTOS часть 1-ая. STM32F4 и SAM3N.
Старт ARM. RTOS часть 2-ая.
Старт ARM. RTOS часть 3-ая. Очереди.
Старт ARM. RTOS часть 4-ая. Семафоры.
Старт ARM. RTOS часть 5-ая. Мьютексы.
Старт ARM. RTOS часть 6-ая. Сопрограмма.
Всем привет, продолжаем дальше на практике изучать FreeRTOS. Сегодня речь пойдет о программных таймерах.
Таймер (от англ. Timer) — в информатике средство обеспечения задержек и измерения времени средствами компьютера.
Главной характеристикой таймера является его точность — минимальный гарантированно выдерживаемый интервал времени. По этому параметру таймеры делят на:
малоточные (ошибка измерения может достигать 0,1 с)
точные (ошибка измерения не превышает 0,001 с)
сверхточные (ошибка измерения не превышает 10−6 c)
Существуют два вида таймеров:
Аппаратные таймеры функционируют независимо от центрального процессора и в момент срабатывания генерируют прерывание.
Программные таймеры реализуются за счёт выполнения в цикле заданного количества одинаковых «пустых» операций. При фиксированной частоте работы процессора это позволяет точно определять прошедшее время. Главными минусами такого метода являются: зависимость количества итераций цикла от типа и частоты процессора, невозможность выполнения других операций во время задержки.
Реализовать программный таймер можно использую привязку тактирования процессора.
1. Для создания программного таймера, следует вызвать функцию xTimerCreate().
2. Затем нужно вызвать функцию для запуска таймера xTimerStart().
3. Для сброса таймера нужно вызвать функцию xTimerReset().
4. Для получения идентификатора нужно вызвать функцию pvTimerGetTimerID().
Задача: каждые 2 секунды будем изменять состояния светодиода на отладочной плате 32F746GDISCOVERY.
//... #define TIMER_ID 111 TimerHandle_t xOneShotTimer; const unsigned portBASE_TYPE uxOneShotTimerID = TIMER_ID ; unsigned int uiAutoReloadTimerPeriod = 1 / portTICK_PERIOD_MS; /* Private function prototypes -----------------------------------------------*/ static void SystemClock_Config(void); static void CPU_CACHE_Enable(void); void vOneShotTimersFunction(TimerHandle_t xTimer) { volatile unsigned portBASE_TYPE *pxTimerID; pxTimerID = pvTimerGetTimerID(xTimer); switch (*pxTimerID) { case TIMER_ID: BSP_LED_Toggle(LED1); xTimerStart(xOneShotTimer, 0); break; } } /* Private functions ---------------------------------------------------------*/ /** * @brief Main program * @param None * @retval None */ int main(void) { /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* STM32F7xx HAL library initialization: - Configure the Flash ART accelerator on ITCM interface - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure the system clock to 216 Mhz */ SystemClock_Config(); /* Initialize LED1 */ BSP_LED_Init(LED1); xOneShotTimer = xTimerCreate("OneShotTimer", 2000 / portTICK_PERIOD_MS, pdFALSE, (void*) &uxOneShotTimerID, vOneShotTimersFunction); xTimerReset(xOneShotTimer, 0); vTaskStartScheduler(); /* We should never get here as control is now taken by the scheduler */ for(;;); } //...
Для того чтобы код программы начал работать, его нужно скопировать и вставить в один из проектов для freertos из примеров stm32cubemx для F7 (STM32Cube_FW_F7_V1.2.0\Projects\STM32746G-Discovery\Applications\FreeRTOS).
Так же необходимо в файле конфигурации freertos (FreeRTOSCongig.h) разрешить работу таймеров, для это устанавливаем #define configUSE_TIMERS 1