news 2026/4/23 7:51:39

给STM32F103的Blue Pill开发板装上µC/OS-III:从CubeMX配置到多任务LED闪烁的保姆级教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
给STM32F103的Blue Pill开发板装上µC/OS-III:从CubeMX配置到多任务LED闪烁的保姆级教程

给STM32F103的Blue Pill开发板装上µC/OS-III:从CubeMX配置到多任务LED闪烁的保姆级教程

第一次接触实时操作系统(RTOS)时,看着开发板上两个LED灯以不同频率交替闪烁,那种成就感至今难忘。本教程将带你用最经典的Blue Pill开发板(STM32F103C8T6)和µC/OS-III系统,重现这个"Hello World"级别的多任务实验。不同于单纯的理论讲解,我们会从CubeMX图形化配置开始,手把手完成RTOS移植、任务创建、调试的全过程,让你在1小时内看到实际运行效果。

1. 硬件准备与开发环境搭建

1.1 所需材料清单

  • Blue Pill开发板(STM32F103C8T6核心板)
  • USB转TTL串口模块(如CH340G)
  • 2个LED灯及220Ω限流电阻(板载PC13已自带LED)
  • ST-Link V2调试器(可选,用于烧录和调试)
  • 杜邦线若干

提示:如果使用板载PC13 LED,其驱动能力较弱,建议外接LED到PA3等IO口获得更明显视觉效果。

1.2 软件工具安装

需要提前准备好以下开发环境:

# 开发工具链 - STM32CubeMX 6.9.0+ - Keil MDK-ARM 5.37+ 或 STM32CubeIDE 1.13+ - µC/OS-III源码包(可从Micrium官网获取评估版) # 驱动支持 - STM32F1xx HAL库 - ST-Link驱动(如使用ST-Link调试)

安装完成后,建议在CubeMX中检查芯片支持包是否包含STM32F1系列:

  1. 启动STM32CubeMX
  2. 点击"Help" → "Manage embedded software packages"
  3. 在"STM32F1"系列前打勾安装

2. CubeMX基础工程配置

2.1 时钟树设置

在CubeMX中新建工程选择STM32F103C8T6后,首先配置时钟源:

  1. RCC配置

    • High Speed Clock (HSE):Crystal/Ceramic Resonator
    • Low Speed Clock (LSE):Disable
  2. 时钟树参数

    • HSE频率:8MHz(匹配外部晶振)
    • PLL倍频:×9
    • 系统时钟:72MHz
    • APB1分频:/2(36MHz)
    • APB2分频:/1(72MHz)

2.2 GPIO与外设配置

我们需要配置两个LED引脚和一个串口用于调试输出:

功能引脚模式参数
LED1PC13GPIO_Output默认低电平
LED2PA3GPIO_Output默认低电平
USART1_TXPA9Alternate波特率115200
USART1_RXPA10Alternate无硬件流控

在CubeMX的"Pinout & Configuration"界面完成上述配置后,生成代码前还需:

  1. 在"Project Manager"选项卡设置工程名称和路径
  2. 选择Toolchain为MDK-ARM或STM32CubeIDE
  3. 勾选"Generate peripheral initialization as a pair of .c/.h files"

3. µC/OS-III源码移植

3.1 源码目录结构规划

将µC/OS-III源码整合到工程中时,建议采用以下目录结构:

Project/ ├── Core/ │ ├── Inc/ │ ├── Src/ │ └── OS/ # µC/OS配置文件 ├── Drivers/ ├── µC/ # µC/OS-III核心源码 │ ├── uC-CPU/ # CPU相关接口 │ ├── uC-LIB/ # 轻量级库 │ └── uCOS-III/ # 内核源码 └── MDK-ARM/ # Keil工程文件

具体操作步骤:

  1. 在工程根目录创建µC文件夹
  2. 将源码中的uC-CPUuC-LIBuCOS-III三个目录复制到µC
  3. Core/Src下新建OS文件夹存放配置文件

3.2 Keil工程配置

在Keil中需要添加源码路径和调整编译选项:

  1. 添加文件分组

    • uCOSIII-CPU:包含cpu_core.ccpu_a.asm
    • uCOSIII-LIB:包含lib_mem.clib_str.c
    • uCOSIII-Ports:包含os_cpu_c.cos_cpu_a.asm
    • uCOSIII-Source:内核源文件如os_task.cos_time.c
  2. 设置包含路径

    • ../µC/uC-CPU
    • ../µC/uC-CPU/ARM-Cortex-M3/RealView
    • ../µC/uC-LIB
    • ../µC/uCOS-III/Ports/ARM-Cortex-M3/Generic/RealView
    • ../µC/uCOS-III/Source
  3. 编译选项调整

    • 在"C/C++"选项卡的"Define"中添加:OS_CFG_APP_HOOKS_EN=0
    • 优化等级建议选择-O1平衡代码大小和性能

4. 多任务LED闪烁实现

4.1 系统初始化流程

完整的RTOS启动流程需要在main.c中实现:

#include "includes.h" // 任务栈和TCB定义 #define TASK_STACK_SIZE 128 OS_TCB AppTaskStartTCB; CPU_STK AppTaskStartStk[TASK_STACK_SIZE]; int main(void) { OS_ERR err; // 初始化µC/OS-III OSInit(&err); if (err != OS_ERR_NONE) { while(1); // 初始化失败处理 } // 创建起始任务 OSTaskCreate(&AppTaskStartTCB, "App Task Start", AppTaskStart, (void *)0, 1, // 最高优先级 &AppTaskStartStk[0], TASK_STACK_SIZE/10, TASK_STACK_SIZE, 0, 0, (void *)0, OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, &err); // 启动多任务调度 OSStart(&err); while(1); }

