(学习日记)2024.05.11:UCOSIII第六十五节:常用的控制宏介绍 第一部分
之前的章节都是针对某个或某些知识点进行的专项讲解,重点在功能和代码解释。
(图片来源网络,侵删)
回到最初开始学μC/OS-III系统时,当时就定下了一个目标,不仅要读懂,还要读透,改造成更适合中国宝宝体质的使用方式。在学完野火的教程后,经过几经思考,最后决定自己锦上添花,再续上几章。
这几章想达成目的如下:
- 能够快速的上手
- 能够控制系统的功能
- 明白移植的过程
- 能够根据需要的功能来裁剪源码
从第六十一章开始的章节都是熟读源码后,根据笔者的整理方法,按照某种逻辑从系统源码中抽出来的专项解释。
笔者整理方法如下
- 各文件夹功能介绍(每个文件夹放什么文件,哪些是移植的,哪些不需要改,哪些需要修改)
- 各文件功能概览(每个文件都明白有哪些东西,是系统的哪一部分)
- 各文件函数概览(每个文件的有什么函数,函数的作用是什么,形参是什么)
- 移植的本质与移植的顺序(哪些文件需要了解,哪些文件是移植的时候需要更换的)
- 添加与裁剪源码(添功能与删功能怎么上手)
- 常用的结构体列表
- 常用宏介绍(如何用宏来控制整个系统,启用或关闭某个功能)
- main函数常用的结构顺序
- 创建任务的流程
- 任务在几种队列的变化
每个整理方法会用一章或多章的篇幅来解释。
点击此处进入μC/OS-iii章节总目录
2024.05.11:UCOSIII第六十五节:常用的控制宏介绍 第一部分
- 六十九、UCOSIII:常用的控制宏介绍 第一部分
- app_cfg.h文件
- 任务堆栈大小
- 任务优先级大小
- 最大信号量数目
- 消息队列的最大消息数量
- 每个消息的最大大小(字节)
- 代码实例
- 应用实例
- cpu_cfg.h文件
- CPU 名称配置
- CPU 时间戳配置
- CPU 中断禁用时间测量配置
- CPU计数前导零配置
- 代码实例
- 应用实例
六十九、UCOSIII:常用的控制宏介绍 第一部分
app_cfg.h文件
在本文件中定义的宏如下:
任务堆栈大小
任务优先级大小
最大信号量数目
消息队列的最大消息数量
每个消息的最大大小(字节)
代码实例
本文件代码实例如下:
#ifndef APP_CFG_H #define APP_CFG_H /****************************** 任务配置 *************************************/ #define APP_TASK_START_PRIO 3 // 应用程序启动任务的优先级 #define APP_TASK_START_STK_SIZE 256 // 应用程序启动任务的堆栈大小 #define TASK1_PRIO 6 // 任务1的优先级 #define TASK1_STK_SIZE 128 // 任务1的堆栈大小 #define TASK2_PRIO 7 // 任务2的优先级 #define TASK2_STK_SIZE 128 // 任务2的堆栈大小 /****************************** 信号量配置 ***********************************/ #define MAX_SEM 5 // 最大信号量数目 /****************************** 消息队列配置 **********************************/ #define MAX_QUEUE_ENTRIES 10 // 消息队列的最大消息数量 #define MAX_MSG_SIZE 32 // 每个消息的最大大小(字节) #endif /* APP_CFG_H */
应用实例
使用app_cfg.h中定义的配置参数在应用程序中创建任务、初始化信号量和消息队列:
#include "os.h" #include "app_cfg.h" // 任务函数原型 void Task1(void *p_arg); void Task2(void *p_arg); // 信号量 OS_SEM sem1; // 消息队列 OS_Q queue1; int main(void) { OS_ERR err; // 初始化操作系统 OSInit(&err); // 创建任务 OSTaskCreate((OS_TCB *)&Task1TCB, (CPU_CHAR *)"Task 1", Task1, 0, TASK1_PRIO, &Task1Stk[0], TASK1_STK_SIZE / 10, TASK1_STK_SIZE, 0, 0, 0, (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), &err); OSTaskCreate((OS_TCB *)&Task2TCB, (CPU_CHAR *)"Task 2", Task2, 0, TASK2_PRIO, &Task2Stk[0], TASK2_STK_SIZE / 10, TASK2_STK_SIZE, 0, 0, 0, (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), &err); // 创建信号量 OSSemCreate(&sem1, (CPU_CHAR *)"Semaphore 1", 0, &err); // 创建消息队列 OSQCreate(&queue1, (CPU_CHAR *)"Queue 1", MAX_QUEUE_ENTRIES, &err); // 启动操作系统 OSStart(&err); return 0; } // 任务函数 void Task1(void *p_arg) { OS_ERR err; while (1) { // 任务1的代码 // 例如:等待信号量 OSSemPend(&sem1, 0, OS_OPT_PEND_BLOCKING, NULL, &err); // 执行其他操作 } } void Task2(void *p_arg) { OS_ERR err; while (1) { // 任务2的代码 // 例如:向消息队列发送消息 CPU_INT08U msg = 10; OSQPost(&queue1, &msg, sizeof(msg), OS_OPT_POST_FIFO, &err); // 执行其他操作 } }cpu_cfg.h文件
cpu_cfg.h文件通常包含一些针对特定处理器和编译器的配置选项和宏定义。
这些配置选项可以根据你的硬件平台和应用程序需求进行自定义。一般情况下,cpu_cfg.h 文件可能包含以下内容:
CPU 名称配置
CPU 时间戳配置
CPU 中断禁用时间测量配置
CPU计数前导零配置
代码实例
/* ********************************************************************************************************* * CPU 名称配置 * * 注意事项:(1) 配置 CPU_CFG_NAME_EN 以启用/禁用 CPU 主机名特性: * * (a) CPU 主机名存储 * (b) CPU 主机名 API 函数 * * (2) 使用所需的 ASCII 字符串大小配置 CPU_CFG_NAME_SIZE,包括终止的 NULL 字符。 * * 参见 'cpu_core.h 全局变量 注意事项 #1'。 ********************************************************************************************************* */ //CPU 名称配置: //CPU_CFG_NAME_EN: 用于启用或禁用 CPU 主机名特性。 //CPU_CFG_NAME_SIZE: 配置 CPU 主机名的 ASCII 字符串大小,包括终止的 NULL 字符。 /* 配置 CPU 主机名特性(参见注意事项 #1): */ #define CPU_CFG_NAME_EN DEF_ENABLED /* DEF_DISABLED CPU 主机名已禁用 */ /* DEF_ENABLED CPU 主机名已启用 */ /* 配置 CPU 主机名 ASCII 字符串大小 ... */ #define CPU_CFG_NAME_SIZE 16u /* ...(参见注意事项 #2)。 */ /*$PAGE*/ /* ********************************************************************************************************* * CPU 时间戳配置 * * 注意事项:(1) 配置 CPU_CFG_TS_xx_EN 以启用/禁用 CPU 时间戳功能: * * (a) CPU_CFG_TS_32_EN 启用/禁用 32 位 CPU 时间戳功能 * (b) CPU_CFG_TS_64_EN 启用/禁用 64 位 CPU 时间戳功能 * * (2) (a) 使用 CPU_CFG_TS_TMR_SIZE 配置 CPU 时间戳定时器的字大小: * * CPU_WORD_SIZE_08 8 位字大小 * CPU_WORD_SIZE_16 16 位字大小 * CPU_WORD_SIZE_32 32 位字大小 * CPU_WORD_SIZE_64 64 位字大小 * * (b) 如果 CPU 时间戳定时器的大小不是 8 位八位组的二进制倍数(例如 20 位或偶数 24 位), * 则应配置为下一个较低的二进制倍数的八位组大小(例如 16 位)。 * 然而,CPU 时间戳定时器的最小支持字大小为 8 位。 * * 参见 'cpu_core.h 函数原型 CPU_TS_TmrRd() 注意事项 #2a'。 ********************************************************************************************************* */ //CPU 时间戳配置: //CPU_CFG_TS_32_EN 和 CPU_CFG_TS_64_EN: 启用或禁用 32 位和 64 位 CPU 时间戳功能。 //CPU_CFG_TS_TMR_SIZE: 配置 CPU 时间戳定时器的字大小。可以是 8 位、16 位、32 位或 64 位。 /* 配置 CPU 时间戳功能(参见注意事项 #1): */ #define CPU_CFG_TS_32_EN DEF_ENABLED // Modified by fire (原是 DEF_DISABLED) #define CPU_CFG_TS_64_EN DEF_DISABLED /* DEF_DISABLED CPU 时间戳已禁用 */ /* DEF_ENABLED CPU 时间戳已启用 */ /* 配置 CPU 时间戳定时器字大小 ... */ /* ...(参见注意事项 #2): */ #define CPU_CFG_TS_TMR_SIZE CPU_WORD_SIZE_32 /* ********************************************************************************************************* * CPU 中断禁用时间测量配置 * * 注意事项:(1) (a) 配置 CPU_CFG_INT_DIS_MEAS_EN 以启用/禁用测量 CPU 中断禁用时间: * * (a) 已启用, 如果在 'cpu_cfg.h' 中 CPU_CFG_INT_DIS_MEAS_EN #define'd * * (b) 已禁用, 如果在 'cpu_cfg.h' 中 CPU_CFG_INT_DIS_MEAS_EN 未 #define'd * * 参见 'cpu_core.h 函数原型 注意事项 #1' * & 'cpu_core.h CPU 包含文件 注意事项 #3'。 * * (b) 使用 CPU_CFG_INT_DIS_MEAS_OVRHD_NBR 配置要测量和平均中断禁用时间测量开销的次数。 * * 建议仅进行一次测量,即使对于启用指令高速缓存的 CPU,临界区也不会在指令缓存循环中调用。 * 因此,对于大多数非缓存中断禁用时间测量,单次非缓存/非平均时间测量是更现实的开销。 * * 参见 'cpu_core.c CPU_IntDisMeasInit() 注意事项 #3a'。 ********************************************************************************************************* */ //CPU 中断禁用时间测量配置: //CPU_CFG_INT_DIS_MEAS_EN: 启用或禁用测量 CPU 中断禁用时间的功能。 //CPU_CFG_INT_DIS_MEAS_OVRHD_NBR: 配置测量中断禁用时间开销的次数。建议仅测量一次开销。 #if 1 // Modified by fire (原是 0) /* 配置 CPU 中断禁用时间 ... */ #define CPU_CFG_INT_DIS_MEAS_EN /* ... 测量功能(参见注意事项 #1a)。 */ #endif /* 配置中断禁用开销测量的次数 ... */ #define CPU_CFG_INT_DIS_MEAS_OVRHD_NBR 1u /* ... 时间测量(参见注意事项 #1b)。 */ /*$PAGE*/ /* ********************************************************************************************************* * CPU计数前导零配置 * * 注意事项:(1) 配置 CPU_CFG_LEAD_ZEROS_ASM_PRESENT 以在以下位置原型/定义计数前导零位数功能: * * (a) 'cpu.h'/'cpu_a.asm', 如果在 'cpu.h'/'cpu_cfg.h' 中 CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd,则启用汇编版本的功能 * * (b) 'cpu_core.h'/'cpu_core.c',如果在 'cpu.h'/'cpu_cfg.h' 中 CPU_CFG_LEAD_ZEROS_ASM_PRESENT 未 #define'd,则启用 C 源码版本的功能 ********************************************************************************************************* */ //CPU 前导零计数配置: //CPU_CFG_LEAD_ZEROS_ASM_PRESENT: 启用汇编版本或 C 源码版本的计数前导零位数函数。 #if 1 /* 配置 CPU 计数前导零位数 ... */ #define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... 汇编版本(参见注意事项 #1)。 */ #endif应用实例
好的,下面是一个简单的示例,展示了如何在代码中使用上述 cpu_cfg.h 中定义的一些宏:
#include #include #define TASK_PRIO_HIGH 10 #define TASK_PRIO_MEDIUM 15 #define TASK_PRIO_LOW 20 #define TASK_STACK_SIZE 256 // 定义任务堆栈 static CPU_STK task_stk_high[TASK_STACK_SIZE]; static CPU_STK task_stk_medium[TASK_STACK_SIZE]; static CPU_STK task_stk_low[TASK_STACK_SIZE]; // 任务函数 void TaskHighPrio(void *p_arg); void TaskMediumPrio(void *p_arg); void TaskLowPrio(void *p_arg); int main(void) { OS_ERR os_err; // 初始化uC/OS-III内核 OSInit(&os_err); // 创建任务 OSTaskCreate(&TaskHighPrio, (void *)0, &task_stk_high[TASK_STACK_SIZE - 1], TASK_PRIO_HIGH); OSTaskCreate(&TaskMediumPrio, (void *)0, &task_stk_medium[TASK_STACK_SIZE - 1], TASK_PRIO_MEDIUM); OSTaskCreate(&TaskLowPrio, (void *)0, &task_stk_low[TASK_STACK_SIZE - 1], TASK_PRIO_LOW); // 启动uC/OS-III内核 OSStart(&os_err); return 0; } // 高优先级任务函数 void TaskHighPrio(void *p_arg) { while (1) { // 高优先级任务逻辑 OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, NULL); } } // 中优先级任务函数 void TaskMediumPrio(void *p_arg) { while (1) { // 中优先级任务逻辑 OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, NULL); } } // 低优先级任务函数 void TaskLowPrio(void *p_arg) { while (1) { // 低优先级任务逻辑 OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, NULL); } }在这个示例中,我们使用了 cpu_cfg.h 中定义的宏来设置任务的优先级和堆栈大小。同时,任务函数中的 OSTimeDlyHMSM 函数用于模拟任务执行的延迟。这里只是一个简单的示例,实际的应用中,你需要根据具体的需求来编写任务函数和任务创建的逻辑。
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!
