物联操作技术应用 3_第1页
物联操作技术应用 3_第2页
物联操作技术应用 3_第3页
物联操作技术应用 3_第4页
物联操作技术应用 3_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第3章任务管理Chapter3TaskManagement《物联网操作系统技术与应用》制作人张亚军

前面已经完成了LiteOS到STM32开发板的移植,LiteOS基础内核支持任务管理、内存管理、时间管理、通信机制、中断管理、队列管理、事件管理、定时器等基础组件,下面从最简单的任务创建开始,开启学习使用LiteOS的征程。

本章先介绍任务相关的基本概念,分析任务调度的机制,学习任务相关函数的功能及使用,让读者掌握LiteOS的任务管理,从而能够创建单任务及多任务程序。前言01040302学习目标能够描述任务的基本概念以及任务调度的具体过程能够描述LiteOS创建任务的过程能够使用任务管理函数创建单任务程序能够创建多任务程序目录任务管理基本概念 任务管理常用函数3.13.2CONTENTS任务管理基本概念3.1BasicConceptsofTaskManagement

3.1.1任务在物联网操作系统中,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。LiteOS是一个支持多任务的操作系统,多个任务在单个CPU上并发执行,每个任务都在独立的环境中运行,在任何时刻,有且只有一个任务处于运行态,从宏观上可以看作单个CPU同时执行多个任务,从微观上看则是CPU通过快速的任务切换来实现并发。

3.1.2任务控制块

