Страница на этапе разработки
Дальше мы будем писать программный код в среде программирования MXCubeIDE так как он имеет компилятор предназначенный именно для системы FreeRTOS в отличии от Keil uVision.
В данном уроке мы с Вами Создадим четыре задачи, предварительно настроив ножки РС9, РС8, РС6, РС5 и дадим им названия LED1, LED2, LED3, LED4.
Так как у нас все четыре задачи будут одинаковые, мы создадим одну задачу которая запустит все остальные.
Для этого мы создадим структуру с помощью которой буду переданы параметры для наших задач:
/* USER CODE BEGIN PTD */
typedef uint32_t TaskProfiler;
typedef struct
{
GPIO_TypeDef *port;
uint16_t pin;
uint32_t delay_ms;
TaskProfiler *profiler;
} LedTaskParam_t;
/* USER CODE END PTD */
Дальше мы описываем переменные для создания наших задач:
/* USER CODE BEGIN PD */
#define LED_BLINK_DELAY_MS 500U
/* USER CODE END PD */
/* USER CODE BEGIN PM */
osThreadId_t vLed1Handle;
osThreadId_t vLed2Handle;
osThreadId_t vLed3Handle;
osThreadId_t vLed4Handle;
const osThreadAttr_t vLed1_attributes = {
.name = «vLed1»,
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow,
};
const osThreadAttr_t vLed2_attributes = {
.name = «vLed2»,
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow,
};
const osThreadAttr_t vLed3_attributes = {
.name = «vLed3»,
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow,
};
const osThreadAttr_t vLed4_attributes = {
.name = «vLed4»,
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow,
};
/* USER CODE END PM */
Дальше мы создаем параметры для наших задач.
/* USER CODE BEGIN PV */
TaskProfiler LED1TaskProfiler = 0;
TaskProfiler LED2TaskProfiler = 0;
TaskProfiler LED3TaskProfiler = 0;
TaskProfiler LED4TaskProfiler = 0;
/*
* LED1_Pin, LED2_Pin, LED3_Pin, LED4_Pin.
*/
static LedTaskParam_t led1_param =
{
.port = GPIOC,
.pin = LED1_Pin,
.delay_ms = LED_BLINK_DELAY_MS,
.profiler = &LED1TaskProfiler
};
static LedTaskParam_t led2_param =
{
.port = GPIOC,
.pin = LED2_Pin,
.delay_ms = LED_BLINK_DELAY_MS,
.profiler = &LED2TaskProfiler
};
static LedTaskParam_t led3_param =
{
.port = GPIOC,
.pin = LED3_Pin,
.delay_ms = LED_BLINK_DELAY_MS,
.profiler = &LED3TaskProfiler
};
static LedTaskParam_t led4_param =
{
.port = GPIOC,
.pin = LED4_Pin,
.delay_ms = LED_BLINK_DELAY_MS,
.profiler = &LED4TaskProfiler
};
/* USER CODE END PV */
Дальше мы объявляем функцию задачи и создаем наши четыре задачи.
/* USER CODE BEGIN PFP */
void LedTask(void *argument);
/* USER CODE END PFP */
/* USER CODE BEGIN RTOS_THREADS */
vLed1Handle = osThreadNew(LedTask, &led1_param, &vLed1_attributes);
vLed2Handle = osThreadNew(LedTask, &led2_param, &vLed2_attributes);
vLed3Handle = osThreadNew(LedTask, &led3_param, &vLed3_attributes);
vLed4Handle = osThreadNew(LedTask, &led4_param, &vLed4_attributes);
if ((vLed1Handle == NULL) ||
(vLed2Handle == NULL) ||
(vLed3Handle == NULL) ||
(vLed4Handle == NULL))
{
Error_Handler();
}
/* USER CODE END RTOS_THREADS */
Описываем саму задачу:
void LedTask(void *argument){
LedTaskParam_t *led = (LedTaskParam_t *)argument;
if (led == NULL) {
for (;;) {
osDelay(1000);
}
}
for (;;){
HAL_GPIO_TogglePin(led->port, led->pin);
if (led->profiler != NULL) {
(*led->profiler)++;
}
osDelay(led->delay_ms);
}
}
/* USER CODE END 4 */
Запустив наш программный код, мы увидим как 4 светодиода моргают одновременно. Так как наши задачи одинаковые то и результат работы у всех одинаковые.