嵌入式系统第八章 嵌入式实时操作系统cos -ii_第1页
嵌入式系统第八章 嵌入式实时操作系统cos -ii_第2页
嵌入式系统第八章 嵌入式实时操作系统cos -ii_第3页
嵌入式系统第八章 嵌入式实时操作系统cos -ii_第4页
嵌入式系统第八章 嵌入式实时操作系统cos -ii_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

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

文档简介

1、8.1 嵌入式操作系统概述 嵌入式操作系统(EOS):在嵌入式系统环境下运行的操作系统。嵌入式操作系统的功能: 进程管理 存储管理 I/O设备管理 文件管理第8章 嵌入式实时操作系统 C/OS -II常见的嵌入式操作系统 VxWorks 目前较好的商业操作系统 Linux 当今最重要开源免费操作系统 uCOS-II 最适合学习的操作系统 WinCE 微软开发的一个Windows兼容 操作系统1、C/OSMicro Controller O S, (微控制器操作系统)美国人Jean Labrosse 1992年完成应用面覆盖了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路 系统、自

2、动提款机等 1998年C/OS-II,目前的版本C/OS2000年,得到美国航空管理局(FAA)的认证,可以用于飞行器中8.2 COS简介公开源代码可移植性好 绝大部分 C/OS-II的源码是用移植性很强的ANSI C写的。只有和微处理器硬件相关的那部分是用汇编语言写的,使得 C/OS-II便于移植到其他微处理器上。可固化 C/OS-II是为嵌入式应用而设计的,这就意味着,只要有固化手段(C编译、连接、下载和固化), C/OS-II可以嵌入到读者的产品中成为产品的一部分。2. C/OS的特点:可裁剪 可以只使用 C/OS-II中应用程序需要的那些系统服务。也就是说某产品可以只使用很少几个 C/

3、OS-II调用,而另一个产品则使用了几乎所有 C/OS-II的功能,这样可以减少产品中的 C/OS-II所需的存储器空间(RAM和ROM)。这种可剪裁性是靠条件编译实现的。占先式内核 总是让优先级最高的就绪任务处于运行状态多任务管理 C/OS-II可以管理64个任务,然而,目前这一版本保留8个给系统。应用程序最多可以有56个任务可确定性好 全部 C/OS-II的函数调用与服务的执行时间具有可确定性。任务栈每个任务有自己单独的栈, C/OS-II允许每个任务有不同的栈空间,以便压低应用程序对RAM的需求。系统服务C/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与

4、释放、时间相关函数等。中断管理中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。稳定性与可靠性好3. C/OS-II提供的系统服务任务管理信号量任务间无冲突共享资源的方式消息信箱任务间传递单个数据的方式消息队列任务间传递多个数据的方式事件任务间进行通信的方式内存管理时钟管理的结构 应用软件 uCOS II 的系统服务 (与处理器无关的代码) u OS_MBOX.C u OS_MUTEX.C OS uCOS II的设置 (与应用相关代码) uCOS-II 的移植(与处理器相关的代码) CPU 时钟软件硬件1

5、. 任务的基本概念COS-II的任务是一个线程,就是用来解决应用问题的C语言函数和与之关联的数据结构而构成的一个实体。 COS-II的任务一般由任务程序代码、任务堆栈、 任务控制块三部分构成。 C/OS版本支持64个任务,每个任务有 一个特定的优先级(是0-63之间的数,用符号 Prio代表)。优先级越高,数字越小。8.3 COS-II中的任务任务的构成任务的链表任务控制块任务的代码任务的堆栈2. 任务的五种状态任务用户任务由用户定义的任务系统任务由操作系统定义的任务,例如空闲 任务,当无用户任务时操作系统调 用该任务。 COS-II有8个系统任务。3. 任务的类型典型的任务一个无限循环。vo

6、id mytask(void *pdata) /定义任务 for (;) 可以中断的用户代码 ; OS_ENTER_CRITICAL() ;/关中断 不可以中断的用户代码 ; OS_EXIT_CRITICAL();/开中断 可以中断的用户代码 ; 4. C/OS-II的任务代码与应用程序的一般结构(1)任务(task)代码的一般结构(2)用户应用程序的一般结构Void Mytask1 (void*pdata) /定义任务1 for(; ;) Void Mytask2 (void*pdata) /定义任务2 for(; ;) /定义N个任务void main ( ) /主函数 OSInit (

7、) ; / uCOS-II 初始化 OSTaskCreate (MyTask1, &MyTask1Agu,) ; /创建任务1 OStaskCreate (MyTask2, &MyTask1Agu ,) ; /创建任务2 /创建任务N OSStart ( ) ; /启动任务 注意:用户的主函数main( )程序只负责创建任务和启动任务, 而由操作系统负责调度运行它们5. C/OS-II的任务堆栈每个任务为了进行任务切换与响应中断时保护现场的需要都要定义自己的堆栈。例:#define STACKSIZE 64 /定义任务堆栈的大小OS_STK Task1_Stack STACKSIZE; /用数

