(学习日记)2024.03.02:UCOSIII第四节:创建任务

写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。


标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。


点击此处进入学习日记的总目录

2024.03.02

  • 九、UCOSIII:创建任务
    • 1、任务的定义
    • 2、定义任务栈
    • 3、定义任务函数
    • 4、定义任务控制块TCB
    • 5、任务创建函数
    • 6、任务栈初始化函数
    • 7、将任务添加到就绪列表
    • 8、全局变量的声明方法

九、UCOSIII:创建任务

1、任务的定义

在裸机系统中,系统的主体就是main函数里面顺序执行的无限循环,这个无限循环里面CPU按照顺序完成各种事情。
在多任务系统中,我们根据功能的不同,把整个系统分割成一个个独立的且无法返回的函数,这个函数我们称为任务。

void task_entry (void *parg)
{/* 任务主体,无限循环且不能返回 */for (;;){/* 任务主体代码 */}
}

2、定义任务栈

在这里插入图片描述

/*
************************************************************************************************************************
*                                                  TCB & STACK & 任务声明
************************************************************************************************************************
*/
#define  TASK1_STK_SIZE       20
#define  TASK2_STK_SIZE       20static   CPU_STK   Task1Stk[TASK1_STK_SIZE];
static   CPU_STK   Task2Stk[TASK2_STK_SIZE];static   OS_TCB    Task1TCB;
static   OS_TCB    Task2TCB;void     Task1( void *p_arg );
void     Task2( void *p_arg );

在多任务系统中,有多少个任务就需要定义多少个任务栈。

任务栈的大小由宏定义控制,在μC/OS-III中, 空闲任务的栈最小应该大于128,那么我们这里的任务的栈也暂且配置为128。
(但是代码里任务栈数量为20)

任务栈其实就是一个预先定义好的全局数据,数据类型为CPU_STK。
在μC/OS-III中,凡是涉及数据类型的地方, μC/OS-II都会将标准的C数据类型用typedef重新取一个类型名,命名方式则采用见名之义的方式命名且统统大写。

3、定义任务函数

任务是一个独立的函数,函数主体无限循环且不能返回。
任务的代码示意如下:

/* flag 必须定义成全局变量才能添加到逻辑分析仪里面观察波形
** 在逻辑分析仪中要设置以 bit 的模式才能看到波形,不能用默认的模拟量
*/
uint32_t flag1;
uint32_t flag2;/* 任务1 */
void Task1( void *p_arg )(2)
{
for ( ;; ) {flag1 = 1;delay( 100 );flag1 = 0;delay( 100 );}//任务是一个独立的、无限循环且不能返回的函数。
}/* 任务2 */
void Task2( void *p_arg )(3)
{
for ( ;; ) {flag2 = 1;delay( 100 );flag2 = 0;delay( 100 );}
}

4、定义任务控制块TCB

在这里插入图片描述

/*
************************************************************************************************************************
************************************************************************************************************************
*                                                  数据类型
************************************************************************************************************************
************************************************************************************************************************
*/typedef  struct  os_rdy_list         OS_RDY_LIST;
typedef  void                        (*OS_TASK_PTR)(void *p_arg);
typedef  struct  os_tcb              OS_TCB;
/*
------------------------------------------------------------------------------------------------------------------------
*                                                   就绪列表
------------------------------------------------------------------------------------------------------------------------
*/
struct os_rdy_list
{OS_TCB        *HeadPtr;OS_TCB        *TailPtr;
};

在裸机系统中,程序的主体是CPU按照顺序执行的。而在多任务系统中,任务的执行是由系统调度的。

系统为了顺利的调度任务, 为每个任务都额外定义了一个任务控制块TCB(Task ControlBlock),这个任务控制块就相当于任务的身份证, 里面存有任务的所有信息,比如任务的栈,任务名称,任务的形参等。

有了这个任务控制块之后, 以后系统对任务的全部操作都可以通过这个TCB来实现。
TCB是一个新的数据类型, 在os.h这个头文件中声明,使用它可以为每个任务都定义一个TCB实体。
目前TCB里面的成员还比较少,只有栈指针和栈大小。其中为了以后操作方便,我们把栈指针作为TCB的第一个成员。

