0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

UCOS2系统内核讲述(四)_ 创建任务

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 2020-03-25 10:12 次阅读

Ⅰ、写在前面

学习本文之前可以参看我前面的文章:

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源代码工程(官方原始软件工程)

官网下载(需要账号):

https://www.micrium.com/downloadcenter/download-results/?searchterm=hm-stmicroelectronics&supported=true

360云盘下载:

https://yunpan.cn/cM9Gzv4drXqxv访问密码 c82c

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 宏定义
    +关注

    关注

    0

    文章

    50

    浏览量

    9005
  • ucos2
    +关注

    关注

    0

    文章

    15

    浏览量

    3557
  • 操作系统内核

    关注

    0

    文章

    8

    浏览量

    2368
收藏 人收藏

    评论

    相关推荐

    esp8266的freertos+lwip不支持在多个任务创建多个不同的socket吗?

    我用的是V1.5.0版本的rtos的sdk。 我起了两个任务,每个任务创建一个tcp socket 客户端,每个socket都是设置成非阻塞的。 其中一个任务的socket,我用
    发表于 07-11 07:29

    如何使用freeRTOS在两个任务之间传输任务数据?

    大家好, 我是 PSoC6 的新手,并尝试以运行第二个任务的方式调整“ PSoC™ 6 MCU:emFile 文件系统”,该任务作为 I2C 主控运行。 i
    发表于 07-03 07:55

    esp32-c3工程中怎么创建多个freertos任务?

    ESP-IDF中给出的ESP32-C3的例程都只有一个任务。即void app_main() 而且没看见这个app_main任务是在哪里被创建的??? 如果我想建一个ESP32-C3的多任务
    发表于 06-27 06:37

    esp32S2创建任务时,若任务堆栈大小配置超过 4096*6 ,该任务创建失败,如何解决?

    esp32S2创建任务时,若任务堆栈大小配置超过 4096*6 ,该任务创建失败, xTask
    发表于 06-20 08:26

    STM32F303 ucos ii任务调度都用什么?

    现在303上用ucos ii跑了两个任务,一个是显示LCD,一个是读取FRAM。现在发现,若读FRAM的优先级高,有时LCD会花屏一闪,若显示优先级高,有时FRAM读出的数会不对。 目前是做个信号量做互锁,但这样跟不用系统时差不
    发表于 05-14 06:16

    uCOS使用FATFS的时候如果操作SD卡的优先级低了,uCOS就死机怎么解决?

    不知道大家遇到过这个情况没有,uCOS使用FATFS的时候如果操作SD卡的优先级低了,uCOS相应的任务会死机,我的FATFS的可重入也已经打开了
    发表于 05-14 06:13

    请问一下FREERTOS只能创建4个任务,修改哪个宏定义可以增加创建任务的数量?

    请问一下FREERTOS只能创建4个任务,修改哪个宏定义可以增加创建任务的数量?解决方法:增加FREERTOS的堆。
    发表于 05-13 06:44

    emwin发布信号量给ucos的其他任务失败的原因?

    , OS_OPT_PEND_BLOCKING,p_ts, err); //Test(); GPIOG->ODR^=GPIO_Pin_13; OSTimeDlyHMSM(0, 0, 2, 0
    发表于 05-11 07:20

    基于STM32Cubemx创建FreeRTOS,创建UART任务遇到的两个问题求解

    基于STM32Cubemx创建FreeRTOS,创建UART任务,经过测试发现有以下两个问题: 1、串口波特率问题: 在STM32Cubemx中串口设置如下: /* USART3 init
    发表于 05-10 07:33

    用STM32CubeMX中的FreeRTOS创建3任务无法运行的原因?

    用STM32CubeMX中的FreeRTOS 创建3任务 Task Priority =osPrioirityNoral 等级的任务,无法运行。 如果创建
    发表于 05-09 07:02

    OpenHarmony语言基础类库【@ohos.taskpool(启动任务池)】

    任务池(taskpool)作用是为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能,且您无需关心线程实例的生命周期。您可以使用任务池API创建后台
    的头像 发表于 04-24 17:45 346次阅读
    OpenHarmony语言基础类库【@ohos.taskpool(启动<b class='flag-5'>任务</b>池)】

    freertos任务创建,每一个任务分配的内存是多大才好,怎么计算呢?

    小白刚刚接触freertos,想问一下就创建任务而言,每一个任务分配的内存是多大才好,怎么计算呢? 另外,每个任务的执行周期怎么确定?在任务
    发表于 04-23 06:39

    请问stm32L4是不是M4内核

    为什么L4在ucos 库里是属于 M3内核,F4系列 在ucos库里是属于 M4内核
    发表于 04-17 07:07

    请问FreeRTOS同一个任务多次创建会有什么后果?

    比如在初始创建任务时就创建任务1、2、3、4、5 然后在任务
    发表于 04-15 06:36

    RZ/G2L Linux系统如何添加新的内核模块

    RZ/G2L Linux系统的镜像基于yocto构建,本篇介绍如何添加新的内核模块。
    的头像 发表于 01-04 12:19 1777次阅读
    RZ/G<b class='flag-5'>2</b>L Linux<b class='flag-5'>系统</b>如何添加新的<b class='flag-5'>内核</b>模块