Старт ARM. RTOS часть 1-ая. STM32F4 и SAM3N.
Старт ARM. RTOS часть 2-ая.
Старт ARM. RTOS часть 3-ая. Очереди.
Старт ARM. RTOS часть 4-ая. Семафоры.
Старт ARM. RTOS часть 5-ая. Мьютексы.
Всем привет, продолжаем дальше на практике изучать FreeRTOS на базе STM32F429i – DISCO. Сегодня на повестки дня сопрограммы.
Сопрограмма (англ. coroutine) — компонент программы, обобщающий понятие подпрограммы, который дополнительно поддерживает множество входных точек (а не одну как подпрограмма) и остановку и продолжение выполнения с сохранением определённого положения.
Сопрограммы являются более гибкими и обобщёнными, чем подпрограммы, но реже используются на практике. Применение сопрограмм являлось методикой ещё ассемблера, практиковалось лишь в некоторых высокоуровневых языках (Simula, Modula-2). Сопрограммы хорошо пригодны для реализации многих похожих компонентов программ (итераторов, бесконечных списков, каналов, совместных задач).
Сопрограммы являются более обобщёнными, чем подпрограммы. Подпрограмма имеет всегда одну входную точку, сопрограмма имеет стартовую точку входа и размещённые внутри последовательность возвратов и следующих за ними точек входа. Подпрограмма может возвращаться только однажды, сопрограмма может возвращать управление несколько раз. Время работы подпрограммы определяется принципом LIFO (последняя вызванная подпрограмма завершается первой), время работы сопрограммы определяется её использованием и необходимостью.
Сопрограмма похожа на задачу, она также представляет собой независимый поток команд процессора, и ее можно использовать как базовую единицу программы. Программа, работающая под управлением FreeRTOS, может состоять из множества сопрограмм.
Самое главное преимущество сопрограмм перед задачами — это то, что использование сопрограмм позволяет достичь значительной экономии оперативной памяти по сравнению с использованием задач во FreeRTOS.
Открываем FreeRTOSConfig.h и изменяем #define configUSE_CO_ROUTINES 0 #define configUSE_IDLE_HOOK 0 на #define configUSE_CO_ROUTINES 1 #define configUSE_IDLE_HOOK 1
Пример coroutine
void SystemClock_Config(void); static void MX_GPIO_Init(void); void vLED1(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex){ crSTART(xHandle); for(;;){ HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_13); crDELAY( xHandle, 200 / portTICK_RATE_MS); } crEND(); } void vLED2(xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex){ crSTART(xHandle); for(;;){ HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_14); crDELAY( xHandle, 200 / portTICK_RATE_MS); } crEND(); } int main(void) { HAL_Init(); SystemClock_Config(); HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); MX_GPIO_Init(); xCoRoutineCreate(vLED1, 1, 0); xCoRoutineCreate(vLED2, 1, 0); vTaskStartScheduler(); } void vApplicationIdleHook( void ) { for(;;) { vCoRoutineSchedule(); } }
С сопрограммами на сегодня все! В следующий раз разберем пример для таймеров. 🙂