2. RTOS任务创建与调度观察

任务定义

本案例在STM32F103开发板上,基于FreeRTOS创建两个独立任务:任务A控制LED以500ms周期闪烁,任务B控制蜂鸣器以200ms周期鸣响。通过观察两个任务互不阻塞地交替运行,验证RTOS多任务并发调度机制。

硬件连接

STM32F103 Cortex-M3 @72MHz PA1 PA2 330Ω LED GND NPN 蜂鸣器 3.3V GND ● PA1 → LED ● PA2 → 蜂鸣器 任务A: LED 500ms翻转 任务B: 蜂鸣器 200ms翻转

代码实现


// main.c
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"

// 引脚定义
#define LED_PIN       GPIO_PIN_1
#define LED_PORT      GPIOA
#define BUZZER_PIN    GPIO_PIN_2
#define BUZZER_PORT   GPIOA

// 任务句柄
osThreadId_t taskAHandle;
osThreadId_t taskBHandle;

// 任务函数声明
void TaskA_LED(void *argument);
void TaskB_Buzzer(void *argument);

// 任务属性定义
const osThreadAttr_t taskA_attr = {
    .name = "TaskA_LED",
    .stack_size = 128 * 4,
    .priority = osPriorityNormal,
};

const osThreadAttr_t taskB_attr = {
    .name = "TaskB_Buzzer",
    .stack_size = 128 * 4,
    .priority = osPriorityNormal,
};

// 任务A:控制LED 500ms翻转
void TaskA_LED(void *argument) {
    while (1) {
        HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
        osDelay(500);  // 500ms延时
    }
}

// 任务B:控制蜂鸣器 200ms翻转
void TaskB_Buzzer(void *argument) {
    while (1) {
        HAL_GPIO_TogglePin(BUZZER_PORT, BUZZER_PIN);
        osDelay(200);  // 200ms延时
    }
}

// GPIO初始化
static void GPIO_Init(void) {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = LED_PIN | BUZZER_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

// 主函数
int main(void) {
    HAL_Init();
    GPIO_Init();
    
    // 初始化RTOS内核
    osKernelInitialize();
    
    // 创建两个任务
    taskAHandle = osThreadNew(TaskA_LED, NULL, &taskA_attr);
    taskBHandle = osThreadNew(TaskB_Buzzer, NULL, &taskB_attr);
    
    // 启动调度器
    osKernelStart();
    
    while (1) {
        // 不会执行到这里
    }
}

工程配置说明

本案例基于STM32CubeMX生成的FreeRTOS工程,需在CubeMX中完成以下配置:

  • 启用FreeRTOS CMSIS_V1接口(或V2,代码兼容)
  • 将PA1、PA2配置为GPIO输出
  • 时钟配置为72MHz主频
  • 堆栈大小:每个任务分配128字(512字节)

验证方法

运行与观察:

  1. 编译并烧录程序到STM32F103开发板
  2. 上电后观察LED和蜂鸣器行为

判定标准:

  • LED以约500ms周期闪烁(亮250ms,灭250ms)
  • 蜂鸣器以约200ms周期鸣响(响100ms,停100ms)
  • 两个任务互不阻塞,LED闪烁频率不受蜂鸣器影响,反之亦然
  • 若LED和蜂鸣器各自按预期频率工作且互不干扰,则判定多任务并发执行成功

预期输出:由于两个任务独立运行,LED和蜂鸣器各自按照自己的延时参数翻转GPIO,观察到的现象是LED慢速闪烁、蜂鸣器快速鸣响,两者同时进行且节奏独立。