8、组作为堆栈OS_STK Task1_Stack STACKSIZE=0;/堆栈赋初值(1)任务堆栈的定义6. C/OS-II的任务控制块及任务控制块链表任务控制块 OS_TCB是一个数据结构,保存该任务的相关参数,包括任务堆栈指针,状态,优先级,任务表位置,任务链表指针等。 C/OS-II用控制链表来管理任务控制块。 在调用C/OS-II的初始化函数OSInit( ) 进行初始化时建立空任务链表被建立(所 有的任务控制块还没分配任务); 在调用函数OSTaskCreate( )创建任务时 给空任务链表赋值,既给任务控制块分配 任务。COS-II是采用占先式算法来调度任务的,优先级最高的任务一旦

9、准备就绪,则拥有CPU的所有权开始投入运行。任务就绪的判断是依据任务就绪表进行。7. C/OS-II的任务调度多任务操作系统的一项重要任务就是对任务的调度,所谓调度就是通过一种算法在多个任务中确定哪个任务来运行。任务的调度要完成两项工作,一是在任务就绪表中查找具有最高优先级别的就绪任务;二是实现任务的切换,这些工作是由COS-II的函数OSSched( )来实现的。8. C/OS-II任务的创建COS-II提供两个创建任务函数:一个是普通创建任务函数 OSTaskCreate( );另一个是扩展创建任务函数 OSTaskCreateExt( ),可以使用这两个函数之一来创建任务。创建任务的方法

10、在启动任务之前创建各任务在启动任务之前,先创建一个起始任务,将它赋予最高的优先级,然后再在起始任务中创建其它任务(1)在启动任务之前创建各任务具体应用程序流程 1)头文件# /包含uCOS-II头文件#include “./”/包含uCOS-II附加头文件#include ./inc/drivers.h/包含驱动头文件#include ./inc/sys/lib.h/包含头文件#include /包含C标准库函数文件#include /包含C标准库函数文件例:包含在程序中用到的头文件 2)任务声明定义任务1堆栈任务1函数声明定义任务1的优先权定义任务2堆栈任务2函数声明定义任务2的优先权定义任

11、务N堆栈任务N函数声明定义任务N的优先权OS_STK task1_StackSTACKSIZE=0; /定义任务1堆栈void Task1(void *Id); /任务1函数声明#define Task1_Prio 12 /定义任务1的优先权OS_STK task2_StackSTACKSIZE=0; /定义任务2堆栈void Task2(void *Id); /任务2函数声明#define Task2_Prio 15 /定义任务2的优先权任务声明的例子: 3)定义主函数例:int main (void) ARMTargetInt( );/目标板初始化; OSInit( ) ; /ucos-i

12、i 初始化; OSTaskCreate(任务1名,任务1参数,任务1栈指针, 任务1优先权); OSTaskCreate(任务2名,任务2参数,任务2栈指针, 任务2优先权); OSAddTask_Init(0); /系统任务初始化 OSStart( ); /启动任务 return 0 ; Void Mytask1 (void*pdata) /定义任务1 for(; ;) Void Mytask2 (void*pdata) /定义任务2 for(; ;) 4)定义各任务(2)先建立启动任务的方法Void main (void) /主函数 OSInit( ); /对C/OS-II进行初始化 OS

13、TaskCreate( TaskStart , ); /创建起始任务 OSStart( ); / 启动操作系统任务调度Void TaskStart(Viod *pdata ) /起始任务 /起始任务初始化 OSTaskCreate( Task2 , ); /创建任务2 /创建其它任务 for (; ;) /起始任务的具体代码 例:试在操作系统C/OS-II下创建两个任务, 在C/OS-II管理下运行,要求T1每运行 2次T2运行1次,并将运行的情况传送到 在PC机的超级终端上显示。/*uCOS-II在ARM上多任务应用程序的头文件*/#include./ucos-ii/includes.h /

14、包含uCOS-II头文件#include ./ucos-ii/add/osaddition.h/包含uCOS-II头文件#include ./inc/drivers.h/包含驱动头文件#include ./inc/sys/lib.h/包含/头文件#include /包含C标准库函数文件#include /包含C标准库函数文件#pragma import(_use_no_semihosting_swi) /不使用SWI/*任务定义*/OS_STK T1_StackSTACKSIZE=0; /定义任务1堆栈void T1(void *Id); /任务1函数说明#define T1_Prio 12