4.2 LED任务实现

在起始任务中创建两个LED闪烁任务:

// LED任务控制块和栈 OS_TCB Led1TaskTCB, Led2TaskTCB; CPU_STK Led1TaskStk[64], Led2TaskStk[64]; void AppTaskStart(void *p_arg) { OS_ERR err; (void)p_arg; // 硬件初始化 BSP_Init(); // 包含GPIO初始化 // 创建LED1任务(1Hz闪烁) OSTaskCreate(&Led1TaskTCB, "LED1 Task", Led1Task, (void *)0, 2, &Led1TaskStk[0], 64/10, 64, 0, 0, (void *)0, OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, &err); // 创建LED2任务(0.33Hz闪烁) OSTaskCreate(&Led2TaskTCB, "LED2 Task", Led2Task, (void *)0, 3, &Led2TaskStk[0], 64/10, 64, 0, 0, (void *)0, OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, &err); // 起始任务自我删除 OSTaskDel(NULL, &err); } void Led1Task(void *p_arg) { (void)p_arg; OS_ERR err; while(1) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); } } void Led2Task(void *p_arg) { (void)p_arg; OS_ERR err; while(1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_3); OSTimeDlyHMSM(0, 0, 1, 500, OS_OPT_TIME_HMSM_STRICT, &err); } }

4.3 调试技巧

当多任务系统运行不正常时,可以通过以下方法排查:

  1. 串口打印调试信息

    printf("Task %s running at %d ms\n", OSTaskNameGet(OSTCBCurPtr->Prio, &err), OSTimeGet(&err));
  2. 检查任务栈使用情况

    CPU_STK_SIZE used; OS_TaskStkChk(ledTaskPrio, &used, &free, &err); printf("LED Task Stack: %d/%d used\n", used, TASK_STACK_SIZE);
  3. 使用RTOS感知调试

    • 在Keil的Debug模式下,打开"View" → "System Viewer" → "RTX RTOS"
    • 可以实时查看任务状态、信号量、消息队列等信息

5. 进阶功能扩展

5.1 添加串口调试任务

在现有基础上增加一个串口输出任务:

OS_TCB UartTaskTCB; CPU_STK UartTaskStk[128]; void UartTask(void *p_arg) { OS_ERR err; (void)p_arg; while(1) { printf("[%d] System running\n", OSTimeGet(&err)); OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, &err); } }

需要在CubeMX中配置USART并启用重定向:

// 在usart.c中添加 #include <stdio.h> int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; }

5.2 使用信号量同步任务

实现LED闪烁与串口输出的同步:

  1. 定义信号量

    OS_SEM UartSem; OS_ERR err; OSSemCreate(&UartSem, "UART Sem", 1, &err);
  2. 修改任务

    void Led1Task(void *p_arg) { while(1) { OSSemPend(&UartSem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); OSSemPost(&UartSem, OS_OPT_POST_ALL, &err); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); } }

5.3 低功耗优化

当系统需要省电时,可以启用Tickless模式:

  1. 修改os_cfg.h

    #define OS_CFG_TICKLESS_EN 1
  2. 实现钩子函数

    void OSTimeTickHook(void) { if(OSIntNestingCtr == 0) { if(OSPrioHighRdy != OSPrioCur) { // 进入低功耗模式 __WFI(); } } }

6. 常见问题解决

6.1 编译错误处理

  • undefined symbol OS_CPU_SysTickHandler: 在stm32f1xx_it.c中注释掉原有的SysTick_Handler,使用µC/OS提供的版本

  • 堆栈溢出: 增大任务栈大小或在startup_stm32f103xb.s中调整Heap_Size

6.2 运行异常排查

  • LED不闪烁: 检查GPIO初始化是否正确,确认BSP_Init()被调用

  • 系统卡死: 检查是否所有任务都调用了延时函数,避免忙等待

6.3 性能优化建议

  • os_cfg.h中关闭不需要的功能(如统计任务、时间测量)
  • 根据实际需求调整OS_CFG_TICK_RATE_HZ(通常10-100Hz)
  • 使用OS_OPT_TIME_DLY替代OS_OPT_TIME_HMSM_STRICT减少开销

移植完成后,可以尝试扩展更多功能,如:

  • 添加按键检测任务
  • 实现PWM调光控制
  • 接入传感器数据采集
  • 建立TCP/IP网络连接
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 16:28:50

PyCharm 终端显示优化

PyCharm 终端美化方案针对PyCharm终端无行号及输出不清晰问题&#xff0c;推荐三种美化方案&#xff1a;1&#xff09;使用Rich库实现彩色打印&#xff1b;2&#xff09;用PrettyTable/Tabulate优化表格输出&#xff1b;3&#xff09;安装GrepConsole插件进行界面美化。特别推荐…

作者头像 李华
网站建设 2026/4/18 15:32:25

如何轻松备份微信聊天记录:WeChatMsg完整使用指南

如何轻松备份微信聊天记录&#xff1a;WeChatMsg完整使用指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg…

作者头像 李华