任务可以视作一组信息组成的实体。任务的信息存放在一个名为任务控制块(TaskControlBlock,TCB)的数据结构表中。每一个任务都含有一个TCB,TCB包含了任务栈指针、任务状态、任务优先级、任务ID、任务名、任务入口函数等信息,这些信息可以反映出任务的运行情况。当任务被中断并在后来恢复执行时,可以通过TCB找到任务之前的全部运行状态,并依此恢复任务,就像任务从来没有被打断过一样。3.1任务管理基本概念TCB的信息在任务创建时设置并初始化,随后在操作系统内核调度和任务执行过程中实时记录任务的相关信息。TCB信息定义在LiteOS源码目录下的\kernel\base\include\los_tack.ph文件中,内容如下:3.1任务管理基本概念typedefstructtagTaskCB{VOID*pStackPointer;/**<任务栈指针*/UINT16usTaskStatus;/**<任务状态*/UINT16usPriority;/**<任务优先级*/UINT32uwStackSize;/**<任务栈大小*/UINT32uwTopOfStack;/**<任务栈顶*/UINT32uwTaskID;/**<任务ID*/TSK_ENTRY_FUNCpfnTaskEntry;/**<任务入口函数*/VOID*pTaskSem;/**<任务阻塞在哪个信号量*/VOID*pTaskMux;/**<任务阻塞在哪个互斥锁*/UINT32uwArg;/**<参数*/CHAR*pcTaskName;/**<任务名称

*/LOS_DL_LISTstPendList;/**<挂起列表*/LOS_DL_LISTstTimerList;/**<时间相关列表*/UINT32uwIdxRollNum;/**<TASK在排序队列中的超时时间控制信息。系统依据该值为TASK设置超时时间,扫描并处理超时状态。*/EVENT_CB_SuwEvent;/**<事件*/UINT32uwEventMask;/**<事件掩码*/UINT32uwEventMode;/**<事件模式*/VOID*puwMsg;/**<内存分配给队列*/#if(LOSCFG_LIB_LIBC_NEWLIB_REENT==YES)struct_reentstNewLibReent;#endif}LOS_TASK_CB;

3.1.3任务栈

每个任务都拥有一个独立的栈空间,称之为任务栈。任务栈占用的是MCU内部的SRAM(静态随机存取存储器,内存),栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。创建的任务越多,需要使用的栈空间就越大,即需要使用的SRAM也就越多,一个MCU能够支持创建多少个任务,取决于它的SRAM空间有多少。当任务切换或响应中断时,会将切出或挂起的任务的上下文信息保存在任务自身的任务栈中,任务恢复运行时再还原现场,以保证任务恢复后数据不会丢失。

在LiteOS中,允许用户指定任务栈大小,任务栈的大小按8字节对齐。若指定的任务栈大小为0,则使用默认的任务栈大小。

3.1任务管理基本概念3.1.4任务状态任务状态用于描述任务所表现出的行为。HuaweiLiteOS系统中的任务有多种运行状态。系统初始化完成后,创建的任务就可以在系统中竞争一定的资源,由内核进行调度。任务状态通常分为以下四种:(1)就绪态(Ready):该任务在就绪队列中,只等待CPU。(2)运行态(Running):该任务正在执行。(3)阻塞态(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、任务正在等待信号量、读写队列或者等待事件等。(4)退出态(Dead):该任务运行结束,等待系统回收资源。

3.1任务管理基本概念LiteOS中的每一个任务都有多种运行状态,这些状态是怎么迁移的呢?图3-1展示了任务在4种状态间的迁移。

3.1任务管理基本概念图3-1任务在4种状态间的迁移任务状态迁移说明:(1)就绪态→运行态任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行,从而进入运行态,但此刻该任务依旧在就绪队列中。(2)运行态→阻塞态正在运行的任务发生阻塞(挂起、延时、读信号量等)时,该任务会从就绪队列中删除,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。3.1任务管理基本概念

(3)阻塞态→就绪态(阻塞态→运行态)

阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。

(4)就绪态→阻塞态

任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务从就绪队列中删除,不会参与任务调度,直到该任务被恢复。

(5)运行态→就绪态

有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。

(6)运行态→退出态

运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。

(7)阻塞态→退出态

阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。3.1.5任务优先级优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,就绪队列中最高优先级的任务将得到执行。高优先级的任务可以打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。以HuaweiLiteOS为例,任务一共有32个优先级(0~31),最高优先级为0,最低优先级为31。任务优先级在任务创建时给定,也可以在执行过程中进行动态调整。优先级可以使用LiteOS的API动态的设定和查询。

3.1任务管理基本概念3.1.6任务ID

在LiteOS中,任务ID(也可以理解为任务句柄)是非常重要的,因为它是任务的唯一标识,任务ID本质是一个从0开始的整数,是任务身份的标志(也可以简单理解为任务的索引号)。在任务创建之前,用户需要定义一个任务ID变量,用来存储任务创建成功后返回的任务ID。用户可以通过任务ID对任务进行挂起、恢复、查询信息等操作。任务ID定义的代码如下:

3.1任务管理基本概念1

/*定义任务ID变量Test1_Task_Handle*/2UINT32Test1_Task_Handle;3.1.7任务上下文

任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当一个任务挂起时,其他任务继续执行,可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。

因此,HuaweiLiteOS在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后,从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。

3.1.8任务调度机制LiteOS中提供的任务调度算法包括抢占式调度机制和时间片轮转调度机制。抢占式调度:在系统中除了中断处理函数、调度器上锁和处于临界段中的情况是不可抢占之外,系统的其他部分都是可以抢占的。当有比当前任务优先级更高的任务就绪时,当前任务将立刻被切出,高优先级任务抢占处理器运行。时间片轮转调度:是一种经典、简单、公平,且广泛使用的调度机制。相同优先级的任务采用时间片轮转方式进行调度。每个任务被分配一个时间段,称为时间片,即该任务允许运行的时间。如果在时间片结束时任务还在运行,则CPU将被剥夺并分配给另一个任务;如果任务在时间片结束前阻塞或结束,则CPU立即进行切换。

3.1任务管理基本概念任务管理常用函数CommonFunctionsofTaskManagement3.23.2

任务管理常用函数

HuaweiLiteOS任务管理模块提供任务创建、任务删除、任务延时、任务挂起和任务恢复等功能。用户创建任务时,系统会将任务栈进行初始化,预置上下文,并将“任务入口函数”地址放在相应位置,这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。

任务管理提供的常用函数及功能如表3-1所示。

表3-1任务管理常用函数及功能功能分类函数名功能创建和删除任务LOS_TaskCreate创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务LOS_TaskDelete删除指定的任务控制任务状态LOS_TaskResume恢复指定任务ID号的任务,使该任务进入ready状态LOS_TaskSuspend挂起指定任务ID号的任务,然后切换任务LOS_TaskDelay任务延时等待,释放CPU,等待时间(时间单位是tick)到期后该任务会重新进入ready状态。控制任务优先级LOS_CurTaskPriSet设置当前任务的优先级LOS_TaskPriSet设置指定任务ID号的任务的优先级LOS_TaskPriGet获取指定任务ID号的任务的优先级3.2

任务管理常用函数

3.2.1任务创建函数LOS_TaskCreate()

创建任务函数是创建每个独立任务的时候必须使用的,LOS_TaskCreate()函数语法要点如表3-2所示。在使用任务创建函数的时候,需要提前定义任务ID变量,并且要自定义实现任务创建的pstInitParam,如果任务创建成功,则返回LOS_OK,否则返回对应的错误代码。

表3-2LOS_TaskCreate()函数语法要点函数原型LITE_OS_SEC_TEXT_INITUINT32LOS_TaskCreate(UINT32*puwTaskID,TSK_INIT_PARAM_S*pstInitParam)函数传入值*puwTaskID:用于接收系统创建好的任务的ID号,后续用户通过该ID号操作任务*pstInitParam:用户创建任务时需要指定的用户级参数。自定义任务配置的TSK_INIT_PARAM_S结构体在los_task.h中,代码如下:typedefstructtagTskInitParam{TSK_ENTRY_FUNCpfnTaskEntry;/**<任务入口函数*/UINT16usTaskPrio;/**<任务的优先级*/UINT32uwArg;/**<任务参数*/UINT32uwStackSize;/**<任务栈大小*/CHAR*pcName;/**<任务名称*/UINT32uwResved;/**<设置LOS_TASK_STATUS_DETACHED的值。表示任务的工作函数退出后是否自行删除该任务,置0表示不删除。默认为自行删除。*/}TSK_INIT_PARAM_S;用户可以根据自己的任务需要来配置,重要任务的优先级可以设置高一点,任务栈可以设置大一点,防止溢出导致系统崩溃,若指定的任务栈大小为0,则系统使用配置项LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE指定默认的任务栈大小,任务栈的大小按8字节大小对齐。函数返回值LOS_OK:成功创建任务错误代码:出错函数原型中的LITE_OS_SEC_TEXT_INIT,其作用是将函数放入指定的段。3.2

任务管理常用函数

3.2.2任务删除函数LOS_TaskDelete()

任务删除函数是根据任务ID直接删除任务,任务控制块与任务栈将被系统回收,所有保存的信息都会被清空。LOS_TaskDelete()函数语法要点如表3-3所示。

表3-3LOS_TaskDelete()函数语法要点函数原型LITE_OS_SEC_TEXT_INITUINT32LOS_TaskDelete(UINT32uwTaskID)函数传入值uwTaskID:要删除的任务的ID号函数返回值LOS_OK:成功删除任务错误代码:出错

3.2.3任务延时函数LOS_TaskDelay()

为了避免高优先级任务始终抢占CPU而导致低优先级任务无法执行,可以在程序中增加延时函数,以确保低优先级的任务能够被执行到。LiteOS的延时函数为LOS_TaskDelay(),使用该函数,任务将在指定数量的Tick内释放CPU资源,从而让低优先级的任务能够运行。

表3-4LOS_TaskDelay()函数语法要点函数原型LITE_OS_SEC_TEXTUINT32LOS_TaskDelay(UINT32uwTick)函数传入值uwTick:延时的tick数函数返回值LOS_OK:成功延时错误代码:出错3.2

任务管理常用函数

注意:

(1)任务延时函数不允许在中断中使用;

(2)任务延时函数不允许在任务调度被锁定的时候使用;

(3)不允许在系统初始化之前使用该函数;

(4)如果传入延时tick数为0并且未锁定任务调度,则执行具有当前任务相同优先级的任务队列中的下一个任务,如果没有当前任务优先级的就绪任务可用,则不会发生任务调度,并继续执行当前任务;

(5)当传入延时tick数大于0时,需要将当前任务加入到排序队列中,等待延时时间到后超时唤醒。启动一次任务切换,调度优先级队列中优先级最高的任务执行;

(6)任务延时函数有返回值,如果使用时候发生错误,可以根据返回的错误代码来进行调整;

(7)延时的时间不一定绝对准确,有可能会因为高优先级任务工作而致使低优先级任务的延时比用户期望的延时长。

任务描述

在LiteOS中创建任务Test1_Task,程序运行后,每隔1000ticks,开发板串口输出一次信息、LED1灯由亮变灭或由灭变亮翻转闪烁。说明:tick是系统最小的时间单位,可以在系统配置文件中配置,假设每秒产生1000个tick中断,那么tick中断每1ms产生一次。任务3-1创建单任务

任务描述

在LiteOS中创建两个任务Test1_Task和Test2_Task,程序运行后,Test1_Task任务控制开发板上LED1灯每隔1000ticks翻转闪烁,并在串口输出相应运行信息;Test2_Task任务控制LED2灯每隔500ticks翻转闪烁,并在串口输出相应运行信息。任务3-2创建多任务 3.2

任务管理常用函数3.2.4设置任务的优先级函数LOS_TaskPriSet()

任务的优先级是可以动态调整的。在HuaweiLiteOS中,可以使用LOS_TaskPriSet()函数设置指定ID的任务的优先级,优先级调整会立即生效。

设置任务优先级LOS_TaskPriSet()函数语法要点如表3-5所示。

表3-5LOS_TaskPriSet()函数语法要点函数原型LITE_OS_SEC_TEXT_MINORUINT32LOS_TaskPriSet(UINT32uwTaskID,UINT16usTaskPrio)函数传入值uwTaskID:要设置优先级的任务的ID号usTaskPrio:任务的优先级函数返回值LOS_OK:成功设置任务优先级错误代码:出错3.2.5设置当前任务的优先级函数LOS_CurTaskPriSet()

使用LOS_CurTaskPriSet()函数可以设置当前任务的优先级,其语法要点如表3-6所示。

表3-6LOS_CurTaskPriSet()函数语法要点函数原型LITE_OS_SEC_TEXT_MINORUINT32LOS_CurTaskPriSet(UINT16usTaskPrio)函数传入值usTaskPrio:任务的优先级函数返回值LOS_OK:当前正在运行的任务的优先级已成功设置为指定的优先级错误代码:出错3.2

任务管理常用函数3.2.6获取任务的优先级函数LOS_TaskPriGet()

使用LOS_TaskPriGet()函数可以设置当前任务的优先级,其语法要点如表3-7所示。

表3-7LOS_TaskPriGet()函数语法要点3.2.7任务挂起函数LOS_TaskSuspend()

当长时间暂停运行某个任务,打算在需要的时候再恢复运行,此时,就可以使用任务挂起函数,即仅仅使任务进入阻塞态,其内部的资源都会保留在任务栈中,且不会参与任务的调度。

函数原型LITE_OS_SEC_TEXT_MINORUINT16LOS_TaskPriGet(UINT32uwTaskID)函数传入值uwTaskID:要获取优先级的任务的ID号函数返回值任务号为uwTaskID的任务的优先级:成功返回任务优先级错误代码:出错

注意:(1)不建议使用LOS_CurTaskPriSet()或者LOS_TaskPriSet()函数来修改软件定时器任务的优先级,否则可能会导致系统出现问题;(2)LOS_CurTaskPriSet()和LOS_TaskPriSet()函数不能在中断中使用;(3)LOS_TaskPriGet()函数传入的taskID对应的任务未创建或者超过最大任务数,统一返回0xffff。3.2

任务管理常用函数3.2.8任务恢复函数LOS_TaskResume()

当挂起的任务需要恢复时,可以调用任务恢复函数LOS_TaskResume(),任务即可从阻塞态进入就绪态,参与任务的调度,如果该任务的优先级是当前就绪任务中优先级最高的,那么系统就会立即进行一次任务切换,恢复的任务将按照挂起前的任务状态继续运行。表3-9LOS_TaskResume()函数语法要点函数原型LITE_OS_SEC_TEXT_INITUINT32LOS_TaskResume(UINT32uwTaskID)函数传入值uwTaskID:要恢复的任务的ID号函数返回值LOS_OK:任务成功恢复错误代码:出错表3-8LOS_TaskSuspend()函数语法要点函数原型LITE_OS_SEC_TEXT_INITUINT32LOS_TaskSuspend(UINT32uwTaskID)函数传入值uwTaskID:要挂起的任务的ID号函数返回值LOS_OK:任务成功挂起错误代码:出错注意:挂起任务的时候若为当前任务且已锁任务,则不能被挂起。

任务描述在LiteOS中创建两个任务LED_Task和Key_Task,LED_Task是LED任务,Key_Task是按键任务。LED任务的功能是LED1灯每隔1000ticks翻转闪烁,并在串口打印任务运行的状态;按键任务则检测按键的按下情况,按下KEY1键将LED任务挂起,按下KEY2键将LED任务恢复。

任务3-3任务管理 谢谢观看THANKYOUFORWATCHING任务3-1创建单任务Task3-1CreatingaSingleTask《物联网操作系统技术与应用》制作人张亚军

任务描述

在LiteOS中创建任务Test1_Task,程序运行后,每隔1000ticks,开发板串口输出一次信息、LED1灯由亮变灭或由灭变亮翻转闪烁。说明:tick是系统最小的时间单位,可以在系统配置文件中配置,假设每秒产生1000个tick中断,那么tick中断每1ms产生一次。

任务实现1.打开上一章中移植好LiteOS的裸机工程TEST(双击TEST\MDK-ARM目录下的TEST.uvprojx文件),修改main.c文件,添加头文件。任务3-1创建单任务26

/*USERCODEBEGINIncludes*/27

/*LiteOS头文件*/28#include"los_sys.h"29#include"los_task.ph"30

/*USERCODEENDIncludes*/2.定义任务ID变量。

任务3-1创建单任务59

/*USERCODEBEGIN0*/60

/*定义任务ID变量*/61UINT32Test1_Task_Handle;3.创建和管理任务Test1_Task。1)定义任务实现函数Test1_Task()。62

/*********************************************************63*@函数名

:Test1_Task64*@功能说明:Test1_Task任务实现65*@参数

:NULL66*@返回值

:NULL67***********************************************************/68

static

voidTest1_Task(void)69

{70UINT32uwRet=LOS_OK;71

while(1)72

{73HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_5);74printf("任务1运行中,每1000ticks打印一次信息\r\n");75uwRet=LOS_TaskDelay(1000);76

if(uwRet!=LOS_OK)77

return;78

}79

}2)定义任务创建函数Creat_Test1_Task()。

