收藏 分享(赏)

《嵌入式操作系统及ARM Cortex-MO》课件第六章.pptx

上传人:bubibi 文档编号:22680020 上传时间:2024-06-27 格式:PPTX 页数:55 大小:6.56MB
下载 相关 举报
《嵌入式操作系统及ARM Cortex-MO》课件第六章.pptx_第1页
第1页 / 共55页
《嵌入式操作系统及ARM Cortex-MO》课件第六章.pptx_第2页
第2页 / 共55页
《嵌入式操作系统及ARM Cortex-MO》课件第六章.pptx_第3页
第3页 / 共55页
《嵌入式操作系统及ARM Cortex-MO》课件第六章.pptx_第4页
第4页 / 共55页
《嵌入式操作系统及ARM Cortex-MO》课件第六章.pptx_第5页
第5页 / 共55页
亲,该文档总共55页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

1、第六章第六章 c/OS-c/OS-任务任务6.16.1C/OS-C/OS-用户任务用户任务6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁6.36.3ISPISP下载下载6.46.4串口通信串口通信6.56.5统计任务实例统计任务实例本章介绍嵌入式实时操作系统C/OS-的用户任务管理方法和基于C/OS-的KEIL MDK工程程序框架,然后,基于LPC824学习板介绍串口通信方法,最后,将讨论统计任务的使用方法。本章的工程程序框架实现了LED灯闪烁和串口通信的功能,后续章节的工程均在这个程序框架的基础上,添加新的任务,扩展新的功能。相对于系统任务而言,C/OS-应用程

2、序中用户创建的任务称为用户任务,每个用户任务都在周期性执行着某项工作,或请求到事件后执行相应的功能。用户任务的特点为:(1)用户任务对应的函数体是一个带有无限循环的函数,由于具有无限循环,故该类函数没有返回值。(2)用户任务对应的函数具有一个“void*”类型的指针参数,该指针可以指向任何类型的数据,通过该指针在任务创建时向任务传递一些数据,这种传递只能发生一次,即创建任务的时候,一旦任务开始工作,就无法再通过该函数参数向任务传递数据了。(3)每个用户任务具有唯一的优先级号,取值范围为0OS_LOWEST_PRIO3(OS_LOWEST_PRIO为os_cfg.h中宏定义的常量,最大值为254

3、),一般地,系统的空闲任务优先级号为OS_LOWEST_PRIO,统计任务的优先级号为OS_LOWEST_PRIO1,定时器任务的优先级号被设定为OS_LOWEST_PRIO2。此外,需要为优先级继承优先级留出优先级号,所以,用户任务的优先级号一般为4OS_LOWEST_PRIO3。在本书基于LPC824的工程中,OS_LOWEST_PRIO被宏定义为26,用户任务的优先级号取值为423。(4)每个用户任务具有独立的堆栈,使用OS_STK类型定义堆栈,堆栈数组的大小一般要在50以上。在C/OS-V2.91中,用户任务管理相关的函数有11个,这里列出常用的6个,如表6-1所示。表表6-16-1请

4、看下页请看下页6.16.1C/OS-C/OS-用户任务用户任务表表6-16-1常用的用户任务管理函数常用的用户任务管理函数6.16.1C/OS-C/OS-用户任务用户任务6.16.1C/OS-C/OS-用户任务用户任务创建用户任务的过程如下:(1)根据任务要实现的功能,编写带有无限循环体的函数。(2)为任务指定唯一的优先级号。(3)为任务创建独立的堆栈。(4)调用OSTaskCreateExt函数创建任务。在C/OS-中,用户任务共有五种状态,如图6-1所示。图图6-16-1用户任务状态用户任务状态6.16.1C/OS-C/OS-用户任务用户任务一个用户任务调用OSTaskCreate或OST

