基于uCOS-II的嵌入式应用程序开发.ppt
《基于uCOS-II的嵌入式应用程序开发.ppt》由会员分享,可在线阅读,更多相关《基于uCOS-II的嵌入式应用程序开发.ppt(44页珍藏版)》请在三一办公上搜索。
1、第八章基于C/OS-II的嵌入式应用程序开发,目 录,8.1 嵌入式应用程序开发的特点8.2 C/OS-II应用程序结构分析8.3 C/OS-II程序设计技术 8.4 C/OS-II在ARM微处理器上的移植 8.5 应用程序设计及实例,2,8.1嵌入式应用程序开发的特点,8.1.1 开发调试环境的建立 在嵌入式系统开发中,典型的调试环境一般通常由三部分构成:一是通用计算机(用来运行调试软件,称为调试主机);二是协议转换器(连接调试主机发出的高级命令与微处理器JTAG接口的低级命令之间的接口);三是调试目标。硬件调试环境如下图:,3,8.1嵌入式应用程序开发的特点,8.1.2 基于嵌入式处理器的
2、直接编程技术 如果针对硬件电路直接设计应用程序,那么应用程序的代码必须包括以下几个部分:启动部分:硬件加电后首先运行(硬件检测和资源分配)处理器管理部分:实现处理器状态转换和寄存器使用等 外围设备访问部分:外围设备(如串口)的初始化等 程序功能部分:实现程序所要完成的具体功能 这样设计程序对设计人员的能力要求是很高的。,4,8.1嵌入式应用程序开发的特点,8.1.3 基于嵌入式操作系统的编程技术 随着嵌入式微处理器和程序设计技术的发展,人们把一个大的程序从功能上可划分为三个部分:板级支持包(BSP):其目的是屏蔽下层硬件,主要由Boot Loader和Drivers两部分构成。嵌入式实时操作系
3、统(RTOS)。应用程序:基于相应操作系统、在相应开发环境下设计的并最终运行在相应目标机上的程序。这里,可由掌握不同技术的人去设计不同的部分,并在三部分之间设计相应的接口以供三部分之间相互调用。,5,8.2 C/OS-II应用程序结构分析,下面以一个简单实例来说明基于C/OS-II操作系统设计的嵌入式应用程序的结构。程序清单8.1 两个LED交替闪烁#include“config.h”(1)#define LED1(118)/定义LED1,P1.18控制LED1(2)#define LED2(119)/定义LED2,P1.19控制LED2(3)#define TASK_STACK_SIZE 1
4、28/定义用户任务的堆栈长度(4)OS_STK task1StkTASK_STACK_SIZE;/定义任务LED1的堆栈(5)OS_STK task2StkTASK_STACK_SIZE;/定义任务LED2的堆栈(6)void task1(void*pdata);/LED1任务函数声明(7)void task2(void*pdata);/LED2任务函数声明(8),6,8.2 C/OS-II应用程序结构分析,7,int main(void)/主函数(9)OSInit();/初始化C/OS-II(10)OSTaskCreate(task1,(void*)0,/创建LED1任务(14)/main函
5、数中所调用的OSInit、OSTaskCreate和OSStart,是/C/OS-II操作系统提供的API函数。/main函数并没有直接调用task1和task2,只是在main中调用/OSTaskCreate创建两个任务时分别把task1和task2作为参数。,8.2 C/OS-II应用程序结构分析,8,void task1(void*pdata)/任务LED1函数定义(15)pdata=pdata;/防止出现编译警告(16)TargetInit();/目标板初始化,包括初始化中断系统(17)PINSEL2/延时1/4秒(25),8.2 C/OS-II应用程序结构分析,9,void task
6、2(void*pdata)/任务LED2函数定义(26)pdata=pdata;(27)while(1)/超级循环(28)IO1CLR=LED2;/点亮LED2(29)OSTimeDly(OS_TICKS_PER_SEC/3);/延时1/3秒(30)IO1SET=LED2;/熄灭LED2(31)OSTimeDly(OS_TICKS_PER_SEC/3);/延时1/3秒(32)/task1和task2中的“pdata=pdata;”是防止在编译时出现警告。/task1和task2中调用的OSTimeDly,是C/OS-II提供的API函数。/PINSEL2、IO1DIR 等都是宏定义,代表寄存器
7、地址,给该寄/存器赋值可以实现不同的功能,它们都在(*.h)文件中定义。,8.2 C/OS-II应用程序结构分析,10,上述程序的功能是让2个LED灯以不同的速度闪烁,其执行流程如下图:,8.2 C/OS-II应用程序结构分析,11,关于该程序的执行过程作以下说明:该程序首先从 main函数开始执行,初始化C/OS-II,创建任务task1和task2,最后启动C/OS-II中任务调度程序的执行。任务调度程序、任务task1和task2、空闲任务(C/OS-II中)等的交替执行。当任务调度程序执行后,任务调度程序会选择当前处于就绪态的最高优先级的任务来执行;当正在执行的任务调用延时函数延时时,
8、就会挂起该任务,程序又会执行调度程序来调度其它任务的执行。main函数最后一条语句是 return(0),但程序一直在任务调度程序、任务task1和task2等之间交替执行,永远也不会返回到main函数,所以永远也不会执行return(0)。由以上分析可知,在使用C/OS-II操作系统的嵌入式应用程序中,程序的基本结构除main函数外,还包括一个个任务函数,当然也包括非任务函数。设计程序的任务主要是划分和设计一个个任务函数。,8.3 C/OS-II程序设计技术,8.3.1 任务的划分与设计 任务的特性 任务的基本特性有:动态性、独立性和并发性 任务的动态性是指:在程序的运行过程中,各个任务的状
9、态是动态变化的。这些状态有就绪态、运行态和等待态等。任务的独立性是指:程序中的所有任务在逻辑上都是平等的。它们的执行是由调度程序调度来实现的,这样,在每个任务看来,CPU 为自己独占。任务之间要传输信息时必须通过第三方来完成,如消息邮箱等。任务的并发性是指:所有任务共有一个CPU,但在某一时刻,一个CPU只能运行一个任务。高优先级的任务可以剥夺另一个正在运行的低优先级任务的运行权而进入运行状态。高优先级任务在运行一段时间后必须将自己挂起(如调用延时函数等)以让出CPU而让处于就绪态的低优先级的任务得到执行。这样所有任务的运行时间就会相互重叠,表面上看起来好象同时运行一样。,12,8.3 C/O
10、S-II程序设计技术,任务的划分方法 在进行任务划分时,可以有不同的方案,但其要达到的目标都是一致的。首先要满足系统对“实时性”的要求,其次要使任务数目合理和简化软件系统,最后要降低系统对资源的需求。任务的划分有下列一些基本原则:设备依赖性任务的划分:以CPU为中心,将与各种输入/输出设备相关的功能 分别划分为独立的任务(如键盘任务、显示任务等)。关键任务的划分:“关键性”是指某种功能在应用系统中的重要性。若该功能不能正常实现,将会造成重大影响,如火灾报警中传感器信号的检测。紧迫任务的划分:“紧迫性”是指某种功能必须在规定的时间内得到运行,并在规定的时刻前执行完毕。此外,还有:数据处理任务的划
11、分、功能聚合任务的划分、触发条件相同任务的划分、运行周期相同任务的划分、顺序操作任务的划分等原则。这些原则只是一般性原则,设计任务时必须具体问题具体分析。,13,8.3 C/OS-II程序设计技术,任务函数的代码结构 在任务函数中,必须至少调用一次操作系统的服务函数,否则低优先级的任务将永远无法得到运行。按照执行方式可以将任务函数的结构分为三类。单次执行的任务:此类任务在创建后只执行一次,执行结束后即自行删除。其任务函数的代码结构如下:void MyTask(void*pdata)/单次执行的任务函数 进行准备工作的代码;任务实体代码;调用任务删除函数;/调用OSTaskDel(OS_PRIO
12、_SELF)“进行准备工作的代码”完成各项准备工作,如定义和初始化变量等;“任务实体代码”完成该任务的具体功能,通常包含对系统函数的调用,除若干临界段代码(中断被关闭)外,其它代码均可以被中断,用以保证高优先级的就绪任务能够及时得到运行;“调用任务删除函数”将自己删除。,14,8.3 C/OS-II程序设计技术,周期性执行的任务 此类任务在创建后按一个固定的周期来执行。其任务函数的结构如下:void MyTask(void*pdata)/周期性执行的任务函数 进行准备工作的代码;while(1)/无限循环 任务实体代码;调用系统延时函数;/调用OSTimeDly()或OSTimeDlyHMSM
13、()“调用系统延时函数”使自己挂起,把CPU的控制权交给操作系统,由操作系统(中的调度程序)来调度其它已经就绪的最高优先级的任务运行。当延时时间到后,该周期性任务重新进入就绪状态。,15,8.3 C/OS-II程序设计技术,事件触发执行的任务 此类任务在创建后,很快可以获得运行权,但实体代码的执行需要等待某种事件的发生,在相关事件发生之前,该任务则被C/OS-II挂起。其结构如下:void MyTask(void*pdata)/事件触发执行的任务函数 进行准备工作的代码;while(1)/无限循环 调用获取事件的函数;/如等待信号量等 任务实体代码;“调用获取事件的函数”调用 C/OS-II提
14、供的获取某种事件(如信号量)的函数,来等待另外一个任务(或 ISR)发出的信息,此后该任务处于挂起状态;当另外一个任务(或 ISR)调用了C/OS-II提供的通信函数发出相关信息时,C/OS-II就使该任务进入就绪状态,并且通过任务调度,使该任务的实体代码得到执行。相关事件发生一次,任务实体代码就执行一次。,16,8.3 C/OS-II程序设计技术,8.3.2 任务间的行为同步方法 在实时操作系统 C/OS-II的支持下,系统的整体功能是通过各个任务(包括 ISR)的协同运行来实现的。一个任务的运行,往往需要和其它的任务配合才能达到预期的效果,任务之间的这种配合和协调关系就称为任务间的行为同步
15、。C/OS-II 所提供的控制任务间行为同步的通信手段有:计数信号量、事件标志组、消息邮箱和消息队列。通常使用的行为同步方法有:两个任务之间的单向同步:即一个任务为控制方,它发出控制信息;而另一个任务为被控制方,它获得控制方发出的控制信息后即进入就绪状态。这可使用信号量来实现。,17,8.3 C/OS-II程序设计技术,两个任务之间的双向同步:即两个任务同为控制方和被控制方。在这种情况下,首先一个任务必须为控制方,它发出控制信息后就变为被控制方,此时其需等待另一个任务发出的控制信息后才能继续运行;而另一个任务首先为被控制方,当它获得控制方发出的控制信息后才能运行,并变为控制方。这可使用消息邮箱
16、来实现。一个任务同步多个任务:即一个任务为控制方,它发出控制信息,来控制多个任务的执行。此时可采用具有消息分发功能的通信机制(当然也可采用多个通信工具)来实现。两个以上任务同步一个任务:即多个任务为控制方,它们发出控制信息来控制一个任务的执行。此时可采用“事件标志组”来实现。,18,8.3 C/OS-II程序设计技术,8.3.3 共享资源的同步方法 被两个以上并发程序单元(任务或ISR)访问的资源称为共享资源(如全局变量、外设等)。任务对共享资源进行访问的代码段落称为关键段落。各个任务访问同一共享资源的关键段落必须互斥,才能保障共享资源信息的可靠性和完整性。这种使得不同任务访问共享资源时能够确
17、保共享资源信息可靠和完整的措施称为共享资源同步。实现共享资源同步的方法有:关中断、关调度、使用互斥信号量等。中断有可能会引起任务切换,使某个低优先级的任务挂起,使某个高优先级的任务得到执行。如果这两个任务对同一个共享资源进行访问,这就有可能引起错误的结果。此时可以关闭中断。当共享资源的使用者全部是任务(即不包含ISR)时,就可以采用“关调度”的方法来访问共享资源。关调度可使 C/OS-II的任务调度器停止工作,不能进行任务切换,从而保证关键段落代码的执行不会受到其它任务的干扰。当需要访问的共享资源比较复杂,且访问过程比较费时时,关中断和关调度措施都会严重影响到系统的实时性。当该共享资源的使用者
18、全部是任务(即不包含ISR)时,就可以采用互斥信号量的方法来访问这个共享资源。,8.3 C/OS-II程序设计技术,8.3.4 任务间的数据通信方法 ISR与任务函数在形式上与普通C函数没有什么区别。ISR的运行是由异步事件引起的,任务函数的运行是由C/OS-II中的调度器调度的,它们之间不能直接调用,其数据通信是通过以下几种方法实现的。全局变量:提供数据的任务或ISR向全局变量中写数据,使用数据的任务或ISR从全局变量中读数据,对全局变量的访问必须遵循“共享资源同步”的规则。任务或 ISR向全局变量中写入数据后,并不能通知相关的任务,也就是不能实现“行为同步”。内存数据块:当需要传输的数据量
19、很大时,采用内存数据块来存放这些数据是最方便的。内存数据块是共享资源,也不能用来实现“行为同步”。消息邮箱:当每次发送的数据都要求接收方及时接收时,在数据通信的同时必然发生“行为同步”,此时可使用消息邮箱,并要求接收消息的任务总是在等待消息。消息队列:消息队列是具有“行为同步”功能和缓冲功能的数据通信手段,它与消息邮箱的不同之处是可以存放多条消息。,20,8.4 C/OS-II在ARM微处理器上的移植,所谓移植,就是使一个实时内核能够在某个微处理器或微控制器上运行。C/OS-在设计时就已经充分考虑了可移植性。8.4.1 C/OS-II对处理器的要求 要使C/OS-能正常运行,处理器平台必须满足
20、以下要求:处理器的C编译器能够产生可重入代码。用C语言就可以打开和关闭中断。处理器支持中断,并且能产生定时中断(通常在10至100Hz之间)。处理器支持能够容纳一定量数据(一般是几千字节)的硬件堆栈。处理器有将堆栈指针和其它CPU寄存器读出和存储到堆栈(或内存)的指令。LPC2000系列微控制器(ARM7)可以满足第、和点的要求,所使用的ADS1.2的C编译器可以满足第和点要求。,21,8.4 C/OS-II在ARM微处理器上的移植,8.4.2 C/OS-II移植所涉及的文件 移植C/OS-涉及到三个文件:OS_CPU.H文件 OS_CPU.H文件是操作系统移植头文件。其中包括了用#defin
21、e定义的与处理器相关的常量、宏和数据类型等。其文件结构如下:/数据类型(与编译器相关)typedef unsigned char INT8U;/*无符号8位整数*/typedef unsigned int OS_STK;/*堆栈入口宽度为16位*/与处理器相关的代码#define OS_ENTER_CRITICAL()?/*禁止中断*/#define OS_STK_GROWTH 1/堆栈增长方向:1=向下,0=向上,22,8.4 C/OS-II在ARM微处理器上的移植,OS_CPU_A.ASM文件 OS_CPU_A.ASM是与处理器有关的汇编语言代码文件,主要进行任务切换。它在ADS中的后缀名
22、为“.S”,即文件名为OS_CPU_A.S。其中要求用户编写的四个汇编语言函数为:OSStartHighRdy():C/OS-启动时运行优先级最高的任务 OSCtxSw():任务级的任务切换函数 OSIntCtxSw():中断级的任务切换函数 OSTickISR():时钟中断处理函数 如果用户的编译器支持在 C语言代码中插入汇编语言代码的话,用户就可以将所有与处理器相关的代码放到OS_CPU_C.C文件中,而不必再拥有一些分散的汇编文件。,23,8.4 C/OS-II在ARM微处理器上的移植,OS_CPU_C.C文件 OS_CPU_C.C是移植中要修改的C语言程序文件。其中要求用户编写六个C语
23、言函数:OSTaskStkInit():初始化任务的堆栈结构 OSTaskCreateHook():创建任务钩子函数,允许用户扩展C/OS-功能 OSTaskDelHook():删除任务钩子函数 OSTaskSwHook():任务切换钩子函数 OSTaskStatHook():统计任务钩子函数,用来扩展统计任务的功能 OSTimeTickHook():时钟节拍钩子函数 用户必须编写的唯一函数是OSTaskStkInit(),其它五个钩子函数是用来扩展相应的功能,必须声明但不一定要包含代码。,24,8.4 C/OS-II在ARM微处理器上的移植,8.4.3 C/OS-II的移植过程及内容 移植
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 uCOS II 嵌入式 应用程序 开发

链接地址:https://www.31ppt.com/p-4969468.html