第三章 中断与时钟_第1页
第三章 中断与时钟_第2页
第三章 中断与时钟_第3页
第三章 中断与时钟_第4页
第三章 中断与时钟_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

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

文档简介

嵌入式系统

EmbeddedSystem教师:白华邮箱:baihua2000@电话公室:4A-4092.2.4任务的其他管理函数堆栈检验:OSTaskStkChk()确定任务实际需要的堆栈空间大小删除任务:OSTaskDel()任务休眠,任务代码并未删除,只是不再被调用请求删除任务:OSTaskDelReq()改变任务的优先级:OSTaskChangePrio()挂起任务:OSTaskSuspend()空闲任务不能被挂起恢复任务:OSTaskResume()被挂起的任务只能通过该函数恢复获得任务信息:OSTaskQuery()获得指定任务的OS_TCB中内容的拷贝2.3例程解析共有10个任务在屏幕随机的位置上显示一个0~9的数字。每个任务只显示同一个数字,也就是其中一个任务在随机位置显示0,另一个显示1,等等。该例程目的在于演示mC/OS-II的多任务处理能力。#include"includes.h"includes.h是主控头文件,包含所有相关的头文件,从此可使用系统提供的数据类型、系统函数和全局变量等。#defineTASK_STK_SIZE512#defineN_TASKS10定义两个常数:TASK_STK_SIZE表示堆栈可容纳的指针元数目;N_TASKS表示需要建立的任务数。OS_STKTaskStk[N_TASKS][TASK_STK_SIZE];OS_STKTaskStartStk[TASK_STK_SIZE];charTaskData[N_TASKS];OS_EVENT*RandomSem;定义不同类型的变量(或数组)voidTask(void*data);voidTaskStart(void*data);staticvoidTaskStartCreateTasks(void);staticvoidTaskStartDispInit(void);staticvoidTaskStartDisp(void);自定义函数声明前往第17页voidmain(void){

PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);

OSInit();PC_DOSSaveReturn();PC_VectSet(uCOS,OSCtxSw);RandomSem=OSSemCreate(1);OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);OSStart();}PC_DispClrScr()为系统函数,具有清屏功能。()中的参数表示前景色为白色,背景色为黑色。voidmain(void){PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);

OSInit();

PC_DOSSaveReturn();PC_VectSet(uCOS,OSCtxSw);RandomSem=OSSemCreate(1);OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);OSStart();}非常重要的系统函数,执行μC/OS-II的初始化。在使用μC/OS-II的所有服务之前,必须要调用μC/OS-II的初始化函数OSInit()对μC/OS-II自身的运行环境进行初始化。函数OSInit()将对μC/OS-II的所有的全局变量和数据结构进行初始化,同时创建空闲任务OSTaskIdle,并赋之以最低的优先级别和永远的就绪状态。如果用户应用程序还要使用统计任务的话(常数OS_TASK_STAT_EN=1),则OSInit()还要以优先级别为OS_LOWEST_PRIO-1来创建统计任务。初始化函数OSInit()对数据结构进行初始化时,主要要创建5个空数据缓冲区(任务控制块、事件控制块、消息队列控制块、标志控制块、存储控制块)。为了可以快速地查询任务控制块链表中的各个元素,初始化函数OSInit()还要创建一个数组OSTCBPrioTbl[OS_LOWEST_PRIO+1],在这个数组中,按任务的优先级别的顺序把任务控制块的指针存放在了对应的元素中。2.3.1μC/OS-II的初始化(OSInit()函数)voidmain(void){PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);OSInit();PC_DOSSaveReturn();