15、/定义任务1的优先权OS_STK T2_StackSTACKSIZE=0; /定义任务2堆栈void T2(void *Id); /任务2函数说明#define T2_Prio 15 /定义任务2的优先权/*主函数*/int main(void)ARMTargetInit(); /目标板初始化OSInit(); / uCOS-II初始化OSTaskCreate(T1, (void *)0, (OS_STK *)&T1StackSTACKSIZE-1, T1Prio);/创建任务1OSTaskCreate(T2, (void *)0, (OS_STK *)&T2 StackSTACKSIZE-1

16、, T2 Prio);/创建任务2OSAddTask_Init(0); /系统任务初始化OSStart(); /启动任务return 0; /返回/*定义任务1*/void T1(void *Id) for(;)printf(运行任务1n); /传送并显示运行任务1OSTimeDly(1000); /延时 /*定义任务2*/void T2(void *Id) for(;)printf(运行任务2n); /传送并显示运行任务2OSTimeDly(2000); /延时 1. 基本概念C/OS-II是一多任务管理系统,多任务的协调工作需要解决两个基本问题:(1)多个任务无冲突共享资源(称为任务间的同

17、步问题);(2)任务之间传递数据(称为任务间的通信问题)。使用信号量来解决多个任务无冲突共享资源及任务同步使用消息信箱来实现任务间传递一个(组)数据C/OS-II使用消息队列来实现任务间传递多个(组)数据8.4 任务间的同步与通信2. 信号量信号量表示共享资源被占用情况的标 志信号,在程序中是全局变量。两个任务使用信号量实现无冲突共享资源示意图两个任务使用消息信箱传递数据示意图3. 消息信箱消息信箱为了实现任务间传递数据在内存设置 一个消息缓冲区,用来传递消息缓冲 区指针的数据结构称为消息信箱。两个任务使用消息队列传递数据示意图4. 消息队列消息队列为了实现任务间传递多个数据在内存设置多个消息

18、缓冲区,同时定义一个指针数组,每个数组元素存放一个消息缓冲区指针,这种用来传递多个消息的的数据结构称为消息队列。5.C/OS-II的信号量的操作函数及应用C/OS-II提供了6个对信号量操作函数创建信号量函数OSSemCreate( )请求信号量函数OSSemPend( )无等待请求信号量函数OSSemAccept( )发送信号量函数OSSemPost( )查询信号量当前状态函数OSSemQuery( )删除信号量函数OSSemDel( )C/OS-II的消息邮箱的编程举例试编制信号量演示程序,在一个任务task1中用OSSemPost( )来发送信号量,在另一个任务task2中用OSSemP

19、end()函数来接收信号量,并将信号量显示出来。/*头文件包含*/#include./ucos-ii/includes.h /包含C/OS-头文件#include ./ucos-ii/add/osaddition.h/包含C/OS-头文件#include ./inc/drivers.h ” /包含驱动头文件#include ./inc/sys/lib.h/包含/头文件#include /包含C标准库函数文件#include /包含C标准库函数文件#pragma import(_use_no_semihosting_swi) /不使用SWI /*任务定义*/OS_STK task1_StackS

20、TACKSIZE=0;/定义任务1堆栈OS_STK task2_StackSTACKSIZE=0; /定义任务2堆栈void task1(void *Id);/定义任务1void task2(void *Id);/定义任务2OS_EVENT *sem; /定义信号量事件指针U8 err;/*主函数*/int main()ARMTargetInit(); OSInit();sem=OSSemCreate(1);/创建信号量 OSTaskCreate(task1, (void*)0, (OS_STK*)&task1_StackSTACKSIZE-1,5); OSTaskCreate(task2,(

21、void*)0, (OS_STK*)&task2_StackSTACKSIZE-1,6);OSAddTask_Init(0); OSStart(); return 0; /操作系统管理任务时永不返回,程序结束时返回 /*任务1函数*/void task1(void *Id)/任务1while(1)OSSemPost(sem);/发送信号量printf(t任务1运行,发出信号量n);OSTimeDly(1000);OSTaskDel(5);/删除任务1 /*任务2函数*/void task2(void *Id) U16 value; while(1) value=OSSemAccept(sem)

22、; /查看资源是否可以使用 printf(t任务2运行,接收信号量n); printf(value=%dn,value); OSSemPend(sem,0,&err); /等待接收信号才往下执行任务 OSTimeDly(1000);/延时6.C/OS-II的消息邮箱的操作函数及应用C/OS-II提供了6种消息邮箱操作函数创建消息邮箱函数 OSMboxCreate( )等待消息函数 OSMboxPend( )发送消息函数 OSMboxPost( )无等待地获得消息函数 OSMboxAccept( )查询消息邮箱的状态函数 OSMboxQuery( )删除消息邮箱函数 OSMboxDel( )使用