任务3-1创建单任务80

/*************************************************************81*@函数名

:Creat_Test1_Task82*@功能说明:

创建Test1_Task任务83*@参数

84*@返回值

无85***********************************************************/86

staticUINT32Creat_Test1_Task()87

{88

//定义一个创建任务的返回类型,初始化为创建成功的返回值89UINT32uwRet=LOS_OK;

90

//定义一个用于创建任务的参数结构体91TSK_INIT_PARAM_Stask_init_param;

92task_init_param.usTaskPrio=

1;

/*任务优先级,数值越小,优先级越高*/93task_init_param.pcName=

"Test1_Task";/*任务名*/94task_init_param.pfnTaskEntry=

(TSK_ENTRY_FUNC)Test1_Task;/*任务函数入口*/95task_init_param.uwStackSize=

0x1000;

/*堆栈大小*/96uwRet=LOS_TaskCreate(&Test1_Task_Handle,

&task_init_param);/*创建任务*/97

returnuwRet;98

}3)定义任务管理函数AppTaskCreate()。

任务3-1创建单任务99

/*************************************************************100*@函数名

:AppTaskCreate101*@功能说明:

任务创建,为了方便管理,所有的任务创建函数都可以放在这个函数里面102*@参数

103*@返回值

无104**********************************************************/105staticUINT32AppTaskCreate(void)106{107

/*定义一个返回类型变量,初始化为LOS_OK*/108UINT32uwRet=LOS_OK;109uwRet=Creat_Test1_Task();110

if

(uwRet!=LOS_OK)111

{112printf("Test1_Task任务创建失败!失败代码0x%X\n",uwRet);113

returnuwRet;114

}115

returnLOS_OK;116}117/*USERCODEEND0*/5.在主函数中添加代码。