5、任务创建函数

在这里插入图片描述

#include "os.h"void OSTaskCreate (OS_TCB        *p_tcb, OS_TASK_PTR   p_task, void          *p_arg,CPU_STK       *p_stk_base,CPU_STK_SIZE  stk_size,OS_ERR        *p_err)
{CPU_STK       *p_sp;p_sp = OSTaskStkInit (p_task,p_arg,p_stk_base,stk_size);p_tcb->StkPtr = p_sp;p_tcb->StkSize = stk_size;*p_err = OS_ERR_NONE;
}

任务的栈,任务的函数实体,任务的TCB最终需要联系起来才能由系统进行统一调度。

那么这个联系的工作就由任务创建函数 OSTaskCreate来实现,该函数在os_task.c中定义,所有跟任务相关的函数都在这个文件定义。

  • OSTaskCreate函数遵循μC/OS-III中的函数命名规则,以大小的OS开头,表示这是一个外部函数,可以由用户调用,以OS_开头的函数表示内部函数,只能由μC/OS-III内部使用。紧接着是文件名,表示该函数放在哪个文件,最后是函数功能名称。
  • p_tcb是任务控制块指针。
  • p_task 是任务函数名,类型为OS_TASK_PTR,原型声明在os.h中

在这里插入图片描述
在这里插入图片描述

  • p_arg是任务形参,用于传递任务参数。 p_stk_base 用于指向任务栈的起始地址。 stk_size 表示任务栈的大小。
  • p_err 用于存错误码,μC/OS-III中为函数的返回值预先定义了很多错误码,
    错误码是枚举类型的数据,在os.h中定义 OSTaskStkInit()是任务栈初始化函数。 当任务第一次运行的时候, 加载到CPU寄存器的参数就放在任务栈里面,在任务创建的时候,预先初始化好栈。
  • OSTaskStkInit()函数在os_cpu_c.c中定义
  • p_tcb->StkPtr = p_sp;
    将剩余栈的栈顶指针p_sp保存到任务控制块TCB的第一个成员StkPtr中。
  • p_tcb->StkSize = stk_size;
    将任务栈的大小保存到任务控制块TCB的成员StkSize中。
  • *p_err = OS_ERR_NONE;
    函数执行到这里表示没有错误,即OS_ERR_NONE。

6、任务栈初始化函数

在这里插入图片描述