23、它们就可实现消息邮箱的功能试编制消息信箱演示程序,task0通过OSMboxPost(Come,&buffer)向消息信箱发送消息,然后在task1中通过OSMboxPend接收消息,并将接收到的消息显示出来。C/OS-II的消息邮箱的编程举例#include./ucos-ii/includes.h /包含C/OS-头文件#include ./ucos-ii/add/osaddition.h/包含C/OS-头文件#include ./inc/drivers.h/包含驱动头文件#include ./inc/sys/lib.h/包含/头文件#include /包含C标准库函数文件#include

24、/包含C标准库函数文件#pragma import(_use_no_semihosting_swi) /不使用SWI/*任务定义*/OS_STK task0_StackSTACKSIZE=0;/定义1任务堆栈OS_STK task1_StackSTACKSIZE=0; /定义任务2堆栈void task0(void *dat);/定义任务0void task1(void *dat); /定义任务1OS_EVENT *Come; /定义消息信箱事件指针U8 err;/*主函数*/int main()ARMTargetInit(); OSInit(); Come=OSMboxCreate(void

25、 *)0);/建立消息邮箱OSTaskCreate(task0,(void*)0,(OS_STK *)&task0_StackSTACKSIZE-1,5);/创建任务task0OSTaskCreate(task1,(void*)0,(OS_STK *)&task1_StackSTACKSIZE-1,6);/创建任务task1OSAddTask_Init(0);OSStart();return 0;/*任务0函数*/void task0(void *dat) /任务0 U16 buffer=0 x0FFF;/要发送的信息int i=0;while(1) OSMboxPost(Come,&buff

26、er);/通过消息邮箱发送信息给任务 printf(tTask0 is runningn); OSTimeDly(2000); if(i3) i+; else printf(Task0运行结束,释放任务资源n); OSTaskDel(5);/删除任务0 /*任务1函数*/void task1(void *dat) U16 *msg; U16 c; while(1) msg=OSMboxPend(Come,0,&err);/等待接收邮箱信息 c=*msg; printf(tTask1 is runningn);/获得指针指向的变量 printf(获取到的消息为:%ldn,c); printf(T

27、ask1运行结束,释放任务资源n); OSTaskDel(6);/删除任务1 OSTimeDly(1000); 运行结果:C/OS-在S3C44B0X上的移植一、移植条件 二、移植内容 主要内容1、处理器的C编译器能产生可重入代码 2、用C语言就可以打开和关闭中断 3、处理器支持中断并且能产生定时中断 4、处理器支持容纳一定量数据的硬件堆栈 5、处理器有将堆栈指针和其他CPU寄存 器读出和存储到堆栈或内存中的指令一、移植的条件1、处理器的C编译器能产生可重入代码1)可重入代码指的是可以被多个任务同时调用,但不会破坏数据的一段代码,或者说代码具有在执行过程中打断后再次被调用的能力。2)C/OS-

28、是多任务内核,函数可能会被多个任务调用。所以要完成多任务,代码的可重入性是基础。int temp;void swap (int *x,int*y)temp=*x;*x=*y;*y=temp;void swap (int *x,int*y)int temp;temp=*x;*x=*y;*y=temp;下面列举了两个函数例子,它们的区别在于变量temp保存的位置不同,左边temp作为全局变量存在,右边函数中temp作为函数的局部变量存在,因此左边的函数是不可重入的,而右边的函数是可以重入的。由此可见,在函数中应尽量避免使用全局变量。此外,还需要C编译器的支持,使用Embest IDE的集成开发环境

29、,可以生成可重入的代码。2、用C语言就可以打开和关闭中断uCOS-II在C语言代码中通过使用以下两个宏OS_ENTER_CRITICAL ( ) OS_EXIT_CRITICAL( )打开和关闭中断,从而保护临界代码#define OS_ENTER_CRITICAL() ARMDisableInt()ARMDisableInt: mrs r12, CPSR /* 获取模式寄存器 */orr r12, r12, #I_BIT /* 设置禁止中断位 */msr CPSR_c, r12 /* 设置模式寄存器 */ bxlr3、处理器有将堆栈指针和其他CPU寄存器读出和存储到堆栈或内存中的指令。ARM处理器中汇编指令stmfd可以将所有寄存器压栈,对应也有一个出栈的指令ldmfd。二、uC/OS-II移植内容及步骤移植第一步基本的配置和定义移植第二步移植与处理器相关的汇编代码文件移植第三步移植与处理器相关的标准C代码文件一、定义编译器相关的数据类型四、定义OS_TASK_SW()宏三、定义栈的增长方向 二、定义允许和禁止中断宏typedef unsigned char BOOLEAN;typedef unsigned char INT8U;typedef signed char INT8S;typedef unsign

温馨提示

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

评论

0/150

提交评论