参考教程:【正点原子】手把手教你学UCOS-III实时操作系统_哔哩哔哩_bilibili
一、µCOS-III源码体系结构简介
1、使用的源码版本
组件 | 版本号 |
µC-OS3 | v3.08.01 |
µC-CPU | v1.32.01 |
µC-LIB | v1.39.01 |
2、µC-OS3文件内容
名称 | 描述 |
Cfg | 包含的是 µC/OS-III 配置文件的模板文件 |
Ports | 存放接口文件,是CPU与 µC/OS-III的连接桥梁 |
Source | 是µC/OS-III 的源码文件,也是 µC/OS-III 的核心文件 |
Template | 与动态 Tick 管理相关的文件 |
3、µC-CPU文件内容
包含了与 ARM Cortex-M内核的CPU相关的移植文件,如前导置零指令、大小端模式设置等。
4、µC-LIB文件内容
官方提供的ASCII字符操作、数学、内存管理、字符串操作的库。
二、µCOS-III源码移植
1、移植步骤概览
(1)将µCOS-III源码添加至基础工程,并添加头文件路径。
(2)修改stm32f10x.h文件。
(3)添加头文件cpu_cfg.h、lib_cfg.h、os_cfg.h、os_cfg_app.h。
(4)添加应用程序,验证移植是否成功。
2、示例
(1)拷贝一份STM32教程中使用OLED屏进行显示的工程文件夹,并更名为“UCOS-III移植工程”。
(2)在工程文件夹中新建文件夹,命名为“UCOS-III”,在µCOS-III文件夹中再新建4个文件夹,分别命名为“UCOS-config”、“UCOS-CPU”、“UCOS-LIB”、“UCOS-OS3”。
(3)在源码包中找到以下文件,将它们添加进UCOS-config文件夹中。
①路径uC-CPU-1.31.01/Cfg/Template下的cpu_cfg.h文件。
②路径uC-LIB-1.39.01/Cfg/Template 下的 lib_cfg.h文件。
③路径uC-OS3-3.08.01/Cfg/Template下的os_app_hooks.c、os_app_hooks.h、os_cfg.h、os_cfg_app.h文件。
(4)在源码包中找到以下文件,将它们添加进UCOS-CPU文件夹中。
①路径uC-CPU-1.32.01下的cpu_cache.h、cpu_def.h、cpu_core.h、cpu_core.c文件。
②路径uC-CPU-1.32.01/ARM-Cortex-M/ARMv7-M下的cpu_c.c文件。
③路径uC-CPU-1.32.01/ARM-Cortex-M/ARMv7-M/ARM下的cpu.h、cpu_a.asm文件。
(5)在源码包中找到以下文件,将它们添加进UCOS-LIB文件夹中。
①路径uC-LIB-1.39.01下的14个代码文件。
②路径uC-LIB-1.39.01/Ports/ARM-Cortex-M3/RealView下的lib_mem_a.asm文件。(Keil-MDK又称RealView)
(6)在源码包中找到以下文件,将它们添加进UCOS-OS3文件夹中。
①路径uC-OS3-3.08.01/Ports/ARM-Cortex-M/ARMv7-M下的os_cpu_c.c文件。
②路径uC-OS3-3.08.01/Ports/ARM-Cortex-M/ARMv7-M/ARM下的os_cpu.c、os_cp_a.asm文件。
③路径uC-OS3-3.08.01/Source下的20个代码文件。
(6)打开工程,在工程中添加上面拷贝的所有代码文件,并添加头文件路径,此处不再详细赘述。
(7)将cpu_cfg.h文件中的CPU_CFG_NVIC_PRIO_BITS条件编译打开。
#if 1
#define CPU_CFG_NVIC_PRIO_BITS 4u
#endif
(8)将os_cpu_c.c文件中包含头文件os.h的语句更改为使用相对路径。
/***** INCLUDE FILES*****/
#include "os.h"
(9)将lib_mem.c文件中的条件编译“#if (LIB_MEM_CFG_OPTIMIZE_ASM_EN != DEF_ENABLED)”修改为“#if (LIB_MEM_CFG_OPTIMIZE_ASM_EN != DEF_DISNABLED)”。
(10)在startup_stm32f10x_md.s文件中将PendSV_Handler修改为OS_CPU_PendSVHandler(一共3处),将SysTick_Handler修改为OS_CPU_SysTickHandler(一共3处)。
DCD OS_CPU_PendSVHandler
DCD OS_CPU_SysTickHandler
/********************************/
OS_CPU_PendSVHandler PROC
EXPORT OS_CPU_PendSVHandler [WEAK]
B .
ENDP
OS_CPU_SysTickHandler PROC
EXPORT OS_CPU_SysTickHandler [WEAK]
B .
ENDP
(11)注释stm32f10x_it.c文件中的两个空函数。
//void PendSV_Handler(void){}
//void SysTick_Handler(void){}
(12)点击编译,如无报错说明移植成功,后续例程基于此工程展开。
3、系统配置文件详解
(1)os_cfg.h配置文件主要用于配置µCOS-III内核的一些功能,比如消息队列、信号量、事件标志等。
宏定义 | 解释 |
OS_CFG_APP_HOOKS_EN | 此宏用于配置使能或禁用应用程序指定的钩子函数 当此宏配置为1时,使能应用程序指定的钩子函数,通过这个功能,用户可以很方便地在应用程序中扩展µC/OS-III的功能 |
OS_CFG_ARG_CHK_EN | 此宏用于配置使能或禁用µC/OS-III函数的参数检查功能 当此宏配置为1时,µC/OS-III会检查函数的传入参数是否合法,例如传递给函数的指针是否非空、传递的参数是否在允许的范围值内、参数对应的选项是否有效等。启用此功能将会增加µC/OS-III占用的Flash空间和RAM空间 |
OS_CFG_CALLED_FROM_ISR_CHK_EN | 此宏用于配置使能或禁用检查是否在中断中非法调用任务级函数 当此宏配置为1时,µC/OS-III会在执行函数前,判断该函数是否为中断中被非法调用 |
OS_CFG_DBG_EN | 此宏用于配置使能或禁用µC/OS-III的代码调试功能 当此宏配置为1时,会编译os_dbg.c文件中的内容,以帮助进行代码调试 |
OS_CFG_TICK_EN | 此宏用于配置使能或禁用µC/OS-III的内核时钟节拍 当此宏配置为1时,则使能µC/OSIII内核的时钟节拍功能 |
OS_CFG_DYN_TICK_EN | 此宏用于配置使能或禁用 µC/OS-III的动态时钟节拍管理功能 当此宏配置为1时,则使能µC/OS-III的动态时钟节拍管理功能 |
OS_CFG_INVALID_OS_CALLS_CHK_EN | 此宏用于配置使能或禁用检查是否在µC/OS-III系统开始运行前非法调用系统函数 当此宏配置为1时,则使能该检查功能 |
OS_CFG_OBJ_TYPE_CHK_EN | 此宏用于配置使能或禁用检查µC/OS-III对象操作函数传入的对象参数类型是否合法 当此宏配置为1时,则使能该检查功能 |
OS_CFG_OBJ_CREATED_CHK_EN | 此宏用于配置使能或禁用检查µC/OS-III对象是否被重复创建 当此宏配置为1时,则使能该检查功能 |
OS_CFG_TS_EN | 此宏用于配置使能或禁用时间戳功能 当此宏配置为1时,则使能时间戳功能。 |
OS_CFG_PRIO_MAX | 此宏用于定义任务优先级的最大数值 系统中最高任务优先级的数值为0,最低任务优先级的数值为 OS_CFG_PRIO_MAX-1 |
OS_CFG_SCHED_ROUND_ROBIN_EN | 此宏用于配置使能或禁用时间片调度功能 当此宏配置为1时,则使能时间片调度功能 |
OS_CFG_STK_SIZE_MIN | 此宏用于定义系统中允许的最小任务栈的大小,默认单位为字(由变量类型CPU_STK决定) |
OS_CFG_FLAG_EN | 此宏用于使能或禁用事件标志功能 当此宏配置为1时,则使能事件标志功能 |
OS_CFG_FLAG_DEL_EN | 此宏用于使能或禁用事件标志的删除功能 当此宏配置为1时,会编译函数OSFlagDel,它用于删除事件标志 |
OS_CFG_FLAG_MODE_CLR_EN | 此宏用于使能或禁用在等待或发布事件标志时,可以同时设置或清除事件标志功能 当此宏配置为1时,则使能该功能 |
OS_CFG_FLAG_PEND_ABORT_EN | 此宏用于使能或禁用终止等待事件标志功能 当此宏配置为1时,会编译函数OSFlagPendAbort,它用于终止等待事件标志 |
OS_CFG_MEM_EN | 此宏用于使能或禁用µC/OS-III的内存管理功能 当此宏配置为1时,则使能µC/OS-III的内存管理功能 |
OS_CFG_MUTEX_EN | 此宏用于使能或禁用互斥信号量功能 当此宏配置为1时,则使能互斥信号量功能 |
OS_CFG_MUTEX_DEL_EN | 此宏用于使能或禁用互斥信号量的删除功能 当此宏配置为1时,会编译函数 OSMutexDel,它用于删除互斥信号量 |
OS_CFG_MUTEX_PEND_ABORT_EN | 此宏用于使能或禁用终止等待互斥信号量功能 当此宏配置为1时,会编译函数OSMutexPendAbort,它用于终止等待互斥信号量 |
OS_CFG_Q_EN | 此宏用于使能或禁用消息队列功能 当此宏配置为1时,则使能消息队列功能 |
OS_CFG_Q_DEL_EN | 此宏用于使能或禁用消息队列删除功能 当此宏配置为1时,会编译函数 OSQDel,它用于删除消息队列 |
OS_CFG_Q_FLUSH_EN | 此宏用于使能或禁用清空消息队列功能 当此宏配置为1时,会编译函数 OSQFlush,它用于清空消息队列中的消息 |
OS_CFG_Q_PEND_ABORT_EN | 此宏用于使能或禁用终止等待消息队列功能 当此宏配置为1时,会编译函数OSQPendAbort,用于终止等待消息队列 |
OS_CFG_SEM_EN | 此宏用于使能或禁用信号量功能 当此宏配置为1时,则使能信号量功能 |
OS_CFG_SEM_DEL_EN | 此宏用于使能或禁用信号量删除功能 当此宏配置为1时,会编译函数OSSemDel,它用于删除信号量 |
OS_CFG_SEM_PEND_ABORT_EN | 此宏用于使能或禁用终止等待信号量功能 当此宏配置为1时,会编译函数OSSemPendAbort,它用于终止等待信号量 |
OS_CFG_SEM_SET_EN | 此宏用于使能或禁用强制设置信号量值功能 当此宏配置为1时,会编译函数OSSemSet,它用于强制设置信号量的值 |
OS_CFG_STAT_TASK_EN | 此宏用于使能或禁用µC/OS-III的任务统计功能 当此宏配置为1时,则使能µC/OS-III的任务统计功能 |
OS_CFG_STAT_TASK_STK_CHK_EN | 此宏用于使能或禁用在进行任务统计时,检查任务栈的情况 当此宏配置为1时,则使能该功能 |
OS_CFG_TASK_CHANGE_PRIO_EN | 此宏用于使能或禁用更改任务优先级的功能 当此宏配置为1时,会编译函数OSTaskChangePrio,它用于更改任务的任务优先级 |
OS_CFG_TASK_DEL_EN | 此宏用于使能或禁用任务删除功能 当此宏配置为1时,会编译函数 OSTaskDel,用于删除任务 |
OS_CFG_TASK_IDLE_EN | 此宏用于使能或禁用空闲任务功能 当此宏配置为1时,则使能空闲任务功能 |
OS_CFG_TASK_PROFILE_EN | 此宏用于使能或禁用任务分析功能 当此宏配置为1时,则使能任务分析功能 |
OS_CFG_TASK_Q_EN | 此宏用于使能或禁用任务内嵌的消息队列功能 当此宏配置为1时,则使能任务内嵌的消息队列功能,此时会编译OSTaskQXXXX系列函数,它们用于操作任务内嵌的消息队列 |
OS_CFG_TASK_Q_PEND_ABORT_EN | 此宏用于使能或禁用终止等待任务内嵌的消息队列功能 当此宏配置为1时,会编译函数OSTaskQPendAbort,用于终止等待任务内嵌的消息队列 |
OS_CFG_TASK_REG_TBL_SIZE | 此宏用于定义特定于任务的寄存器数量,在任务控制块中有一个拥有OS_CFG_TASK_REG_TBL_SIZE 个元素的数组,应用程序可以在这个数组中保存一些特定于任务的值,例如错误信息、统计信息等 |
OS_CFG_TASK_STK_REDZONE_EN | 此宏用于使能或禁用RedZone栈检查功能 当此宏配置为1时,则使能RedZone栈检查功能,该功能用于检测栈越界问题 |
OS_CFG_TASK_STK_REDZONE_DEPTH | 此宏用于定义任务栈RedZone深度,默认单位为字(由变量类型CPU_STK决定) |
OS_CFG_TASK_SEM_PEND_ABORT_EN | 此宏用于使能或禁用终止等待任务内嵌信号量功能 此宏配置为1时,会编译函数OSTaskSemPendAbort,它用于终止等待任务内嵌信号量 |
OS_CFG_TASK_SUSPEND_EN | 此宏用于使能或禁用任务挂起和恢复功能 此宏配置为1时,会编译函数OSTaskSuspend和函数OSTaskResume,它们分别用于挂起和恢复任务运行 |
OS_CFG_TLS_TBL_SIZE | 此宏用于定义本次存储寄存器的数量 |
OS_CFG_TIME_DLY_HMSM_EN | 此宏用于使能或禁用毫秒级任务延时功能。此宏配置为1时,会编译函数OSTimeDlyHMSM,它用于进行毫秒级延时 |
OS_CFG_TIME_DLY_RESUME_EN | 此宏用于使能或禁用终止任务延时功能 此宏配置为1时,会编译函数OSTimeDlyResume,它用于终止任务延时 |
OS_CFG_TMR_EN | 此宏用于使能或禁用软件定时器功能 当此宏配置为1时,则使能软件定时器功能 |
OS_CFG_TMR_DEL_EN | 此宏用于使能或禁用删除软件定时器功能 当此宏配置为1时,会编译函数OSTmrDel,它用于删除软件定时器 |
OS_CFG_TRACE_EN | 此宏用于使能或禁用跟踪记录功能 当此宏配置为 1 时,则使能跟踪记录功能(此功能需配合第三方软件使用,如“SEGGER SystemView for uC/OS-III”、“Percepio Tracealyzer for uC/OSIII”等) |
OS_CFG_TRACE_API_ENTER_EN | 此宏用于使能或禁用记录进入跟踪记录的API函数的调用 当此宏配置为1时,则使能该功能 |
OS_CFG_TRACE_API_EXIT_EN | 此宏用于使能或禁用记录退出跟踪记录的API函数的调用 当此宏配置为1时,则使能该功能 |
(2)os_cfg_app.h配置文件主要用于系统的应用配置,如空闲任务、任务统计任务、软件定时器任务的任务参数配置等。
宏定义 | 解释 |
OS_CFG_ISR_STK_SIZE | 此宏用于定义用于异常的Main Stack栈的大小,默认单位为字(由变量类型CPU_STK决定) |
OS_CFG_MSG_POOL_SIZE | 此宏用于定义消息队列的消息池大小 |
OS_CFG_TASK_STK_LIMIT_PCT_EMPTY | 此宏用于定义空闲任务、统计任务、软件定时器任务任务栈的剩余最小值,当任务栈剩余量小于这个值,说明任务栈溢出 单位:百分比 |
OS_CFG_IDLE_TASK_STK_SIZE | 此宏用于定义空闲任务任务栈的大小,默认单位为字(由变量类型CPU_STK决定) |
OS_CFG_STAT_TASK_PRIO | 此宏用于定义任务统计任务的任务优先级 |
OS_CFG_STAT_TASK_RATE_HZ | 此宏用于定义任务统计任务的运行频率 单位:赫兹 |
OS_CFG_STAT_TASK_STK_SIZE | 此宏用于定义任务统计任务栈的大小,默认单位为字(由变量类型CPU_STK决定) |
OS_CFG_TICK_RATE_HZ | 此宏用于定义系统时钟节拍的频率 单位:赫兹 |
OS_CFG_TMR_TASK_PRIO | 此宏用于定义软件定时器任务的任务优先级 |
OS_CFG_TMR_TASK_STK_SIZE | 此宏用于定义软件定时器任务的任务栈大小,默认单位为字(由变量类型CPU_STK决定) |
OS_CFG_TMR_TASK_RATE_HZ | 此宏用于定义软件定时器任务的运行频率 单位:赫兹 |
(3)cpu_cfg.h配置文件主要用于配置CPU相关的一些宏定义,如时间戳、前导置零指令相关等内容。
宏定义 | 解释 |
CPU_CFG_NAME_EN | 此宏用于使能或禁止CPU主机名功能 当此宏配置为DEF_ENABLE时,则使能CPU主机名功能 |
CPU_CFG_NAME_SIZE | 此宏用于定义CPU主机名的最大长度 |
CPU_CFG_TS_32_EN | 此宏用于使能或禁用使用32位硬件定时器作为时间戳功能的时基定时器 此宏配置为DEF_ENABLE时,使能使用32位硬件定时器作为时间戳功能的时基定时器 |
CPU_CFG_TS_64_EN | 此宏用于使能或禁用使用64位硬件定时器作为时间戳功能的时基定时器 此宏配置为DEF_ENABLE时,使能使用64位硬件定时器作为时间戳功能的时基定时器 |
CPU_CFG_TS_TMR_SIZE | 此宏用于定义时间戳的实际使用位数,可定义为CPU_WORD_SIZE_08(实际使用8位时间戳)、CPU_WORD_SIZE_16(实际使用16位时间戳)、CPU_WORD_SIZE_32(实际使用32位时间戳)、CPU_WORD_SIZE_64(实际使用64位时间戳) |
CPU_CFG_INT_DIS_MEAS_EN | 此宏用于使能或禁用使用时间戳测量进入临界区和退出临界区期间的耗时时间 此宏配置为DEF_ENABLE时,使能使用时间戳测量进入临界区和退出临界区期间的耗时时间 |
CPU_CFG_INT_DIS_MEAS_OVRHD_NBR | 此宏用于定义执行多少次临界区进入和退出函数,以计算出平均的进入临界区和退出临界区期间的额外耗时时间 |
CPU_CFG_LEAD_ZEROS_ASM_PRESENT | 此宏用于指示CPU具有硬件计算前导零的指令,如CLZ指令 在µC/OS-III中,函数CPU_CntLeadZeros用于计算前导零,如果定义了此宏,则函数CPU_CntLeadZeros定义在文件cpu_a.asm 中使用CLZ指令实现;反之,则函数CPU_CntLeadZeros定义在文件cpu_core.c文件中使用软件算法实现 |
CPU_CFG_TRAIL_ZEROS_ASM_PRESENT | 此宏用于指示CPU具有硬件计算后导零的指令,如RBIT指令和CLZ指令配合使用 在µC/OS-III中,函数CPU_CntTrailZeros用于计算后导零,如果定义了此宏,则函数CPU_CntTrailZeros定义在cpu_a.asm文件中使用RBIT指令配置CLZ指令实现;反之,则函数CPU_CntTrailZeros定义在cpu_core.c文件中使用软件算法实现 |
CPU_CFG_ENDIAN_TYPE | 此宏用于指示CPU的端格式 当此宏配置为CPU_ENDIAN_TYPE_BIG时,表明CPU为大端格式,当此宏配置为CPU_ENDIAN_TYPE_LITTLE时,表明CPU为小端格式 |
CPU_CFG_CACHE_MGMT_EN | 此宏用于使能或禁用µC/OS-III的Cache管理功能 当此宏配置为DEF_ENABLE时,则使能µC/OS-III的Cache管理功能 |
CPU_CFG_KA_IPL_BOUNDARY | 此宏用于定义受µC/OS-III管理的最高中断优先等级,中断优先级低于此宏定义值(中断优先级数值大于此宏定义值)的中断受µC/OS-III管理 |
CPU_CFG_NVIC_PRIO_BITS | 此宏用于定义中断优先级配置寄存器的实际使用位数 |
(3)lib_cfg.h配置文件主要用于配置µC/LIB组件,如使能内存库中优化的内存相关操作函数。
宏定义 | 解释 |
LIB_MEM_CFG_ARG_CHK_EXT_EN | 此宏用于使能或禁用检查内存库(文件lib_mem.c)中函数的传入参数是否合法 当此宏配置为DEF_ENABLE时,则使能检查内存库中函数的传入参数是否合法 |
LIB_MEM_CFG_OPTIMIZE_ASM_EN | 此宏用于使能或禁用使用内存库中优化的内存相关操作函数 当此宏配置为DEF_ENABLE时,则使能使用内存库中优化的内存相关操作函数,例如使用内存库中的函数Mem_Copy代替标准C库中的函数memcpy |
LIB_MEM_CFG_DBG_INFO_EN | 此宏用于使能或禁用为申请的每一个内存块分配一个用于跟踪调试的名称 当此宏配置为DEF_ENABLE时,则使能位申请的每一个内存块分配一个用于跟踪调试的名称 |
LIB_MEM_CFG_HEAP_SIZE | 此宏用于定义用于内存库管理的内存堆的大小 单位:字节 |
LIB_MEM_CFG_HEAP_PADDING_ALIGN | 此宏用于定义使用函数Mem_HeapAlloc申请内存时,所申请的内存大小需按多少字节向上对齐 |
LIB_MEM_CFG_HEAP_BASE_ADDR | 此宏用于定义用于内存库管理的内存堆的起始地址 当没有定义这个宏时,用于内存库管理的内存堆将由编译器自动分配;当定义了这个宏后,用于内存库管理的内存堆将被分配到该宏定义的地址上 |
LIB_STR_CFG_FP_EN | 此宏用于使能或禁用浮点数转字符串功能 当此宏配置为DEF_ENABLE时,将编译函数Str_FmtNbr_32,它用于浮点数转字符串 |
LIB_STR_CFG_FP_MAX_NBR_DIG_SIG | 此宏用于配置浮点数转字符串函数Str_FmtNbr_32的转换精度 |