#include "os.h"/* 任务堆栈初始化 */
CPU_STK *OSTaskStkInit (OS_TASK_PTR  p_task,void         *p_arg,CPU_STK      *p_stk_base,CPU_STK_SIZE stk_size)
{CPU_STK  *p_stk;p_stk = &p_stk_base[stk_size];/* 异常发生时自动保存的寄存器                              */*--p_stk = (CPU_STK)0x01000000u;                        /* xPSR的bit24必须置1                                     */*--p_stk = (CPU_STK)p_task;                             /* 任务的入口地址                                         */*--p_stk = (CPU_STK)0x14141414u;                        /* R14 (LR)                                               */*--p_stk = (CPU_STK)0x12121212u;                        /* R12                                                    */*--p_stk = (CPU_STK)0x03030303u;                        /* R3                                                     */*--p_stk = (CPU_STK)0x02020202u;                        /* R2                                                     */*--p_stk = (CPU_STK)0x01010101u;                        /* R1                                                     */*--p_stk = (CPU_STK)p_arg;                              /* R0 : 任务形参                                          *//* 异常发生时需手动保存的寄存器                            */*--p_stk = (CPU_STK)0x11111111u;                        /* R11                                                    */*--p_stk = (CPU_STK)0x10101010u;                        /* R10                                                    */*--p_stk = (CPU_STK)0x09090909u;                        /* R9                                                     */*--p_stk = (CPU_STK)0x08080808u;                        /* R8                                                     */*--p_stk = (CPU_STK)0x07070707u;                        /* R7                                                     */*--p_stk = (CPU_STK)0x06060606u;                        /* R6                                                     */*--p_stk = (CPU_STK)0x05050505u;                        /* R5                                                     */*--p_stk = (CPU_STK)0x04040404u;                        /* R4                                                     */return (p_stk);
}
  • p_task是任务名,指示着任务的入口地址,在任务切换的时候,需要加载到R15, 即PC寄存器,这样CPU就可以找到要运行的任务。

  • p_arg 是任务的形参,用于传递参数,在任务切换的时候,需要加载到寄存器R0。R0寄存器通常用来传递参数。

  • p_stk_base 表示任务栈的起始地址。

  • stk_size 表示任务栈的大小, 数据类型为CPU_STK_SIZE,在Cortex-M3内核的处理器中等于4个字节,即一个字。

  • p_stk = &p_stk_base[stk_size];
    获取任务栈的栈顶地址,ARMCM3处理器的栈是由高地址向低地址生长的。所以初始化栈之前, 要获取到栈顶地址,然后栈地址逐一递减即可。

  • /* 异常发生时自动保存的寄存器 */ 下面的八行
    任务第一次运行的时候,加载到CPU寄存器的环境参数我们要预先初始化好。初始化的顺序固定, 首先是异常发生时自动保存的8个寄存器,即xPSR、R15、R14、R12、R3、R2、R1和R0。其中xPSR寄存器的位24必须是1, R15PC指针必须存的是任务的入口地址,R0必须是任务形参,剩下的R14、R12、R3、R2和R1为了调试方便,填入与寄存器号相对应的16进制数。

  • /* 异常发生时需手动保存的寄存器 */ 下面的八行
    剩下的是8个需要手动加载到CPU寄存器的参数,为了调试方便填入与寄存器号相对应的16进制数。

  • 返回栈指针p_stk,这个时候p_stk指向剩余栈的栈顶。

7、将任务添加到就绪列表

任务创建好之后,我们需要把任务添加到一个叫就绪列表的数组里面,表示任务已经就绪,系统随时可以调度。

在这里插入图片描述

在这里插入图片描述

int main(void)
{	OS_ERR err;/* 初始化相关的全局变量 */OSInit(&err);/* 创建任务 */OSTaskCreate ((OS_TCB*)      &Task1TCB, (OS_TASK_PTR ) Task1, (void *)       0,(CPU_STK*)     &Task1Stk[0],(CPU_STK_SIZE) TASK1_STK_SIZE,(OS_ERR *)     &err);OSTaskCreate ((OS_TCB*)      &Task2TCB, (OS_TASK_PTR ) Task2, (void *)       0,(CPU_STK*)     &Task2Stk[0],(CPU_STK_SIZE) TASK2_STK_SIZE,(OS_ERR *)     &err);/* 将任务加入到就绪列表 */OSRdyList[0].HeadPtr = &Task1TCB;OSRdyList[1].HeadPtr = &Task2TCB;/* 启动OS,将不再返回 */				OSStart(&err);
}

把任务TCB指针放到OSRDYList数组里面。
OSRdyList定义如下
在这里插入图片描述
OS_CFG_PRIO_MAX是一个定义,表示这个系统支持多少个优先级(刚开始暂时不支持多个优先级,往后章节会支持), 目前这里仅用 来表示这个就绪列表可以存多少个任务的TCB指针。

具体的宏在os_cfg.h中定义
在这里插入图片描述

OSRdyList是一个类型为OS_RDY_LIST的全局变量, 在os.h中定义

μC/OS-III中中会为每个数据类型重新取一个大写的名字。

OS_RDY_LIST里面目前暂时只有两个TCB类型的指针,一个是头指针,一个是尾指针。

需要使用头尾指针来将TCB串成一个双向链表。
在这里插入图片描述

8、全局变量的声明方法

在μC/OS-III中,需要使用很多全局变量,这些全局变量都在os.h这个头文件中定义,但是os.h会被包含进很多的文件中, 那么编译的时候,os.h里面定义的全局变量就会出现重复定义的情况,而我们要的只是os.h里面定义的全局变量只定义一次, 其他包含os.h头文件的时候只是声明。

