1、,1,嵌入式系统 AnIntroductiontoEmbeddedSystem第十一课 嵌入式实时操作系统 RT-Linux,C/OS浙江大学计算机学院 陈天洲 2011.4.27 2011夏学期,周三下午1-3节,周四晚上1-3节 玉泉曹光彪西501,2,课程大纲, RT-Linux操作系统 实时操作系统C/OS简介 实时操作系统C/OS-II的内核结构 实时操作系统C/OS-II中的中断与任务通讯 实时操作系统C/OS-II在ARM7上的移植 实时操作系统C/OS-III,RTLinux(A Real-Time Linux),新墨西哥矿业及科技学院的V. Yodaiken开发 Fsmlab
2、s公司 finite state machine labs, 有限状态机实验室 两个版本 RTLinux Free:由社区支持的免费版本 RTLinux Pro:FSMLabs的商业版本 没有针对实时操作系统的特性而重写Linux的内核 工作量非常大 难以保证兼容性,3,Linux提供实时性需要解决三个问题,1.关中断问题 Linux处于内核临界区时,中断会被系统屏蔽 如果当前进程正处于临界区,即使它的优先级较低,也会延迟高优先级的中断请求。 2.进程调度问题 内核不可抢占,基于固定时间片的可变优先级调度 3.时钟问题 Linux为了提高系统的平均吞吐率,将时钟中断的最小间隔设置为10ms,不
3、能满足实时任务的需要 由于Linux的进程切换比较费时,把时钟间隔改小,时钟中断变频繁,花在中断处理上的时间就越多,4,RTLinux,支持POSIX.1b标准 不同于微内核和大型内核,属于实时EXE(realtime executive)体系结构。 双核技术:一个微型的RTLinux内核把原始的Linux内核作为它在空闲时的一个线程来运行 在Linux内核与硬件中断之间增加一个精巧的可抢先的实时内核 仅支持底层任务创建、中断服务例程的装人、底层任务通信队列、中断服务例程(ISR)和Linux进程 把标准的Linux内核作为实时内核的一个进程与用户进程一起调度 标准的Linux内核的优先级最低
4、,可以被实时进程抢断 正常的Linux进程仍可以在Linux内核上运行 既可以使用标准分时操作系统即Linux的各种服务 又能提供低延时的实时环境,RT-Linux,一个实时内核负责处理硬件消息,接管中断,实时任务可在该内核上直接运行,RTlinux的中断机制,RTlinux采用在Linux内核和中断控制硬件之间增加一层仿真软件的方法截取所有的硬件中断,将这些中断分成Linux中断和实时中断两类。 if(RTlinux收到实时中断)继续向硬件发出中断; elseif(Linux内核屏蔽它)此中断请求将被忽略;else将其交于Linux内核来处理; 由此可以看出,Linux程序的屏蔽中断( cl
5、i)不能禁止实时中断的发生,实时中断的延迟时间也完全由实时内核的处理速度而决定。,RTlinux的调度机制,任务调度策略 采用完全适应于实时应用的按优先级抢占CPU的调度方法 这种方法保证任何时刻都是优先级最高的任务占用CPU。 优先级最高的任务可以中断当前运行的程序而抢占CPU; 优先级较低的任务,只有在所有优先级比它高的任务都运行完后才能投入运行。 也支持其他的调度策略 EDP算法(截止时限靠前者最先调度) RM算法(周期短者优先级高)等 RTlinux将任务调度器本身设计成一个可装载的内核模块,用户可以根据自己的实际需要,编写适合自己的调度算法,通过软件来模拟硬件的中断控制器 RT-Li
6、nux通过将系统的实时时钟设置为单次触发状态,可以提供十几个微秒级的调度粒度,10,课程大纲, RT-Linux操作系统 实时操作系统C/OS简介 实时操作系统C/OS-II的内核结构 实时操作系统C/OS-II中的中断与任务通讯 实时操作系统C/OS-II在ARM7上的移植 实时操作系统C/OS-III,实时操作系统C/OS简介,1992年美国人Jean Labrosse开发了C/OS 用于照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等诸多应用领域 1998年推出C/OS-II 可以将其用于教学和私下研究 用于商业须许可 目前的版本C/OS -II V2.88 200
7、9年推出C/OS-III 只提供库,不开源 抢先式多任务处理,无数目限制的任务及优先级,时间片轮番调度法允许多任务具有相同的优先级 2000年,得到美国航空管理局(FAA)的认证,可以用于飞行器中 网站www.ucos-II.com(),11,开源代码 可移植性(Portable) C/OS-II源码主要用ANSI C写,移植性很强的。 只有和微处理器硬件相关的那部分直接用汇编语言写的,汇编语言写的部分已经压到最低限度,约200行 C/OS-II可以在绝大多数8位、16位、32位以至64位微处理器、微控制器 、数字信号处理器(DSP)上运行。 可固化(ROMable) C/OS-II是为嵌入式
8、应用而设计的,内核可以裁剪得很小,可以嵌入到任何产品中 最小内核可编译至 2KB 可裁剪(Scalable) 通过条件编译,可以根据应用需要只使用 C/OS-II中的部分那些系统服务。,12,C/OS的性能特点,抢占式(Preemptive)实时结构 多任务 C/OS-II可以管理64个任务,其中保留8个给系统。应用程序最多可以有56个任务 可确定性 全部 C/OS-II的函数调用与服务的执行时间是可确定的。 任务栈 每个任务有自己单独的栈, 允许每个任务有不同的栈空间,以便减少应用程序对RAM的需求。 系统服务 C/OS-II提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申
9、请与释放、时间相关函数等。 中断管理 中断可以使正在执行的任务暂时挂起,如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可达255层。 稳定性与可靠性,13,C/OS的性能特点-2,C/OS-II提供的系统服务,信号量 带互斥机制的信号量 减少优先级倒置的问题 事件标志 消息信箱 消息队列 内存管理 时钟管理 任务管理,14,C/GUI and C/FS,C/GUI 嵌入式的用户界面 用ANSI C书写 支持任何8, 16, 32-bits CPU 彩色,灰、度,等级或黑白显示 代码尺寸小 C/FS 嵌入式的文件系统用ANSI C书写 支持任何8,
10、16, 32-bits CPU 支持SMC, MMC, SD, CF, IDE, Flash, RAM其他介质,15,C/OS-II的商业应用,全世界有数百种产品在应用: Avionics Medical Cell phones Routers and switches High-end audio equipment Washing machines and dryers UPS (Uninterruptible Power Supplies) Industrial controllers GPS Navigation Systems Microwave Radios Instrumenta
11、tion Point-of-sale terminals,16,17,课程大纲, RT-Linux操作系统 实时操作系统C/OS简介 实时操作系统C/OS-II的内核结构 实时操作系统C/OS-II中的中断与任务通讯 实时操作系统C/OS-II在ARM7上的移植 实时操作系统C/OS-III,任务管理中断处理 时间管理任务之间通信与同步,18,C/OS-II的内核结构,C/OS-II的任务(task),C/OS-II中任何工作都是用任务来构成的 典型的任务一个无限循环。 void mytask(void *pdata) for (;) do something;waiting;do somet
12、hing; 每个任务对应一个特定的优先级。优先级越高,任务编号数字越小。 系统占用了8个任务 保留优先级为0、1、2、3、OS_LOWEST_PRIO-3、 OS_LOWEST_PRIO-2、 OS_LOWEST_PRIO-1、 OS_LOWEST_PRIO-0。,19,C/OS-II中任务状态,20,C/OS-II的任务结构(Task Structure),21,任务是一个无限循环,任务完成后自我删除,22,当任务完成以后,任务可以自我删除。 注意任务代码并非真的删除了,C/OS-只是简单地不再理会这个任务了,这个任务的代码也不会再运行,如果任务调用了OSTaskDel(),这个任务绝不返回
13、什么。,运行任务可调用的内核函数,23,延迟一段时间使这个任务进入等待状态: OSTimeDly(),OSTimeDlyHMSM()。 等待的时间过去以后,系统服务函数OSTimeTick()使延迟的任务进入就绪态 运行的任务期待某一事件发生时,可调用以下3个函数之一进入等待: OSSemPend(),OSMboxPend(),或OSQPend()。 调用后任务进入了等待状态(WAITING)。 当任务因等待事件被挂起(Pend),下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。,中断任务,运行的
14、任务是可以被中断的响应中断时,正在执行的任务被挂起,中断服务子程序控制了CPU的使用权 从中断服务子程序返回之前,C/OS-要判定,被中断的任务是否还是就绪态任务中优先级最高的。 如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断了的任务才能继续运行。 空闲任务(idle task) 当所有的任务都在等待事件发生时C/OS-执行OSTaskIdle()函数。,24,任务控制块(Task Control Blocks, OSTCBs),任务控制块 OS_TCB是一个数据结构 保存该任务的相关参数,包括任务堆栈指针,状态,优先级,任
15、务表位置,任务链表指针等。 任一旦任务建立了,任务控制块OS_TCBs将被赋值 任务建立的时候,OS_TCBs被初始化了 当任务的CPU使用权被剥夺时,C/OS-用它来保存该任务的状态。 当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。 OS_TCBs全部驻留在RAM中。 所有的任务控制块分为两条链表,空闲链表和使用链表。,25,任务控制块数据结构 Task Control Blocks, OS_TCBs,26,任务控制块主要结构,Struct os_tcb OS_STK *OSTCBStkPtr;struct os_tcb *OSTCBNext;st
16、ruct os_tcb *OSTCBprev;OS_EVENT *OSTCBEventPtr;void *OSTCBMsg;INT16U OSTCBDly;INT8U OSTCBStat;INT8U OSTCBPrio; INT8U OSTCBX, OSTCBY, OSTCBBitX, OSTCBBitY; OS_TCB,27,事件控制块的指针,任务的状态字,任务延时参数,建立任务的二个服务,OS TaskCreate()OSTaskCreateExt (),28,29,空任务列表,30,所有的任务控制块都被放置在任务控制块列表数组OSTCBTbl中,系统初始化时,所有任务控制块被链接成空任务
17、控制块的单向链表,任务建立后,空任务控制块指针OSTCBFreeList指向的任务控制块就赋给了该任务,然后OSTCBFreeList的值调整为指向链表中的下一个空任务控制块。,任务级的任务调度-OSSched,C/OS是占先式实时多任务内核 优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。C/OS中不支持时间片轮转法 每个任务的优先级要求不一样且是唯一的,所以任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。C/OS任务调度所花的时间为常数,与应用程序中建立的任务数无关,31,根据优先级找到任务在就绪任务表中的位置,32,每个就绪的任务都放入就绪表中(rea
18、dy list)中,就绪表有两个变量:OSRdyGrp、OSRdyTbl,优先级最低任务,(空闲任务),优先级最高任务,任务优先级号,根据优先级确定就绪表(1),假设优先级为12的任务进入就绪状态,12=1100b,则OSRdyTbl1的第4位(bit4)置1,且OSRdyGrp的第1位(bit1)置1,相应的数学表达式为:OSRdyGrp |=0x02;OSRdyTbl1 |=0x10; 而优先级为21的任务就绪21=10 101b,则OSRdyTbl2的第5位置1,且OSRdyGrp的第2位置1,相应的数学表达式为:OSRdyGrp |=0x04;OSRdyTbl2 |=0x20;,33,
19、OSRdyGrp:,OSRdyGrp:,根据优先级确定就绪表(2),从上面的计算我们可以得到:若OSRdyGrp及OSRdyBbl的第n位置1,则应该把OSRdyGrp及OSRdyBbl的值与2n 相”或”。 C/OS中,把2n的n=0-7的8个值先计算好,存在数组OSMapTbl7中,即:OSMapTbl0 =20=0x01(0000 0001)OSMapTbl1 =21=0x02(0000 0010)OSMapTbl7 =27=0x80(1000 0000),34,使任务进入就绪态算法,Prio是优先级编号,也是任务的识别号 任务就绪 将任务号放入就绪表,任务就进入就绪态 其方法是: OS
20、RdyGrp |=OSMapTblprio3; OSRdyTblprio3 |=OSMapTblprio ,35,使任务脱离就绪态算法,将任务就绪表OSRdyTblprio3相应元素的相应位清零, 如果OSRdyTblprio3中的所有位都为零时,即全组任务中没有一个进入就绪态时 OSRdyGrp的相应位才为零。If(OSRdyTblprio3,36,就绪表清”0”,任务调度-根据就绪表确定最高优先级,两个关键: 优先级数分解为高三位和低三位分别确定; 高优先级有着小的优先级号 ;,37,任务调度-根据就绪表确定最高优先级,通过OSRdyGrp值确定高3位 设OSRdyGrp=0x24=100
21、 100b, 对应OSRdyTbl2和OSRdyTbl5 选择高优先级在OSRdyTbl2组内 通过OSRdyTbl2的值来确定低3位,假设为OSRdyTbl2=0x12=010 010b, 对应第2个和第5个任务,取高优先级为2,则最高优先级的任务为28+2-1=17,38,C/OS-II源代码中使用了查表法,查表法具有确定的时间,增加了系统的可预测性,C/OS中所有的系统调用时间都是确定的 High3 =OSUnMapTblOSRdyGrp; Low3 =OSUnMapTblOSRdyTblHigh3; Prio =(Hign33)+Low3;,39,优先级判定表OSUnMapTbl256
22、,INT8U const OSUnMapTbl = 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,
23、0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,6, 0, 1, 0
24、, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 ;,40,举例:如OSRdyGrp的值为01101000B,即0x68,则查得OSUnMapTblOSRdyGrp的值是3,它相应于OSRdyGrp中的第3位置1;如OSRdyTbl3的值是11100100B,即0xE4,则查OSUnMapTb
25、lOSRdyTbl3的值是2,则进入就绪态的最高任务优先级Prio=38+2=26,Task scheduler,41,检查是否中断调用和允许任务调用,找到优先级最高的任务,该任务是否正在运行,任务切换,任务切换,将被挂起的任务寄存器入栈 将较高优先级任务的寄存器出栈,42,任务级的任务切换OS_TASK_SW(),43,通过sc系统调用指令完成 保护当前任务的现场 恢复新任务的现场 执行中断返回指令 开始执行新的任务,调用OS_TASK_SW()前的数据结构,44,低优先级任务OS_TCB,OSTCBCur (1),存贮器低地址,存贮器高地址,堆栈方向,SP,R1,R2,R3,R4,PC,P
26、SW,存贮器低地址,存贮器高地址,高优先级任务OS_TCB,OSTCBHighRdy (3),(2),CPU,(4),(5),保存当前CPU寄存器的值,45,低优先级任务OS_TCB,OSTCBCur,存贮器低地址,存贮器高地址,堆栈方向,SP,R1,R2,R3,R4,PC,PSW,存贮器低地址,存贮器高地址,高优先级任务OS_TCB,OSTCBHighRdy (3),(2),CPU,(4),(5),(1),(3),重新装入要运行的任务,46,低优先级任务OS_TCB,OSTCBCur,存贮器低地址,存贮器高地址,堆栈方向,SP,R1,R2,R3,R4,PC,PSW,存贮器低地址,存贮器高地址
27、,高优先级任务OS_TCB,OSTCBHighRdy OSTCBCur (1),(2),CPU,(4),(4),(1),(3),(3),(4),任务切换OS_TASK_SW()的代码,47,Void OSCtxSw(void) 将R1,R2,R3及R4推入当前堆栈;OSTCBCurOSTCBStkPtr = SP;OSTCBCur= OSTCBHighRdy;SP= OSTCBHighRdy OSTCBSTKPtr;将R4,R3,R2及R1从新堆栈中弹出;执行中断返回指令; ,48,课程大纲, RT-Linux操作系统 实时操作系统C/OS简介 实时操作系统C/OS-II的内核结构 实时操作系
28、统C/OS-II中的中断与任务通讯 实时操作系统COS-II在ARM7上的移植 实时操作系统C/OS-III,49,C/OS-II中的中断,中断:由于某种事件的发生,而导致程序流程的改变。产生中断的事件称为中断源。 CPU响应中断的条件: 至少有一个中断源向CPU发出中断信号; 系统允许中断,且对此中断信号未予屏蔽 中断类型: 硬件中断 外部中断 陷井中断 现场控制量的中断,50,C/OS-II中的中断,进入临界区(中断),必要时须用汇编代码,退出临界区(中断),51,中断响应过程与实时调度,52,中断反回过程与实时调度,中断与时钟节拍,C/OS中提供了OSIntEnter() 和OSIntE
29、xit() 告诉内核进入了中断状态。时钟节拍是一种特殊的中断,操作系统的心脏 32位的整数:OSTime+1 对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态 最后进行上下文切换。,53,54,OSTimeTick( void ),时钟节拍中断流程,55,时间,任务一,任务二,OSStart,Time Tick,Time Tick,1,25,50,Time Tick,空闲任务,任务间通信手段,C/OS中,采用多种方法保护任务之间的共享数据和提供任务之间的通信。提供OS_ENTER_CRITICAL和OS_EXIT_CRITICAL来对临界资源进行保护 OSSchedLock( )禁止
30、调度保护任务级的共享资源。 提供了经典操作系统任务间通信方法:信号量、邮箱、消息队列,事件标志。,56,事件控制块ECB,typedef struct void *OSEventPtr; /*指向消息或消息队列的指针*/ INT8U OSEventTblOS_EVENT_TBL_SIZE; /*等待任务列表*/ INT16U OSEventCnt; /*计数器(当事件是信号量时)*/ INT8U OSEventType; /*事件类型:信号量、邮箱等*/ INT8U OSEventGrp; /*等待任务组*/ OS_EVENT;与TCB类似的结构,使用两个链表,空闲链表与使用链表,57,所有的
31、通信信号都被看成是事件(event) 一个称为事件控制块(ECB, Event Control Block)的数据结构来描述一个具体事件,ECB的结构如下,信号量semaphore,信号量在多任务系统中用于:控制共享资源的使用权、标志事件的发生、使两个任务的行为同步。 uC/OS中信号量由两部分组成:信号量的计数值和等待该信号任务的等待任务表。信号量的计数值可以为二进制, 也可以是其他整数。 系统通过OSSemPend( )和OSSemPost( )来支持信号量的两种原子操作P()和V()。P()操作减少信号量的值,如果新的信号量的值不大于0,则操作阻塞;V()操作增加信号量的值。,58,时间
32、管理,五个系统时间服务 OSTimeDLY() 任务延时函数 OSTimeDLYHMSM() 按时分秒延时函数 OSTimeDlyResmue() 结束延时 OStimeGet() OSTimeSet(),59,任务调度,For example1 创建2个任务,每个任务仅仅是进行延时,延时不同的时间片,不同优先级 void Task1(void) void Task2(void) while(1) while(1) blinkled1(); blinkled2();Task1Data+; Task2Data+;OSTimeDly(25); OSTimeDly(50); ,60,多任务循环,vo
33、id main() sysinit();OSInit ();OSTaskCreate ( Task1, (void *) ,61,任务启动,void OSStart (void) INT8U y, x;if (OSRunning = FALSE) 判断是否没有启动内核y = OSUnMapTblOSRdyGrp; x = OSUnMapTblOSRdyTbly;OSPrioHighRdy = (INT8U)(y 3) + x); 找到优先级最高的准备就绪任务OSPrioCur = OSPrioHighRdy; 当前运行任务优先级 OSTCBHighRdy = OSTCBPrioTblOSPri
34、oHighRdy; 根据任务优先级找到任务OSTCBCur = OSTCBHighRdy; OSStartHighRdy(); 让优先级最高的任务运行起来 ,62,任务调度,void OSSched (void) INT8U y;OS_ENTER_CRITICAL();if (OSLockNesting | OSIntNesting) = 0) 调度锁,或者处于中断状态禁止调度y = OSUnMapTblOSRdyGrp; OSPrioHighRdy = (INT8U)(y 3) + OSUnMapTblOSRdyTbly);获取准备就绪组里最高优先级的任务if (OSPrioHighRdy
35、!= OSPrioCur) OSTCBHighRdy = OSTCBPrioTblOSPrioHighRdy; 设置运行任务为最高优先级任务OSCtxSwCtr+; OS_TASK_SW(); 执行上下文切换 OS_EXIT_CRITICAL(); ,63,操作系统的启动和运行过程,64,什么也不做的空闲任务,只是为了消耗CPU的时间片 void OSTaskIdle ( ) for (;) OS_ENTER_CRITICAL();OSIdleCtr+;OS_EXIT_CRITICAL(); ,65,66,课程大纲, RT-Linux操作系统 实时操作系统C/OS简介 实时操作系统C/OS-I
36、I的内核结构 实时操作系统C/OS-II中的中断与任务通讯 实时操作系统COS-II在ARM7上的移植 实时操作系统C/OS-III,C/OS-II在ARM7上的移植,移植:指使一个实时操作系统能够在选定某个微处理器平台上运行 C/OS-II的主要代码都是由标准的C语言写成的,移植方便。,67,移植COS-II满足的条件,处理器的C编译器能产生可重入代码 在程序中可以打开或者关闭中断 处理器支持中断,并且能产生定时中断(通常在101000Hz之间) 处理器支承能够容纳一定量数据的硬件堆栈 处理器有将堆栈指针和其他CPU寄存器存储和读出到堆栈(或者内存)的指令,68,打开/关闭中断,C/OS-I
37、I是通过处理器产生的定时器的中断来实现多任务之间的调度的 ARM7TDMI的处理器上可以产生定时器中断。 ARM7TDMI处理器可以设置相应的寄存器来关闭或者打开系统的所有中断。 在C/OS-II中开关中断函数:OS_ENTER_CRITICAL () OS_EXIT_CRITICAL(),69,处理器支持中断并且能产生定时中断,C/OS-II是通过处理器产生的定时器的中断来实现多任务之间的调度的。ARM7TDMI的处理器上可以产生定时器中断。 本系统工作在60MHz的主频下,定时器的中断的频率为1000Hz。也就是系统的响应时间为1ms。,70,处理器支持硬件堆栈,硬件堆栈任务调度基础 C/
38、OS-II进行任务调度的时候,会把当前任务的CPU寄存器存放到此任务的堆栈中 然后,再从另一个任务的堆栈中恢复原来的工作寄存器,继续运行另一个任务 所以,寄存器的入栈和出栈是C/OS-II多任务调度的基础。 ARM7处理器中有专门的指令处理堆栈,可以灵活的使用堆栈。,71,例:C/OS-II在S3C44B0X上的移植,设置OS_CPU.H中与处理器和编译器相关的代码 用C语言编写六个操作系统相关的函数(OS_CPU_C.C) 用汇编语言编写四个与处理器相关的函数(OS_CPU.ASM),72,设置与处理器和编译器相关的代码,OS_CPU.H 中定义了与编译器相关的数据类型。 如:INT8U、I
39、NT8S等。 与 ARM处理器相关的代码 使用OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL() 宏开启关闭中断 堆栈的增长方向 堆栈由高地址向低地址增长,73,用C语言编写六个操作系统相关的函数,void *OSTaskStkInit (void (*task)(void *pd),void *pdata, void *ptos, INT16U opt) void OSTaskCreateHook (OS_TCB *ptcb) void OSTaskDelHook (OS_TCB *ptcb) void OSTaskSwHook (void) void OSTas
40、kStatHook (void) void OSTimeTickHook (void) 后5个函数为钩子函数,可以不加代码,74,用汇编语言编写四个与处理器相关的函数,OSStartHighRdy() OSCtxSw() OSIntCtxSw() OSTickISR(),75,移植要点,定义函数:OS_ENTER_CRITICAL和OS_ENTER_CRITICAL 定义函数:OS_TASK_SW执行任务切换。 定义函数:OSCtxSw实现用户级上下文切换,用纯汇编实现。 定义函数:OSIntCtxSw实现中断级任务切换,用纯汇编实现。 定义函数:OSTickISR。 定义OSTaskStkI
41、nit:来初始化任务的堆栈。,76,77,课程大纲, RT-Linux操作系统 实时操作系统C/OS简介 实时操作系统C/OS-II的内核结构 实时操作系统C/OS-II中的中断与任务通讯 实时操作系统COS-II在ARM7上的移植 实时操作系统C/OS-III, C/OS的改进,固定的基于优先级的调度 不支持时间片,使用起来不方便 固定任务基础上增加基于时间片的微型调度核 临界资源的访问上使用关闭中断实现 没有使用CPU提供的硬件指令,如测试并置位。 系统时钟中断 没有提供用户使用定时器,可以借鉴linux的定时器加以修改 可以加上文件系统和TCP/IP协议栈,78, C/OS-III的改进,2009年 C/OS-III是可以抢占的多任务内核,始终运行进入就绪态的最重要的任务 C/OS-III支持无限数量的任务,并允许在运行时,监测堆栈增长的任务 支持无限数量的优先级 允许无限数量的内核对象 运行时可以配置 支持的处理器包括:ARM7/9, Cortex-Mx, Nios- II, PowerPC, Coldfire, i.MX, Microblaze, H8, SH, M16C, M32C, Blackfin等等 不开源 部分内核将以库的形势提供,并与特定的硬件开发板捆绑,79,