5、askCreateExt函数创建好后,直接处于就绪态。当调用OSTa-skDel函数后,将使用户任务进入到休眠态,只能通过再次调用OSTaskCreate或OSTa-skCreateExt函数创建任务,任务才能使用。多个任务同时就绪时,任务调试器将使优先级最高的任务优先得到CPU使用权而去执行,被剥夺了CPU使用权但没有执行完的任务将进入就绪态。处于执行态的任务被中断服务函数中断后,将进入中断态,当中断服务程序完成后,将从中断态返回执行态,此时C/OS-将在从中断返回的任务以及所有就绪的任务中选择优先级最高的任务,使其占用CPU而得到执行。处于执行态的任务当执行到延时函数(OSTimeDly或

6、OSTimeDlyHMSM)、请求事件函数(OSSemPend、OSMutex-Pend、OSMboxPend、OSFlagPend或OSEventPendMulti)或任务挂起函数(OSTaskSus-pend)时,该任务进入等待延时、事件或任务恢复的等待态。当处于等待态的任务等待超时(OSTimeTick)、等待延时取消(OSTimeDlyResume)、事件被释放(OSSemPost、OSMutexPost、OSMboxPost、OSMboxPostOpt、OSMboxPostFront、OSFlagPost)、请求事件取消(OSSemPendAbort、OSMboxPendAbort、

7、OSQPendAbort)或任务恢复(OSTaskResume)时,任务由等待态进入到就绪态中。6.16.1C/OS-C/OS-用户任务用户任务在项目ZLX01的基础上,新建项目ZLX06,保存在目录D:ZLXLPC824ZLX06中。将项目ZLX02的文件systick.c和systick.h(位于D:ZLXLPC824ZLX02BSP目录下)复制到目录D:ZLXLPC824ZLX06BSP下。然后,新建文件task01.c和task01.h,保存在目录D:ZLXLPC824ZLX06User下。最后,从网站上下载C/OS-系统文件和移植文件,保存在目录D:ZLXLPC824ZLX06uCO

8、S_中。项目ZLX06-的目录与文件结构如表6-2和图6-2所示。表表6-26-2项目项目ZLX06ZLX06的目录与文件结构的目录与文件结构图图6-26-2请看下页请看下页6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁图图6-26-2项目项目ZLX06ZLX06文件结构文件结构6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁结合表6-2和图6-2可知,项目ZLX06包括6个子目录,依次为User、BSP、COS_、RTE、Listings和Objects,分别用于保存用户编写的应用程序、板级支持包、C/OS-系统相关的文件、CMSIS

9、库文件、编辑链接生成的列表文件以及编辑链接生成的目标文件。这些文件中,User和BSP子目录下的文件需要用户编写,COS_目录下的文件来自Micrium官网,而其余子目录下的文件均由Keil MDK自动生成。图6-2给出了项目ZLX06的文件结构,底层为LPC824学习板,核心为LPC824微控制器,属于硬件部分;与硬件部分直接关联的为移植文件和CPU相关的文件,这里的移植文件为C/OS-针对LPC824的一些堆栈操作和任务切换操作;CPU相关的文件包括LPC824的异常与中断信息等,此处为startup_LPC82x.s等文件。C/OS-移植文件之上为C/OS-系统文件和配置文件,C/OS-

10、配置文件用于根据用户需要的功能裁剪C/OS-系统组件。图6-2最上层为应用程序层,应用程序调用C/OS-系统的函数创建任务完成特定的功能。CMSIS库和BSP板级支持包提供了应用程序直接访问底层硬件的函数,板级支持包是电路板外设的驱动程序包,对于一些常用的开发板,例如LPC824学习板而言,都有工程师专门定制的BSP包,也可以从网上下载到,本书为了叙述方便,BSP包是自己动手制作的。6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁现在,将task01.c文件添加到工程LPC824PRJ的USER分组下,将systick.c文件添加到BSP分组下,将文件ucos_.c

11、和os_dbg.c添加到C/OS-分组下,将app_hooks.c文件添加到C/Config分组下,将文件os_cpu_c.c和os_cpu_a.s添加到uC/Port分组下,完成后的项目ZLX06如图6-3所示。图图6-36-3项目项目ZLX06ZLX06工作界面工作界面6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁 项目ZLX06实现的功能与ZLX01相同,即实现LED灯D9按1Hz的频率闪烁,工作流程如图6-4所示。图图6-46-4项目项目ZLX06ZLX06工作流程工作流程6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁在图6-