通常我们的做法都是在C文件里面定义全局变量,然后在头文件里面加extern声明,哪里需要使用就在哪里加extern声明。
但是μC/OS-III中,文件非常多,这种方法可行,但不现实。所以就有了现在在os.h头文件中定义全局变量, 然后在os.h文件的开头加上 代码清单:任务-17 的宏定义的方法。

但是到了这里还没成功, μC/OS-III再另外新建了一个os_var.c的文件,在里面包含os.h, 且只在这个文件里面定义OS_GLOBALS这个宏

如果没有定义OS_GLOBALS这个宏,那么OS_EXT就为空,否则就为extern。
在这里插入图片描述
经过这样处理之后,在编译整个工程的时候,只有var.c里面的os.h的OS_EXT才会被替换为空,即变量的定义, 其他包含os.h的文件因为没有定义OS_GLOBALS这个宏,则OS_EXT会被替换成extern,即变成了变量的声明。 这样就实现了在头文件中定义变量。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/719427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

这是开玩笑吗?加个工具,WPS与Excel表格变成了应用系统

表格处理数据简单快捷,是个人用户的首选。然而,当企业长期使用,成本表、客户表、销售表等堆积如山,寻找所需表格如同大海捞针,稍有不慎便可能导致数据丢失、混乱。即便使用WPS和Excel这样的表格软件,处理大…

回溯难题(算法村第十八关黄金挑战)

复原 IP 地址 93. 复原 IP 地址 - 力扣(LeetCode) 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 . 分隔。 例如:"0.1.2.201" 和 &q…

IDEA中使用git提交代码时,有.class文件怎么避免

在IDEA中使用git提交代码时,git把.class文件都给我放进来了,而我并不想要提交.class文件 我要提交的是.java文件 应该怎么设置呢 解决方案,点击整个项目的生命周期中的clean之前,你会发现git提交栏的.class文件都不见了。

ROS2服务通信的实现

文章目录 1.服务通信的概念及应用场景1.1概念1.2 应用场景 2.准备工作3.服务通信的实现3.1 服务通信接口消息3.2 服务端实现3.3 客户端实现3.4 编译及运行3.4.1 修改CMakeLists3.4.2 服务端运行结果3.4.2 客户端运行结果 1.服务通信的概念及应用场景 1.1概念 服务通信也是ROS…

抖店0元入驻不交钱会怎么样?个人店和个体店的利弊分析,开店必看

我是王路飞。 现在的抖店是可以开通个人店的。 也就是不需要营业执照、直接使用个人身份证就可以在抖音开店,而且也不需要缴纳店铺保证金就能开店运营了。 但真实情况是怎么样的呢?新手0元入驻抖店不交这个保证金会怎么样呢? 今天给想在抖…

AI大预言模型——ChatGPT在地学、GIS、气象、农业、生态、环境应用