任务3-1创建单任务123intmain(void)124{125

/*USERCODEBEGIN1*/126UINT32uwRet=LOS_OK;

//定义一个返回类型变量,初始化为LOS_OK127

/*USERCODEEND1*/128

/*MCUonfiguration----------------------------------------*/129

/*Resetofallperipherals,InitializestheFlashinterfaceandtheSystick.*/130HAL_Init();131

/*Configurethesystemclock*/132SystemClock_Config();133

/*Initializeallconfiguredperipherals*/134MX_GPIO_Init();135MX_USART1_UART_Init();136MX_USART2_UART_Init();137MX_USART3_UART_Init();138

/*USERCODEBEGIN2*/139

/*LiteOS内核初始化*/140uwRet=LOS_KernelInit();141

if

(uwRet!=LOS_OK)142

{143printf("LiteOS核心初始化失败!失败代码0x%X\n",uwRet);144

returnLOS_NOK;145

}146printf("任务3-1创建单任务!\n\n");147uwRet=AppTaskCreate();148

if

(uwRet!=LOS_OK)149

{150printf("AppTaskCreate创建任务失败!失败代码0x%X\n",uwRet);151

returnLOS_NOK;152

}153

/*开启LiteOS任务调度*/154LOS_Start();155

/*USERCODEEND2*/156

/*Infiniteloop*/157

while

(1)158

{159

}160}6.添加串口发送函数。