12、4中,初始化C/OS-系统(调用OSInit函数)后,将自动创建3个系统任务,即空闲任务、统计任务和定时器任务,优先级依次为26、25和24。C/OS-要求至少要创建一个用户任务,这里创建了用户任务task01,优先级号为4。在C/OS-系统调度器的管理下,这4个任务的就绪情况为:用户任务task01每延时1秒就绪一次、空闲任务始终就绪、定时器任务每0.1秒就绪一次、统计任务每0.1秒就绪一次。当4个任务同时就绪时,C/OS-将使优先级最高的任务,即优先级号为4的用户任务task01得到CPU使用权去执行;当任务task01、定时器任务和统计任务均不就绪时,C/OS-系统将使空闲任务占用CPU

13、执行。在C/OS-系统调度器的作用下,用户任务task01每延时1秒执行一次,每次执行时使LED灯D9闪烁。相对于项目ZLX01和ZLX02而言,这里添加了文件task01.c和task01.h,并修改了main.c、includes.h和systick.c文件,这些文件分别如程序段6-3至程序段6-7所示。用户工程配置文件app_cfg.h和用户钩子文件app_hooks.c分别如程序段6-8和程序段6-9所示。其余文件均可以直接从Micrium官网下载。程序段程序段6-3 task01.c6-3 task01.c文件文件1/Filename:task01.c 23#includeinclu

14、des.h 46.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁5 void Task01(void*data)6 7 data=data;89 SysTickInit();1011 OSStatInit();12 while(1)13 14 OSTimeDlyHMSM(0,0,1,0);15 LEDBlink();16 17 本书中,用任务函数名作为任务名,第517行为任务Task01的函数体,第7行无实质含义,可避免因data参量没有使用而产生的编译警告。第9行配置SysTick定时器定时中断频率为100Hz,SysTick定时器定时中断用作C/OS-的系统节拍。

15、对于LPC824而言,系统节拍频率建议为50Hz200Hz,本书中统一采用100Hz。第11行初始化统计任务,当使用统计任务统计CPU利用率和各个用户任务的堆栈时,此行必不可少。第1216行为任务的无限循环体,第14行调用延时函数OSTimeDlyHMSM延时1秒,该函数的4个参数依次为时、分、秒和毫秒;第15行使LED灯D9闪烁。6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁程序段程序段6-4 task01.h6-4 task01.h文件文件 1/Filename:task01.h 23#ifndef_TASK01_H 4#define_TASK01_H 56#

16、define Task01StkSize80 7#define Task01ID1 8#define Task01Prio(Task01ID+3)910 void Task01(void*);1112#endif在文件task01.h中宏定义任务Task01的堆栈大小、任务ID号和任务优先级号,这里定义任务Task01的堆栈大小为80,任务ID号为1(无实质含义),任务优先级号为4(见第68行)。第10行给出了文件task01.c中的任务函数Task01的声明。6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁程序段程序段6-5 main.c6-5 main.c文件文

17、件 1/Filename:main.c 23#includeincludes.h 45 OS_STK Task01StkTask01StkSize;67 int main(void)8 9 BSPInit();1011 OSInit();12 OSTaskCreateExt(Task01,13(void*)0,14&Task01StkTask01StkSize-1,15 Task01Prio,16 Task01ID,6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁17&Task01Stk0,18 Task01StkSize,19 (void*)0,20 OS_TAS

18、K_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);21 OSStart();22 当使用嵌入式实时操作系统C/OS-时,main.c文件的结构非常固定。一般,在文件头部定义第一个用户任务Task01的堆栈Task01Stk(第5行),长度为Task01StkSize(宏常量,80)。然后,第9行调用BSPInit对LPC824及其外设进行初始化。接着,第1121行为启动C/OS的三步曲:即初始化C/OS-(第11行)、创建第一个用户任务(第1220行)、开启多任务(第21行),这部分代码格式是固定的。第1220行为一条C语句,调用OSTaskCreateExt函数创建第一个