PC_VectSet(uCOS,OSCtxSw);RandomSem=OSSemCreate(1);OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);OSStart();}PC_DOSSaveReturn();/*返回到没有运行mCOS-II之前的DOS环境*/PC_VectSet(uCOS,OSCtxSw);/*指定任务切换处理函数*/RandomSem=OSSemCreate(1);/*建立一个信号量*/信号量是由mC/OS-II提供的一种机制,用于防止多个任务同时访问同一资源(如产生随机数的函数)。这里信号量初值设置为1,通知mC/OS-II在某一时刻只有一个任务可以调用随机数产生函数。该信号量建立函数返回一个指向信号量的指针。OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);/*在开始多任务之前,必须建立至少一个任务。这里建立了一个叫做TaskStart()的任务*/OSStart();/*将控制权交给mC/OS-II内核,开始运行多任务*/2.3.2μC/OS-II的启动(OSStart()函数)多任务的启动是通过OSStart()实现的。在启动mC/OS-II之前,至少须建立一个应用任务。OSStart()函数完成以下两个工作:从任务就绪表中找出用户建立的优先级最高的任务的任务控制块,将该任务设为当前任务。将上述任务的堆栈中保存的值弹回到CPU寄存器中,然后执行一条中断返回指令,强制执行该任务代码。当OSStart()执行后,即多任务启动以后,系统将在用户任务之间,或用户任务与系统任务之间切换,不再返回到主函数main()。voidTaskStart(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifchars[100];INT16Skey;pdata=pdata;TaskStartDispInit();OS_ENTER_CRITICAL();PC_VectSet(0x08,OSTickISR);PC_SetTickRate(OS_TICKS_PER_SEC);OS_EXIT_CRITICAL();OSStatInit();TaskStartCreateTasks();与进入临界段代码的方式有关定义16位变量key,用于按键输入本任务无参数传递,未使用pdata,但为了避免编译器警告,故执行该语句初始化屏幕显示,作者自定义的函数,详见光盘中的源程序代码处理临界段代码1)处理临界段代码——关中断处理完成后——开中断

注:开/关中断的方法与编译器相关。2)μC/OS-II定义了两个宏(macros)来开中断和关中断:OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()这两个宏的定义取决于微处理器,在文件OS_CPU.H中可以找到相应的宏定义,而每种微处理器都有自己的OS_CPU.H2.3.3临界段代码(criticalsections)代码的临界段也称为临界区,指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入,因此在进入临界段之前必须关中断,而临界段代码执行完后,要立即开中断。OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL()具体实现方法有3种1)OS_CRITICAL_MATHOD=1用处理器的关中断指令完成OS_ENTER_CRITICAL()用处理器的开中断指令完成OS_EXIT_CRITICAL()2)OS_CRITICAL_MATHOD=2在堆栈中保存中断的开/关状态,然后再关中断,实现OS_ENTER_CRITICAL()从堆栈中弹出原来的中断开/关状态,实现OS_EXIT_CRITICAL()#defineOS_ENTER_CRITICAL()\asm(“pushpsw”)asm(“DI”)#defineOS_EXIT_CRITICAL()\asm(“poppsw”)

3)OS_CRITICAL_MATHOD=3一些编译器提供了扩展功能,用户可以得到当前处理器状态字的值,并保存在C函数的局部变量中,这个变量可以恢复PSW。#defineOS_ENTER_CRITICAL()\cpu_sr=get_processor_psw();\disable_interrupts();#defineOS_EXIT_CRITICAL()\set_processor_psw(cpu_sr);如果使用这种方式保护临界段代码,则须在应用程序的相关函数中多定义一个局部变量cpu_sr。voidTaskStart(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifchars[100];INT16Skey;pdata=pdata;TaskStartDispInit();OS_ENTER_CRITICAL();PC_VectSet(0x08,OSTickISR);PC_SetTickRate(OS_TICKS_PER_SEC);OS_EXIT_CRITICAL();OSStatInit();TaskStartCreateTasks();把计算机本来为时钟节拍提供的中断服务程序替换成mC/OS-II需要用到的时钟节拍中断服务程序设置时钟节拍的频率为200HzOS_TICKS_PER_SEC=200通过该函数得知处理器在运行所有应用任务时实际的CPU使用率这是作者自定义的一个函数,其作用是建立更多的任务接上页程序……for(;;){TaskStartDisp();if(PC_GetKey(&key)==TRUE){if(key==0x1B){PC_DOSReturn();}}OSCtxSwCtr=0;OSTimeDlyHMSM(0,0,1,0);}}无限循环作者自定义的显示函数,在DOS窗口底部显示任务数、CPU利用率等相关信息判断是否有按键输入如果按下键为Esc返回DOS环境如果没有按下Esc键,记录任务切换次数的全局变量OSCtxSwCtr清零,以便记录下一秒内发生的任务切换次数延时函数,()中从左到右分别表示时、分、秒、毫秒。任务调用该函数将自身挂起1秒,交出CPU使用权,内核开始调度,找到下一个最高优先级的就绪任务staticvoidTaskStartCreateTasks(void){INT8Ui;for(i=0;i<N_TASKS;i++){TaskData[i]='0'+i;OSTaskCreate(Task,(void*)&TaskData[i],&TaskStk[i][TASK_STK_SIZE-1],i+1);}}定义一个局部变量i返回第4页给数组TaskData[]赋值,包含0~9的ASCII字符创建10个任务,任务代码完全相同,每个任务接受一个指向字符数组中不同元素的指针,即每个任务接受了一个不同的字符(0~9)。每个任务需分配自己的堆栈空间,且拥有一个独一无二的优先级voidTask(void*pdata){INT8Ux,y,err;