原文链接:AI大预言模型——ChatGPT在地学、GIS、气象、农业、生态、环境应用 一开启大模型 1 开启大模型 1)大模型的发展历程与最新功能 2)大模型的强大功能与应用场景 3)国内外经典大模型(ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diff…

ios App 发送广播失败解决

记录开发 ios App 使用 c 混编时遇到的问题: 开发环境 macOS Sonoma(最新版本14.3.1) Xcode Version 15.2 ipadOS(最新版本17.3.1) 问题:在mac 上 和 ipad上测试,当 udp 发送广播&#xff…

跨域引起的两个接口的session_id不是同一个

来源场景: RequestMapping(“/captcha”)接口设置了SESSION_KEY,也能获取到,但是到了PostMapping(“/login”)接口就是空的,由于跨域导致的两个session_id不是同一个 /*** 系统用户 前端控制器*/ Controller CrossOrigin(origins…

【数据结构和算法初阶(C语言)】双向循环带头链表的增删查改详解(天才设计的链表结构,应用简单逆天!!!!!)

目录 ​编辑​编辑 1.双向链表的定义:前赴后继 2.带头链表的定义-----哨兵位 3.增删查改 3.1创建新节点函数----方便后续增加节点调用 3.2创建哨兵位----创建头结点 3.3增加节点,尾部插入数据 3.4尾删除 3.5查找函数----遍历对比&#xff…

AcWing 562.壁画

咱先看一眼算法标签,发现是思维题、枚举、前缀和 Buttt其实我们根据上诉的样例解释部分就会发现,其实这就是一个长度为⌈n/2⌉(向上取整哦)的连续子数组的最大和。 这题我也用暴力法试过啦,很明显会TLE 如果你对dp题…

Mac M系列芯片如何重新安装系统

使用可引导安装器重新安装(可用于安装非最新的 Mac OS,系统降级,需要清除所有数据,过程确保连接上网络,虽然这种方式不会下载 Mac OS,但是需要下载固件等信息) 插入制作好的可引导安装器&#x…

【使用imgaug库调整图像大小并修改对应的XML标签框】

使用imgaug库可以方便地进行图像增强操作,包括调整图像大小。以下是使用imgaug库调整图像大小并修改对应的XML标签框的示例脚本: 注意修改输入文件夹路径、输出文件夹路径和目标尺寸为自己内容。 input_folder "path/to/your/input_folder" …

kalibr标定ZED2i双目加imu

一、录制bag 本人使用的zed2i相机。 rosbag record -O 32 /zed2i/zed_node/imu/data /zed2i/zed_node/imdata_raw /zed2i/zed_node/left/image_rect_color /zed2i/zed_node/right/image_rect_color /zed2i/zed_node/left_raw/image_raw_color /zed2i/zed_node/right_raw/ima…

Matlab|【免费】基于合作博弈的综合能源系统利益分配优化调度

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序实现的模型为综合能源系统利益分配优化调度,采用合作博弈方法,模型针对IES系统的P2G、电解槽、甲烷反应器、储氢罐、CHP和燃气锅炉等设备进行建模,实现基于合作博弈的…

Linux 学习笔记(10)

十、 进程管理 进程就是运行中的程序,一个运行着的程序,可能有多个进程。 比如 LinuxSir.Org 所用的 WWW 服务器是 apache 服务器,当管理员启动服务后,可能会有好多人来访问,也就是说许多用户来同时请 求 htt…

Django官网项目 二

官网地址:Writing your first Django app, part 2 | Django documentation | Django 创建模组: 注册model (bug:没有加后面的逗号) 在manage.py 的目录下: python manage.py makemigrations polls pyth…

redis09 集群(cluster)

思维草图 为什么要使用集群 单台redis内存容量的限制单台redis并发写量太大有性能瓶颈 redis集群认识 redis集群是对redis的水平扩容,即启动N个redis节点,将整个数据分布存储在这个N个节点中,每个节点存储总数据的1/N。 如下图&#xff1…

C++ 根据公式计算椭圆任意点到中心的距离

#include <iostream> using namespace std;double fact(int x) //定义阶乘函数。注意是double类型 {double y x; //注意是double类型for (int i x-1; i > 0; i--)y * i;return y; };double My_sin(int x) //定义sin函数。注意是double类型 {double y 0; //注意是do…

【视频图像取证篇】Amped FIVE专业法医图像和视频增强软件之模糊图像去隔行功能

【视频图像取证篇】Amped FIVE专业法医图像和视频增强软件之模糊图像去隔行功能 法医图像和视频增强软件&#xff0c;专业又强大&#xff01;&#xff01;&#xff01;超过 140 种过滤器和工具&#xff0c;用于分析、恢复和增强数字图像和视频。Amped FIVE能够稳定抖动的视频&…

Linux:ansible-playbook配置文件(剧本)(进阶)

Linux&#xff1a;ansible-playbook配置文件&#xff08;剧本&#xff09;_ansible-playbook -i参数-CSDN博客https://blog.csdn.net/w14768855/article/details/132579492?ops_request_misc%257B%2522request%255Fid%2522%253A%2522170930036016800215061982%2522%252C%2522s…