19、用户任务Task01(本书中用任务对应的函数名表示任务),9个参数依次为:任务函数名Task01、任务函数参数为空、任务堆栈栈顶指向地址&Task01Stk79、任务优先级号Task01Prio(宏常量,4)、任务ID号(宏常量,1)、任务堆栈栈底指向地址&Task01Stk0、堆栈长度Task01StkSize(宏常量,80)、任务访问外部空间的指针为空、任务进行堆栈检查且堆栈空间清0。main.c文件在后续项目中其代码保持不变,将不再列出。6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁程序段程序段6-6 includes.h6-6 includes.h文件文件

20、 1/Filename:includes.h 23#includeLPC82x.h 45#includedatatype.h 6#includebsp.h 7#includeled.h 8#includesystick.h 910#includeucos_.h 1112#includetask01.h对比程序段3-2,这里添加了第8、10和12行,第8行为SysTick定时器的头文件,第10行为C/OS-操作系统的头文件,第12行为用户任务Task01的头文件。6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁程序段程序段6-7 systick.c6-7 systic

21、k.c文件文件 1/Filename:systick.c 23#includeincludes.h 45 void SysTickInit(void)6 7 SysTick-LOAD=300000-1;8 SysTick-VAL=0;9 SysTick-CTRL=(1uL0)|(1uL1)|(1uL2);10 对比程序段4-1,这里仅保留了SysTickInit函数,用于配置SysTick定时器中断的工作频率为100Hz,而SysTick定时器中断服务函数SysTick_Handler位于移植文件os_cpu_c.c中,不需要用户编写。6.26.2C/OS-C/OS-程序框架与程序框架与LED

22、LED灯闪烁灯闪烁程序段程序段6-8 app_cfg.h6-8 app_cfg.h文件文件 1/Filename:app_cfg.h 23#includeos_cfg.h45#define OS_TASK_TMR_PRIO(OS_LOWEST_PRIO-2)文件app_cfg.h在C/OS-系统中用于定义用户任务的相关信息,相当于task01.h文件的作用,但是,大部分专家,都只是用该文件宏定义定时器任务的优先级号,如第5行所示,而自己编写与任务文件同名的头文件来定义用户任务的信息。如果工程中不使用软定时器,则该文件内容为空(但文件必须存在)。6.26.2C/OS-C/OS-程序框架与程序框架

23、与LEDLED灯闪烁灯闪烁程序段程序段6-9 app_hooks.c6-9 app_hooks.c文件文件 1/Filename:app_hooks.c 23#includeincludes.h 45 void OSTCBInitHook(OS_TCB*ptcb)6 7 ptcb=ptcb;8 在app_hooks.c文件中,第58行定义了钩子函数OSTCBInitHook。该函数在ucos_.h中声明的,这里只需要给出该函数的定义,第7行可避免编译器出现ptcb没有引用的警告。现在,回到图6-3,编译链接并运行项目ZLX06,可见LED灯D9每秒闪烁一次,与项目ZLX01的功能相同,但是在Z

24、LX06中LED灯的闪烁周期是准确的1秒。6.26.2C/OS-C/OS-程序框架与程序框架与LEDLED灯闪烁灯闪烁项目ZLX06编译链接成功后将生成两个目标文件,即LPC824RPJ.axf和LPC824PRJ.hex,这两个目标文件包含相同的可执行代码,只是它们的存储格式不同,它们都位于目录D:ZLXLPC824ZLX06Objects下。基于KeilMDK集成开发环境在线仿真或直接向LPC824芯片下载的目标文件是LPC824PRJ.axf。本节介绍通过FlashMagic软件借助串口向LPC824芯片下载目标代码的方法,此时使用的目标文件为LPC824PRJ.hex。从 6.46.4

