Ⅰ、写在前面
学习本文之前可以参看我前面的文章:
UCOS2_STM32移植详细过程(汇总文章)
UCOS2系统内核讲述(一)_总体描述
UCOS2系统内核讲述(二)_初始化调用函数
UCOS2系统内核讲述(三)_TCB任务控制块
上一篇文章讲述了关于TCB(Task Control Block)任务控制块数据结构体的内容。本文学习与应用、也与系统内核紧密相关的一个函数“OSTaskCreateExt”创建任务。
OSTaskCreateExt这个函数是我们的应用程序所调用的函数,在我们所移植的软件工程中,main函数就调用了OSTaskCreateExt函数,显而易见,理解它的功能及其参数是多么重要。
本文还是结合前面移植好、可以运行的源代码(可直接下载运行的程序)来进行讲述关于最新版本UCOS2系统内核部分代码(围绕源代码来讲述)。
关于本文的更多详情请往下看。
Ⅱ、OSTaskCreateExt参数详情
创建任务的函数有两个:
OSTaskCreate:以前老版本UCOS系统创建任务的函数,有4个参数。
OSTaskCreateExt:新版本UCOS系统,在“OSTaskCreate”的基础上增加了一些功能参数,有9个参数。其中4个参数是和老版本一样(为了兼容老版本)。在新版本的UCOS系统上,我们一般都使用这个函数创建任务,因此,下面我们讲述“OSTaskCreateExt”函数中每一个参数的意思。
下面截图是截取os_task.c文件,在OSTaskCreateExt函数上面有关于每一个参数的注释(我在源代码中已经把主要意思修改为中文了,结合main函数传递的参数理解):
1.第一个参数task
task从命名上可以理解到,他的意思就是“任务”。
【代码的命名很重要,不管是函数名还是变量名。好程序的命名一般都是比较规范的,理解起来自然也就不费劲。】
这个参数是一个指向(参数为“void *p_arg”,返回值为“void”的函数)的指针。简单一点就是指向函数的指针。因此。传递的参数是一个函数。
在main.c调用OSTaskCreateExt中我们传递的参数是“AppTaskStart”,就是我们应用程序的名字。
2.第二个参数p_arg
p_arg传递参数的指针,是一个任意类型的参数。
当我们需要传递某些参数给函数时,就可以通过该参数进行传递。
在main.c调用OSTaskCreateExt中我们传递的参数是“(void*) 0”,也就是传递一个“空指针”给函数(因为我们没有参数,就传递一个空指针)。
3.第三个参数ptos
ptos:指向任务堆栈栈顶的指针。
这个参数和“第六个参数pbos”对应,需要根据栈的增长方向“OS_STK_GROWTH”来决定。具体见os_cpu.h文件中OS_STK_GROWTH的宏定义,如下图:
由于我们定义OS_STK_GROWTH为1,增长方向是从高地址往低地址增长,因此,在main.c调用OSTaskCreateExt中我们传递的参数是“TaskStartStk[TASK_START_STK_SIZE - 1]”,也就是栈的高地址为栈顶。
4.第四个参数prio
prio:任务的优先级。
这个参数很好理解,前面也讲述过,优先级具有唯一性,优先级决定该任务指向的优先权利(优先级数值越低,优先级越高)。
我们创建的四个任务中传递的参数分别宏定义如下图:
主任务优先级最高(最先执行),其他三个次任务优先级依次降低。
5.第五个参数id
id:任务的ID。
这个参数比较简单,也就是给每一个创建的任务分配一个ID编号。相当于一篇文章每一章节都有编号的意思。
我们在创建的任务中以“优先级”作为编号,所以在参数中,我们看到连续两个参数都是“优先级”。
6.第六个参数pbos
pbos:指向任务堆栈栈底的指针。
这个参数结合“第三个参数ptos”理解,类似的原理,和栈的增长方向“OS_STK_GROWTH”有关。
根据栈的增长方向“OS_STK_GROWTH”为从高地址往低地址增长,所以,在main.c调用OSTaskCreateExt中我们传递的参数是TaskStartStk[0].
7.第七个参数stk_size
stk_size:任务堆栈大小。
这个参数与app_cfg.c文件中定义的“堆栈变量”有关,我们需要传递的大小就是堆栈数组的大小值。
8.第八个参数pext
pext: 指向用户提供的内存(指针)。
这个参数是用作 TCB 扩展的参数,初学者使用不到这个参数,暂时可以不用去理解。
9.第九个参数opt
opt: 用户操作选项参数。
这个参数用户创建任务时需要处理一些额外信息(操作)的参数。【这个参数比较重要,会处理一些信息,在下一章节重点讲述一下关于该参数调用的“OS_TaskStkClr”】
Opt参数在创建任务是主要的三个,在OSTaskCreateExt函数体上面的注释中已经提出来了,如下图:
OS_TASK_OPT_STK_CHK:检测参数是否可用
OS_TASK_OPT_STK_CLR:清除堆栈(清除创建任务时使用的堆栈)
OS_TASK_OPT_SAVE_FP:保存浮点指针(在进行上下文切换时)
参数是宏定义在ucos_ii.h中,如下图:
也就是调用了某一个宏定义,那个宏定义的功能就使能了。
在main.c调用OSTaskCreateExt中我们传递的参数是“OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR”,进行参数检查和堆栈清除。
Ⅲ、创建任务时的堆栈
创建任务的函数体中有几个函数是比较重要的,本姐讲述下图中红色标记函数(蓝色部分是重点,在下一篇文章重点讲述):
1.OS_TaskStkClr
OS_TaskStkClr:创建任务时清除堆栈。
这个函数需要在os_cfg.h使能OS_TASK_STAT_STK_CHK_EN这个参数。
在上面截图中可以看到opt参数选项需要使能:OS_TASK_OPT_STK_CHK和OS_TASK_OPT_STK_CLR,也就是参数检查和堆栈清除。
清除栈的顺序与栈的增长方向有关。看到源代码就知道清除堆栈,其实就是在初始时清空一下堆栈空间。
2.OSTaskStkInit
OSTaskStkInit:初始化创建任务的堆栈。
这个函数位于os_cpu_c.c文件中,前面移植UCOS时提到了一下该函数。
从源代码中可以看得出来,其实这个函数主要的一个参数就是“ptos”栈顶,我们需要分配并保存堆栈。
Ⅳ、实例工程下载
笔者针对于初学者提供的例程都是去掉了许多不必要的功能,精简了官方的代码,对初学者一看就明白,以简单明了的工程供大家学习。
笔者提供的实例工程都是在板子上经过多次测试并没有问题才上传至360云盘,欢迎下载测试、参照学习。
我将最新UCOS2.92操作系统移植到F0、F1、F3、F4各个硬件平台上,可以根据你芯片系列选择下载。
UCOS基于STM32F0、F1、F3、F4系列实例工程源代码(汇总):
https://yunpan.cn/cM9Fjv88cXbjI 访问密码 048d
本文讲述的部分注释修改为中文(软件工程源代码):
https://yunpan.cn/cMIv8haYBL73y 访问密码 e07e
基于STM32平台的UCOS源代码工程(官方原始软件工程)
官网下载(需要账号):
360云盘下载:
https://yunpan.cn/cM9Gzv4drXqxv 访问密码 c82c
Ⅴ、说明
UCOS相关的文章我会第一时间在微信公众号里面和大家分享,也可以到我博客(blog.csdn.net/ybhuangfugui)上查看。
当你掌握UCOS在一种平台上的移植,其他平台移植原理类似,请不要局限某一平台。
以上总结仅供参考,若有不对之处,敬请谅解。
Ⅵ、最后
更多精彩文章我将第一时间在微信公众号里面分享,如果不想错过,可以关注我的微信公众号。
本着免费分享的原则,方便大家手机学习知识,定期在微信平台分享技术知识。如果你觉得分享的内容对你有用,又想了解更多相关的文章,请用微信搜索“EmbeddDeveloper” 或者扫描下面二维码、关注,将有更多精彩内容等着你。