(学习日记)2024.05.11:UCOSIII第六十五节:常用的控制宏介绍 第一部分

2024-05-01 1390阅读

之前的章节都是针对某个或某些知识点进行的专项讲解,重点在功能和代码解释。

(学习日记)2024.05.11:UCOSIII第六十五节:常用的控制宏介绍 第一部分
(图片来源网络,侵删)

回到最初开始学μC/OS-III系统时,当时就定下了一个目标,不仅要读懂,还要读透,改造成更适合中国宝宝体质的使用方式。在学完野火的教程后,经过几经思考,最后决定自己锦上添花,再续上几章。

这几章想达成目的如下:

  • 能够快速的上手
  • 能够控制系统的功能
  • 明白移植的过程
  • 能够根据需要的功能来裁剪源码

    从第六十一章开始的章节都是熟读源码后,根据笔者的整理方法,按照某种逻辑从系统源码中抽出来的专项解释。

    笔者整理方法如下

    1. 各文件夹功能介绍(每个文件夹放什么文件,哪些是移植的,哪些不需要改,哪些需要修改)
    2. 各文件功能概览(每个文件都明白有哪些东西,是系统的哪一部分)
    3. 各文件函数概览(每个文件的有什么函数,函数的作用是什么,形参是什么)
    4. 移植的本质与移植的顺序(哪些文件需要了解,哪些文件是移植的时候需要更换的)
    5. 添加与裁剪源码(添功能与删功能怎么上手)
    6. 常用的结构体列表
    7. 常用宏介绍(如何用宏来控制整个系统,启用或关闭某个功能)
    8. main函数常用的结构顺序
    9. 创建任务的流程
    10. 任务在几种队列的变化

    每个整理方法会用一章或多章的篇幅来解释。

    点击此处进入μ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 函数用于模拟任务执行的延迟。这里只是一个简单的示例,实际的应用中,你需要根据具体的需求来编写任务函数和任务创建的逻辑。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]