25、串口通信串口通信由图6-8可知,主时钟经UARTCLKDIV寄存器(表2-12第13号)分频后,再经分数分频寄存器UARTFRGMULT(表2-12第20号)和UARTFRGDIV(表2-12第19号)分频后得到波特率发生器的时钟源信号U_PCLK,再经波特率发生器内部分频器分频后得到波特率。这样产生的波特率控制发送器和接收器的串行数据传输速率。此外,当工作在同步串行模式下时,U_PCLK也用于产生同步时钟信号。当工作在异步串行模式下时,仅需用到U0_RXD和U0_TXD管脚,U0_CTS和U0_RTS不使用。USART模块的工作时钟为系统时钟,通过写“发送保持寄存器”向外部发送串行数据,通过

26、读“接收缓冲寄存器”接收外部输入的串行数据。6.46.4串口通信串口通信下面先列出USART02的寄存器,如表6-3所示(USART0、USART1和USART2的寄存器相同,只是基地址不同);然后,在此基础上接着讨论串口波特率的设定方式。表表6-36-3USART0USART02 2寄存器寄存器(USART0(USART0基地址基地址:0 x4006 4000,USART1:0 x4006 4000,USART1基地址基地址:0 x4006 8000,USART2:0 x4006 8000,USART2基地址基地址:0 x4006 C000):0 x4006 C000)6.46.4串口通信串

27、口通信表6-3中各个寄存器的含义如下所示,这里先介绍BRG寄存器,然后再依次介绍其他的寄存器。1)波特率设置方法与BRG寄存器LPC824串口工作在异步模式下的波特率计算公式为:波特率16BRG=主时钟/UARTCLKDIV/(1+UARTFRGMULT/UARTFRGDIV)这里,式中的“BRG”表示表6-3中的寄存器BRG的值,“UARTCLKDIV”、“UART-FRGMULT”和“UARTFRGDIV”分别表示第二章表2-12中同名的寄存器的值。表6-4列出了常用的波特率下上述各个寄存器的配置值,假设主时钟为60MHz。表6-4中所列出的针对波特率为9600b/s、19200b/s和3

28、8400b/s的寄存器设定值,可以得到相应的准确的波特率;针对57600b/s和115200b/s的寄存器设定值,得到的相应的波特率有小于0.2%的误差,不影响串行数据的正确传输。表表6-46-4常用波特率下常用波特率下UARTCLKDIVUARTCLKDIV、UARTFRGMULTUARTFRGMULT、UARTFRGDIVUARTFRGDIV和和BRGBRG的值的值6.46.4串口通信串口通信6.46.4串口通信串口通信2)CFG寄存器CFG寄存器各位的详细含义如表6-5,其中第0位为USART有效位,在配置USART波特率发生器寄存器BRG前,必需清零该位,即关闭USART,配置完BRG

29、后,再向该位写1打开USART。由表6-5可知,如果设置USART0工作在异步串行模式下,数据长度为8位,停止位为1位时,可使用语句:CFG=(1uL0)|(1uL2);由表6-5可知,LPC824串口内部接收和发送端集成了反相器,可以接收或发送反相后的信号。表表6-56-5CFGCFG寄存器各位的含义寄存器各位的含义6.46.4串口通信串口通信6.46.4串口通信串口通信3)CTL寄存器USART控制寄存器CTL各位的含义如表6-6所示。根据表6-6,当USART0工作在异步串行模式下时,CTL寄存器保持默认值即可。表表6-66-6CTRCTR寄存器各位的含义寄存器各位的含义6.46.4串口

30、通信串口通信4)STAT寄存器USART状态寄存器STAT各位的含义如表6-7所示。表6-7反映了USART的工作状态。通过读取STAT寄存器的某些位了解USART的工作情况,例如,读出STAT的第3位TXIDLE,如果该位为1表示发送器空闲,可以向发送保持缓冲区写入数据;如果读出0表示发送器忙,则可以通过循环读出TXIDLE的值,直到其为1后,再向发送保持缓冲区写入数据。表表6-76-7STATSTAT寄存器各位的含义寄存器各位的含义6.46.4串口通信串口通信6.46.4串口通信串口通信5)INTENSET寄存器INTENSET寄存器用于开放USART的各种类型中断,向某个寄存器位写入1打