for(;;){OSSemPend(RandomSem,0,&err);x=random(80);y=random(16);OSSemPost(RandomSem);PC_DispChar(x,y+5,*(char*)pdata,DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);OSTimeDly(1);}}无限循环定义三个局部变量查询信号量RandomSem,若该信号量正被其他任务占用,该任务被挂起,内核开始调度。括号中第二个参数表示超时时限,这个值为0表示无限等待调用随机数产生函数,返回一个0~79的数值调用随机数产生函数,返回一个0~15的数值释放信号量RandomSem在坐标为(x,y+5)的位置显示字符,前景色黑色,背景色浅灰色延迟一个时钟节拍,延时期间该任务被挂起,内核开始调度第三章μC/OS-II中断和时钟主要内容μC/OS-II的中断管理和中断服务程序μC/OS-II的系统时钟μC/OS-II的时间管理3.1μC/OS-II的中断3.1.1、基本概念

中断任务在运行过程中,应内部或外部异步事件的请求中止当前任务,而去处理异步事件所要求的任务的过程

中断服务子程序(InterruptServiceRoutines,ISR)应中断请求而运行的程序

中断向量中断服务子程序的入口地址3.1.2

mC/OS-II的中断

中断的优先级高于任务;中断嵌套可以多达255层;当系统处于开中断时,中断才会响应;只有所有中断都完成后,才能返回到任务;进入中断时,中断服务子程序必须调用OSIntEnter();退出中断时,中断服务子程序必须调用OSIntExit()。用户中断服务子程序流程保存全部CPU寄存器;调用OSIntEnter()或OSIntNesting直接加1;If(OSIntNesting==1){OSTCBCur->OSTCBStkPtr=SP;}清中断源;重新开中断;执行用户代码做中断服务;调用OSIntExit();恢复所有CPU寄存器;执行中断返回指令;进入中断函数OSIntEnter()voidOSIntEnter(void){if(OSRunning==TRUE{if(OSIntNesting<255){OSIntNesting++;

}}}voidOSIntExit(void){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifOS_ENTER_CRITICAL();if(OSRunning==TRUE){if(OSIntNesting>0){OSIntNesting--;}if((OSIntNesting||OSLockNesting)==0){OSIntExitY=OSUnMapTbl[OSRdyGrp];OSPrioHighRdy=(INT8U)((OSIntExitY<<3)+OSUnMapTbl[OSRdyTbl[OSIntExitY]]);if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;

OSIntCtxSw();/*调用中断切换函数,而非任务切换函数*/}}}OS_EXIT_CRITICAL();}退出中断函数OSIntExit()时钟:任何操作系统都要提供一个周期性的信号源,以提供系统处理诸如延时、超时等与时间有关的事

温馨提示

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

评论

0/150

提交评论