任务3-1创建单任务218/*USERCODEBEGIN4*/219intfputc(intch,

FILE

*f)220{221HAL_UART_Transmit(&huart3,

(uint8_t

*)&ch,

1,

0xFFFF);

222

returnch;223}224/*USERCODEEND4*/7.查看运行结果。

编译并下载程序到开发板中。打开串口调试助手,选择相应串口,打开串口,按下开发板RST复位键,串口打印信息如图3-2所示。图3-2任务3-1运行结果谢谢观看THANKYOUFORWATCHING任务3-2创建多任务Task3-2CreatingMultipleTasks《物联网操作系统技术与应用》制作人张亚军

任务描述

在LiteOS中创建两个任务Test1_Task和Test2_Task,程序运行后,Test1_Task任务控制开发板上LED1灯每隔1000ticks翻转闪烁,并在串口输出相应运行信息;Test2_Task任务控制LED2灯每隔500ticks翻转闪烁,并在串口输出相应运行信息。

任务实现

1.打开任务3-1工程TEST,修改main.c文件,添加定义任务ID变量Test2_Task_Handle。任务3-2创建多任务 59/*USERCODEBEGIN0*/60/*定义任务ID变量*/61UINT32Test1_Task_Handle;62UINT32Test2_Task_Handle;2.添加创建和管理任务Test2_Task。1)在Test1_Task()函数后添加Test2_Task()函数。