31、开相应的中断,写入0无效。INTENCLR寄存器用于清零INTENSET寄存器的各位,通过向INTENCLR的某位写入1,则清零INTENSET对应位置的位。当读出INTENSET某位的值为1时,说明相应的中断有效;如果读出0,表示相应的中断关闭。INTENSET寄存器如表6-8所示。表表6-86-8INTENSETINTENSET寄存器各位的含义寄存器各位的含义 6.46.4串口通信串口通信6)INTENCLR寄存器INTENCLR寄存器的各位与INTENSET寄存器的各位一一对应,向INTENCLR中某一位写入1,将清零INTENSET中对应位置的位。INTENCLR寄存器如表6-9所示。

32、表表6-96-9INTENCLRINTENCLR寄存器各位的含义寄存器各位的含义6.46.4串口通信串口通信7)RXDAT和TXDAT寄存器RXDAT和TXDAT寄存器均只有第8:0位域有效,分别用于保存新接收到的数据和将要发送的数据。8)RXDATSTAT寄存器RXDATSTAT寄存器的作用与RXDAT寄存器相同,用于保存新接收到的数据,RXDATSTAT寄存器的第8:0位相当于RXDAT寄存器的第8:0位,此外,RXDAT-STAT还包含了接收器的状态标志位,如表6-10所示。表表6-106-10RXDATSTATRXDATSTAT寄存器各位的含义寄存器各位的含义6.46.4串口通信串口通

33、信9)INTSTAT寄存器INTSTAT寄存器反映了USART中断的情况,如果某一位为1,则相应的中断处于请求状态;如果为0表示相应的中断没有发生。INTSTAT寄存器各位的含义如表6-11所示。表表6-116-11INTSTATINTSTAT寄存器各位的含义寄存器各位的含义 6.46.4串口通信串口通信 通过表6-3及其各个寄存器的介绍可知,如果令USART0工作在异步串行模式下,需要做的工作有以下几步:(1)清零CFG寄存器的第0位,关闭串口0。(2)配置BRG寄存器,使串口0工作在所需要的波特率下。这时可借助于表6-4。(3)设置CFG寄存器为(1uL0)|(1uL2),即使串行数据字长

34、为8位,并打开串口。(4)读出STAT寄存器的第3位TXIDLE,如果该位为1,则向TXDAT寄存器写入要发送的字符数据。(5)一般接收串口数据通过串口中断,此时,需要设置INTENSET寄存器的第0位为1;在串口中断服务程序中判断INTSTAT寄存器的第0位RXRDY是否为1,如果为1,则读RXDAT寄存器中的数据。6.46.4串口通信串口通信6.4.26.4.26.4.26.4.2串口通信工程串口通信工程串口通信工程串口通信工程在项目ZLX06的基础上,新建项目ZLX07,保存在目录D:ZLXLPC824ZLX07下,此时的项目ZLX07与项目ZLX06相同。然后,删除目录D:ZLXLPC

35、824ZLX07BSP下的led.c和led.h文件,并从工程分组BSP下移除led.c文件。接着,新建文件uart.c和uart.h,保存在目录D:ZLXLPC824ZLX07BSP下,并把uart.c文件添加到工程分组BSP下。最后,修改文件includes.h、bsp.c和task01.c。完成后的项目ZLX07如图6-9所示。图图6-96-9项目项目ZLX07ZLX07工作界面工作界面 6.46.4串口通信串口通信在计算机中打开串口调试助手软件,然后,在图6-9所示界面上,编译链接并运行项目ZLX07,串口调试助手将显示如图6-10所示信息。图图6-106-10串口调试助手显示的项目串

