UCOS-III 文件结构与 STM32 移植
1. 整体组成
μC/OS-III 常见工程通常由 4 部分组成:
- uC/OS-III:内核源码,任务调度、时钟节拍、同步通信等核心功能都在这里
- uC/CPU:CPU 架构相关移植层,和 Cortex-M 内核绑定最紧
- uC/LIB:Micrium 提供的基础库,字符串、内存、ASCII、数学等通用功能
- 配置文件:决定内核启用哪些特性,以及和 STM32 平台的适配参数
2. uC/OS-III 目录作用
2.1 Cfg:功能裁剪
内核配置模板目录,主要放 OS 配置头文件模板。
移植到 STM32 时,通常会从这里整理出自己的配置文件,例如:
os_cfg.hos_cfg_app.h
作用:
- 配置任务数、空闲任务、统计任务
- 配置信号量、消息队列、事件标志组等功能开关
- 配置软件定时器、中断延迟发布等特性
2.2 Ports
接口/移植接口目录,用来把 CPU 与 μC/OS-III 内核连接起来。
这里面一般包含不同编译器、不同架构下的端口文件。
作用:
- 提供临界区开关
- 提供任务切换相关接口
- 处理中断级与任务级切换衔接
- 适配不同工具链(如 MDK、IAR、GCC)
2.3 Source
μC/OS-III 的核心源码目录,是最重要的一部分。
主要文件通常包括:
os_core.c:内核核心初始化与基础管理os_task.c:任务管理os_tick.c:系统时钟节拍处理os_time.c:延时与时间管理os_sem.c:信号量os_mutex.c:互斥量os_q.c:消息队列os_flag.c:事件标志组os_mem.c:内存分区管理os_stat.c:统计任务os_idle.c:空闲任务os_dbg.c:调试支持os_cfg_app.c:部分应用配置相关实现
这部分就是 RTOS 本体,任务调度和大多数 API 都在这里实现。
2.4 Template
模板目录,通常放示例配置或和 动态 Tick / 定制配置 相关的模板文件。
实际项目里不一定直接参与编译,更多用于参考。
3. uC/CPU 目录作用
uC/CPU 是 CPU 抽象层,专门处理与处理器架构相关的内容。
在 STM32 上,重点关注 ARM Cortex-M 对应目录。
常见作用:
- 定义 CPU 数据类型,如
CPU_INT08U、CPU_STK - 实现临界区控制
- 提供位操作、地址对齐、大小端判断等接口
- 提供任务栈类型、栈增长方向等底层定义
在 STM32 上通常会用到:
ARM-Cortex-M- 某个具体编译器目录(如
ARMCMx/MDK、IAR、GCC)
4. uC/LIB 目录作用
uC/LIB 是 Micrium 的基础库,不属于调度核心,但很多地方会依赖它。
常见文件作用:
lib_ascii.*:ASCII 字符处理lib_str.*:字符串处理lib_mem.*:内存操作lib_math.*:数学相关lib_def.h:基础宏和通用定义
配置目录 Cfg
通常会整理出:
lib_cfg.h
作用:
- 配置是否启用某些库特性
- 调整内存相关函数的实现方式
5. STM32 移植时最关键的文件
在 STM32 + μC/OS-III 工程里,最常改的通常是下面几个文件:
os_cfg.h
内核功能开关配置文件。
决定是否启用:
是否使能事件标志组:
OS_CFG_FLAG_EN是否使能信号量:
OS_CFG_SEM_EN是否使能互斥量:
OS_CFG_MUTEX_EN是否使能消息队列:
OS_CFG_Q_EN是否使能软件定时器:
OS_CFG_TMR_EN是否开启统计任务:
OS_CFG_STAT_TASK_EN最大优先级数:
OS_CFG_PRIO_MAX是否开启时间戳:
OS_CFG_TS_EN
os_cfg_app.h
应用级配置文件。
主要设置:
- 任务控制块数量
- 定时器数量
- 空闲任务/统计任务参数
- 任务栈检查、栈清零等选项
cpu_cfg.h
CPU 配置文件。
主要配置:
- 临界区实现方式
- 栈增长方向
- 时间戳使能
- 优先级位数等
对于 Cortex-M,常见重点是:高四位有效 ,也就是最大优先级数 = 16
#define CPU_CFG_NVIC_PRIO_BITS 4u这个值必须与 STM32 的 NVIC 优先级位数一致。 大多数 STM32F1/F4/F7/H7 常用 4 位,但要以芯片手册和 HAL/CMSIS 配置为准。
lib_cfg.h
uC/LIB 配置文件。 一般用于:
- 配置内存函数
- 裁剪基础库特性
6. STM32 上的移植核心步骤
6.1 准备源码
把以下内容加入工程:
uC/OS-III/SourceuC/CPUuC/LIB- 对应编译器下的
Ports - 自己整理出的配置头文件
#① 告诉编译器要编译哪些 RTOS 文件# uC/OS-III stack sourcesset(UCOSIII_SOURCES # uC/CPU (ARMv7-M, GNU) UCOSIII/uC-CPU/cpu_core.c #CPU核心函数 UCOSIII/uC-CPU/ARM-Cortex-M/ARMv7-M/cpu_c.c #Cortex-M CPU实现 UCOSIII/uC-CPU/ARM-Cortex-M/ARMv7-M/GNU/cpu_a.s #Cortex-M 汇编实现
# uC/LIB UCOSIII/uC-LIB/lib_ascii.c #ASCII字符处理 UCOSIII/uC-LIB/lib_math.c #数学函数 UCOSIII/uC-LIB/lib_mem.c #内存操作 UCOSIII/uC-LIB/lib_str.c #字符串操作
# uC/OS-III kernel UCOSIII/uC-OS3/Source/os_core.c # 内核核心初始化、调度控制 UCOSIII/uC-OS3/Source/os_dbg.c # 调试信息、内核对象调试支持 UCOSIII/uC-OS3/Source/os_flag.c # 事件标志组 (Event Flags) UCOSIII/uC-OS3/Source/os_mem.c # 内存分区管理 UCOSIII/uC-OS3/Source/os_msg.c # 内核消息机制(任务通信基础) UCOSIII/uC-OS3/Source/os_mutex.c # 互斥量 (Mutex) UCOSIII/uC-OS3/Source/os_prio.c # 优先级管理 UCOSIII/uC-OS3/Source/os_q.c # 消息队列 (Message Queue) UCOSIII/uC-OS3/Source/os_sem.c # 信号量 (Semaphore) UCOSIII/uC-OS3/Source/os_stat.c # 统计任务(CPU 使用率统计) UCOSIII/uC-OS3/Source/os_task.c # 任务管理(创建、删除、切换) UCOSIII/uC-OS3/Source/os_tick.c # 系统 Tick 处理 UCOSIII/uC-OS3/Source/os_time.c # 时间管理、任务延时 UCOSIII/uC-OS3/Source/os_tmr.c # 软件定时器 UCOSIII/uC-OS3/Source/os_var.c # 内核全局变量 UCOSIII/uC-OS3/Source/os_cfg_app.c # 应用级 OS 配置
# uC/OS-III ARMv7-M GNU port UCOSIII/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_c.c #CPU接口实现 UCOSIII/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/GNU/os_cpu_a.S #任务切换汇编)#② 告诉编译器头文件在哪# Add include pathstarget_include_directories(${CMAKE_PROJECT_NAME} PRIVATE # Micrium include paths UCOSIII/uC-CPU UCOSIII/uC-CPU/ARM-Cortex-M/ARMv7-M/GNU UCOSIII/uC-LIB UCOSIII/uC-OS3/Source UCOSIII/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/GNU)6.2 选择正确的 Cortex-M 端口
STM32 属于 ARM Cortex-M 系列,所以要选择对应端口文件。 通常要包含:
- 与 Cortex-M 相关的
cpu_a.asm/os_cpu_a.asm os_cpu_c.cos_cpu.h
这些文件负责:
- PendSV 任务切换
- SysTick 时钟节拍对接
- OS 启动首任务
- 中断上下文切换
6.3 配置 SysTick
μC/OS-III 需要周期性时钟节拍驱动调度器,一般使用 SysTick。
典型做法:
- 让 SysTick 周期性中断,例如 1ms
- 在 SysTick 中断服务函数里调用 μC/OS-III 的 Tick 接口
- 如果使用 HAL,要注意 HAL 自己也可能占用 SysTick
6.4 配置 PendSV 和中断优先级
Cortex-M 中,μC/OS-III 的任务切换通常依赖 PendSV。 因此要正确设置:
PendSV优先级:最低SysTick优先级:通常也设为较低- 所有调用 OS API 的中断优先级:必须满足内核要求
/*“Come form os_cpu_a.S”*/.equ NVIC_PENDSV_PRI, 0xFF/*这个的含义是最低优先级,数字越大优先级越低。*//*后续还会介绍*/如果中断优先级设置不当,常见问题有:
- 任务无法切换
- 进入中断后死机
- OS API 在中断中调用异常
- 延时不准或调度失效
6.5 初始化流程
STM32 上常见初始化顺序如下:
int main(void){ BSP_Init(); // 时钟、串口、GPIO 等硬件初始化
OSInit(&err); // 初始化 μC/OS-III
OSTaskCreate(...); // 创建启动任务 OSTaskCreate(...); // 创建其他任务
OSStart(&err); // 启动多任务调度 while (1) { }}UCOSIII 专栏
第 2 篇 / 共 4 篇