任务3-2创建多任务81/************************************************************82*@函数名

:Test2_Task83*@功能说明:Test2_Task任务实现84*@参数

:NULL85*@返回值

:NULL86**********************************************************/87

static

voidTest2_Task(void)88

{89

/*任务都是一个无限循环,不能返回*/90

while(1)91

{92HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_4);93printf("任务2运行中,每500ms打印一次信息\n");94LOS_TaskDelay(500);95

}96

}2)在Creat_Test1_Task()函数后添加Creat_Test2_Task()函数。

任务3-2创建多任务116/************************************************************117*@函数名

:Creat_Test2_Task118*@功能说明:

创建Test2_Task任务119*@参数

120*@返回值

无121***********************************************************/122staticUINT32Creat_Test2_Task()123{124

//定义一个创建任务的返回类型,初始化为创建成功的返回值125UINT32uwRet=LOS_OK;

126TSK_INIT_PARAM_Stask_init_param;127task_init_param.usTaskPrio=

4;

/*任务优先级,数值越小,优先级越高*/128task_init_param.pcName=

"Test2_Task";

/*任务名*/129task_init_param.pfnTaskEntry=

(TSK_ENTRY_FUNC)Test2_Task;/*任务函数入口*/130task_init_param.uwStackSize=

1024;

/*堆栈大小*/131uwRet=LOS_TaskCreate(&Test2_Task_Handle,

&task_init_param);/*创建任务*/132

returnuwRet;133}3)在任务管理函数AppTaskCreate()中添加Creat_Test2_Task()函数调用。