36、口调试助手显示的项目ZLX07ZLX07运行信息运行信息 6.46.4串口通信串口通信项目ZLX07的执行流程如图6-11所示。图图6-116-11项目项目ZLX07ZLX07的执行流程的执行流程6.46.4串口通信串口通信从图6-11中可知,项目ZLX07中包含4个任务,即用户任务task01(优先级号为4)、定时器任务(优先级号为24)、统计任务(优先级号为25)和空闲任务(优先级号为26)。任意时刻C/OS调度器都将从上述4个任务中找出优先级最高的就绪的任务去执行。用户任务task01每3秒就绪一次,由于用户任务task01的优先级最高,一旦task01就绪,则C/OS调度器将使得tas

37、k01得到CPU使用权。用户任务task01执行时首先通过串口向计算机发送C/OS版本信息,接着,启动SysTick定时器,然后进入无限循环体,每延时3秒向上位机串口调试助手输出信息“running.”。在用户任务task01延时等待的过程中,C/OS调度器将从其他就绪的任务中找出优先级最高的任务去执行。6.46.4串口通信串口通信统计任务具有两个作用,其一为统计CPU使用率,其二为统计各个任务的堆栈使用情况,不但可以统计用户任务的堆栈使用情况,也可以统计系统任务(包括统计任务本身)的堆栈使用情况。本节将通过工程实例介绍统计任务的用法。在项目ZLX07的基础上,新建项目ZLX08,保存在目录D

38、:ZLXLPC824ZLX08下,此时的项目ZLX08与ZLX07相同,只需要修改文件task01.c,其代码如程序段6-15所示。程序段程序段6-15task01.c6-15task01.c文件文件1/Filename:task01.c 23#includeincludes.h 45 void Task01(void*data)6 7 Int16Uver;8 OS_STK_DATA StkData;9 INT8Ui,u,h;10 INT32Uj,v;11 6.56.5统计任务实例统计任务实例12 data=data;1314 ver=OSVersion();15 SendString(Int

39、08U*)uC/OS_ Version:);16 SendChar(0+ver/100);17 SendChar(.);18 SendChar(0+(ver/10)%10);19 SendChar(0+ver%10);20 SendChar(n);2122 SysTickInit();2324 OSStatInit();2526 OSCtxSwCtr=0;27第26行的OSCtxSwCtr变量是C/OS-定义的变量,用于保存任务切换的总次数,这里为了计算每秒任务切换的次数,所以,先将它初始化为0。6.56.5统计任务实例统计任务实例28 while(1)29 30 OSTimeDlyHMSM(

40、0,0,3,0);3132 SendString(INT8U*)Tasks:);33 j=100;34 h=0;35 v=OSTaskCtr;36 for(i=1;i=3;i)37 38 u=v/j;39 v=v-u*j;40 if(u0|h0)41 42 h=1;43 SendChar(0u);44 45 j=j/10;46 47 SendString(INT8U*).t);486.56.5统计任务实例统计任务实例第3247行向上机位输出工程中的任务总数,第35行的变量OSTaskCtr为系统变量,保存了工程中总的任务个数。第3646行的代码用于由高位向低位依次得到OSTaskCtr变量的各

41、个数位上的数字,并从第一个不为零的数开始,将获得的数字转化为字符输送到上位机串口调试助手显示出来。下面第49132行使用了同样的方法将整数转化为字符,这种方法比调用sprintf函数而言占用空间少且运行速度更快。49 SendString(INT8U*)TasksSwitches:);50 j=1000;51 h=0;52 v=OSCtxSwCtr/3;53 for(i=1;i=4;i)54 55u=v/j;56v=v-u*j;57 if(u0|h0)58 59 h=1;6.56.5统计任务实例统计任务实例60 SendChar(0u);61 62 j=j/10;63 64 SendStrin

42、g(INT8U*).t);65 OSCtxSwCtr=0;66第4965行为向上位机输出工程执行过程中每秒任务的切换次数。第52行的OSCtxSwCtr为C/OS-系统变量,用于记录任务的总的切换次数,由于第26行和第65行将其清为零,所以,这里的OSCtxSwCtr为3秒内的任务切换次数,第52行中OSCtx-SwCtr/3即为每秒的任务切换次数。67 SendString(INT8U*)CPUUsage:);68 j=100;69 h=0;70 v=OSCPUUsage;71 for(i=1;i=3;i)72 73 u=v/j;74 v=v-u*j;75 if(u0|h0)6.56.5统计

43、任务实例统计任务实例76 77 h=1;78 SendChar(0u);79 80 j=j/10;81 82 SendChar(%);83 SendChar(n);84第6783行用于向上位机输出CPU利用率。第70行的OSCPUUsage为C/OS-系统变量,用于保存工程中用户任务的执行时间占全部CPU时间的百分比,取值为0100。第7181行将OSCPUUsage转化字符输出到上位机。85 OSTaskStkChk(OS_PRIO_SELF,&StkData);函数OSTaskStkChk用于获得任务的堆栈使用信息,有两个参数,第一个参数为任务的优先级号,如果取为OS_PRIO_SELF,

44、表示读取当前任务的堆栈信息;第二个参数为OS_STK_DATA类型的结构体变量,定义在第8行。这样,StkData.OSUsed表示已使用的堆栈大小,StkData.OSFree表示空闲的堆栈大小,以字节为单位。6.56.5统计任务实例统计任务实例86 SendString(INT8U*)TaskNo.:);87 j=100;88 h=0;89 v=Task01Prio;90 for(i=1;i=3;i)91 92 u=v/j;93 v=v-u*j;94 if(u0|h0)95 96h=1;97 SendChar(0u);98 99 j=j/10;100 101 SendString(INT8

45、U*).t);第86101行向上位机输出任务的优先级号,第89行的Task01Prio为任务Task01的优先级号,宏定义在task01.h文件中。6.56.5统计任务实例统计任务实例102 SendString(INT8U*)StackUsed:);103 j=1000;104 h=0;105 v=StkData.OSUsed;106 for(i=1;i=4;i)107 108 u=v/j;109 v=v-u*j;110 if(u0|h0)111 112 h=1;113 SendChar(0u);114 115 j=j/10;116 117 SendString(INT8U*).tt)第10

46、2117行向上位机输出任务Task01使用的堆栈大小,第105行的StkData.OSUsed表示已经使用的堆栈大小,单位为字节。6.56.5统计任务实例统计任务实例118 SendString(INT8U*)StackFree:);119 j=1000;120 h=0;121 v=StkData.OSFree;122 for(i=1;i=4;i)123 124 u=v/j;125 v=v-u*j;126 if(u0|h0)127 128 h=1;129 SendChar(0u);130 131 j=j/10;132 133 SendString(INT8U*)nn);134 135第1181

47、33行向上位机输出任务Task01未使用的堆栈大小,第121行的StkData.OSFree表示未占用的堆栈大小,单位为字节。6.56.5统计任务实例统计任务实例项目ZLX08的运行结果如图6-12所示。图图6-126-12串口调试助手显示结果串口调试助手显示结果由图6-12可知,项目ZLX08中共有4个任务,即用户任务Task01、定时器任务、统计任务和空闲任务。任务切换次数为每秒30次(只有4个任务,用户任务每3秒切换1次、定时器任务每秒切换10次、统计任务每秒切换10次,空闲任务每秒切换10次,总切换次数约为每秒30次),CPU利用率为1%,用户任务Task01(优先级号:4)的堆栈用了144B,空闲176B。6.56.5统计任务实例统计任务实例项目ZLX08的用户任务Task01的运行流程如图6-13所示。由图6-13可知,每3秒用户任务通过串口向上位机串口调试助手输出工程中的任务总数、每秒任务切换次数、CPU利用率以及任务Task01的堆栈使用情况等信息。图图6-136-13用户任务用户任务Task01Task01运行流程运行流程6.56.5统计任务实例统计任务实例

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高等教育

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:文库网官方知乎号:文库网

经营许可证编号: 粤ICP备2021046453号世界地图

文库网官网©版权所有2025营业执照举报