任务3-2创建多任务141staticUINT32AppTaskCreate(void)142{143

/*定义一个返回类型变量,初始化为LOS_OK*/144UINT32uwRet=LOS_OK;145uwRet=Creat_Test1_Task();146

if

(uwRet!=LOS_OK)147

{148printf("Test1_Task任务创建失败!失败代码0x%X\n",uwRet);149

returnuwRet;150

}151uwRet=Creat_Test2_Task();152

if

(uwRet!=LOS_OK)153

{154printf("Test2_Task任务创建失败!失败代码0x%X\n",uwRet);155

returnuwRet;156

}157

returnLOS_OK;158}159/*USERCODEEND0*/3.在主函数中修改代码。

任务3-2创建多任务188printf("任务3-2创建多任务!\n\n");4.查看运行结果。

编译并下载程序到开发板中。按下开发板RST复位键,串口打印信息如图3-3所示。图3-3任务3-2运行结果谢谢观看THANKYOUFORWATCHING任务3-3多任务管理 Task3-3TaskManagement《物联网操作系统技术与应用》制作人张亚军

任务描述在LiteOS中创建两个任务LED_Task和Key_Task,LED_Task是LED任务,Key_Task是按键任务。LED任务的功能是LED1灯每隔1000ticks翻转闪烁,并在串口打印任务运行的状态;按键任务则检测按键的按下情况,按下KEY1键将LED任务挂起,按下KEY2键将LED任务恢复。

任务实现

1.打开任务3-2工程TEST,修改main.c文件,删除原来的任务ID变量,新定义两个任务ID变量LED_Task_Handle和Key_Task_Handle。任务3-3多任务管理 59

/*USERCODEBEGIN0*/60

/*定义任务ID变量*/61UINT32LED_Task_Handle;62UINT32Key_Task_Handle;2.创建和管理任务LED_Task、Key_Task。1)定义任务实现函数LED_Task()和Key_Task()(删除原来的Test1_Task()函数和Test2_Task()函数)。任务3-3任务管理 63

/********************************************************64*@函数名

:LED_Task65*@功能说明:LED_Task任务实现66*@参数

:NULL67*@返回值

:NULL68*********************************************************/69

static

voidLED_Task(void)70

{71

/*任务都是一个无限循环,不能返回*/72

while(1)73

{74HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_5);

//LED1翻转75printf("LED任务正在运行!\n");76LOS_TaskDelay(1000);

77

}78

}79

/************************************************************80*@函数名

:Key_Task81*@功能说明:Key_Task任务实现82*@参数

:NULL83*@返回值

:NULL84***********************************************************/85

static

voidKey_Task(void)86

{87UINT32uwRet=LOS_OK;

88

89

/*任务都是一个无限循环,不能返回*/90

while(1)91

{92

/*KEY1键被按下*/93

if(

!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4))

//读取KEY1按键引脚,低电平表示按下94

{95printf("挂起LED任务!\n");96uwRet=LOS_TaskSuspend(LED_Task_Handle);/*挂起LED1任务*/97

if(LOS_OK==uwRet)98

{99printf("挂起LED任务成功!\n");100LOS_TaskDelay(500);

//等待松手,延时防松手抖动101

}

102

}103

/*KEY2键被按下*/104

else

if(

!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5))

105

{106printf("恢复LED任务!\n");107uwRet=LOS_TaskResume(LED_Task_Handle);

/*恢复LED1任务*/108

if(LOS_OK==uwRet)109

{110printf("恢复LED任务成功!\n");111LOS_TaskDelay(500);

//等待松手,延时防松手抖动112

}113

}114LOS_TaskDelay(20);

/*20ms扫描一次*/115

}116}

2)定义任务创建函数Creat_LED_Task()和Creat_Key_Task()(删除原来Creat_Test1_Task()函数和Creat_Test2_Task()函数)。

任务3-3任务管理 117/************************************************************118*@函数名

:Creat_LED_Task119*@功能说明:

创建LED_Task任务120*@参数

121*@返回值

无122***********************************************************/123staticUINT32Creat_LED_Task()124{125

//定义一个创建任务的返回类型,初始化为创建成功的返回值126UINT32uwRet=LOS_OK;

127

//定义一个用于创建任务的参数结构体128TSK_INIT_PARAM_Stask_init_param;

129task_init_param.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论