uc/os 时钟中断处理
2012-03-14 12:12
309 查看
//中断退出函数OSInitExit(),标志着中断服务子程序的终结 void OSInitExit(void) { #if OS_CRITICAL_METHOD==3 OS_CPU_SR cpu_sr; #endif if(OSRunning==TRUE) { OS_ENTER_CRITICAL(); if(OSIntNesting>0) { OSIntNesting--; //中断嵌套层数计算器减一 } if((OSIntNesting==0)&&(OSLockNesting==0)) {//所有ISR 执行完毕,而且调度没有加锁,则进行重现调度 OSIntExitY=OSUnMapTbl[OSRdyGrp]; //OSUnMapTbl是优先级判定表 OSPrioHighRby=(INT8U)((OSIntExitY<<3)+OSUnMapTbl[OSRdyTbl[OSIntExitY]]); if(OSPrioHighRby!=OSPrioCur) {//若当前任务不是最高优先级任务 OSTCBHighRby=OSTCBPrioTbL[OSPriohighRby]; OSCtxSwCtr++;//保持对上下文切换次数的记录 OSIntCtxSw();//进行中断级的上下文切换,OSIntCtxSw() } } OS_EXIT_CRITICAL(); } } //C 语言时钟节拍函数OSTimeClick() void OSTimeTick(void) { OS_TCB *ptcb; OSTimeTickHook(); //用户定义的时钟节拍接口函数 ptcb=OSTCBList; //ptcb指向TCB 的头 while(ptcb->OSTCBPrio!=OS_IDLE_PRIO) {//遍历TCB 联表中的每一个TCB OS_ENTER_CRITICAL(); if(ptcb->OSTCBDly!=0) {//对节拍延时计算值没有达到零的任务的处理 if(--ptcb->OSTCBDly==0) {//对延时计算减一,若计数结束则满足条件 if(!(ptcb->OSTCBStat&OS_STAT_SUSPEND))//判断是否挂起 { OSRdyGrp|=ptcb->OSTCBBitY; //没有被挂起 OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;// } else //确实被挂起的任务不会进入就绪态 { ptcb->OSTCBDly=1;//使能再次判断挂起任务是否解除了挂起 } } } ptcb=ptcb->OSTCBNext;//联表指针指向下一个TCB OS_EXIT_CRITICAL(); } OS_ENTER_CRITICAL(); OSOSTime++; //32位数加1操作通常使用多条指令,为临界区 OS_EXIT_CRITICAL(); } //任务延时函数 void OSTimeDly(INT16U ticks) { #if OS_CRITICAL_METHOD==3 OS_CPU_SR cpu_sr; #endif if(ticks>0) //指定0值,则表明用户不想延时任务,函数立即返回到调用者 { OS_ENTER_CRITICAL(); if((OSRdyTbl[OSTCBCur->OSTCBY]&=~OSTCBCur->OSTCBBitX)==0) //将当前任务从就绪表中移除 { OSRdyGrp&=~OSTCBCur->OSTCBBitY; } OSTCBCur->OSTCBDly=ticks; //延时节拍数会被保存在当期的OS—TCB中 OS_EXIT_CRITICAL(); OS_Sched(); //任务调度程序 } } //任务延时函数,可提供更好的交互性 INT8U OSTimeDlyHMSM(INT8U hours,INT8U minutes,INT8U seconds,INT16U milli) { INT32U ticks; INT16U loops; if(hours>0||minutes>0||seconds>0||milli>0) { if(minutes>59) { return (OS_TIME_INVALID_MINUTES); } if(seconds>59) { return (OS_TIME_INVALID_SECONDS); } if(milli>999) { return (OS_TIME_INVALID_MILLI); } ticks=((INT32U)hours*3600L+(INT32U)minutes*60L+(INT32U)seconds)*OS_TICKS_PER_SEC+OS_TICKS_PER_SEC*((INT32U)milli+500L/ OS_TICKS_PER_SEC)/1000L; loops=(INT16U)(ticks/65536L); ticks=ticks%65536L; OSTimeDly((INT16U)ticks); while(loops>0) { OSTimeDly(32768); OSTimeDly(32768); loops--; } return (OS_NO_ERR); } return (OS_TIME_ZERO_DLY); } ;基S3C44BOX 处理器硬件平台的OSTickISR汇编程序 .GLOBAL OSTickISR STMDB SP!,{R0-R11,LR}; 保存寄存器的值到栈 MRS R0,CPSR; 以下三条指令是关中断,置I 位为1 ORR R0,R0,#0x80 msr,CPSR_cxsf,R0 LDR R0,=I_ISPC 把IRQ模式下的中断悬挂寄存器I_ISPR地址存入R0的寄存器 LDR R1,=BIT_TIMER0; BIT_TIMER0是定时器0的写入位,在头文件中定义 STR R1,[R0] 定时器0的中断服务悬挂位被清 BL IrqStart 中断计数 BL OSTimeTick 检查所有被延时的进程控制块,将延时节拍计数减1 BL OSIntEXIT 退出中断,检查有无优先级更高的程序已经就绪,如果有,则置变量need_to_swap_context-1 LDR R0,=need_to_swap_context 取变量need_to_swap_context的地址 LDR R2,[R0] 将变量need_to_swap_context存入R0 CMP R2,#1 比较need_to_swap_context是否为1 LDREQ PC,=_CTX_SW; 如果是则跳转到_CTX_SW,进行上下文切换 _NOT_CTX_SW 无须进行上下文切换 LDMIA SP!,{R0-R11,LR} 恢复寄存器的值 SUBS PC,LR,#4 OSTickISR函数返回,返回地址等于LR -4 _CTX_SW 进行上下文切换 MOV R1,#0 将变量need_to_swap_context置为0 STR R1,[R0] 现在进行上下文切换 LDMIA SP!,{R0-R11,LR} 恢复寄存器的值和堆栈指针 SUB LR,LR,#4 返回地址等于LR-4 STR LR,SAVED_LR 保存被抢占程序的返回地址到标SAVED_LR所在的字 MRS LR,SPSR 用4条指令切换管理SVC模式 AND LR,LR,#OXFFFFFFE0 ORR LR,LR,#Ox13 MSR CPSR_CXSF,LR 现在进入SVC管理模式 STR R12,[SP,#-8] 暂时保存R12到栈指针-8的位置 LDR R12,SAVED_LR 从标号SAVED_LR的内存位置取被抢占任务PC到R12 STMFD SP!,{R12} 将R12(原任务的PC)存放到栈区 SUB SP,SP,#4 将栈指针下移一个元素,指向暂存R12字的位置 LDMIA SP!,{R12} 恢复R12寄存器的值,SP上移1个单元 STMFD SP!,{LR} 保存被抢占任务的连接寄存器LR STMFD SP!,{R0-R12} 保存被抢占任务的R0-R12 MRS R4,CPSR STMFD SP!,{R4} 保存CPSR MRS R4,SPSR STMFD SP!,{R4} 保存SPSR 以下四条指令完成OSPrioCur=OSPrioHighRby LDR R4,addr_OSPrioCur LDR R5,addr_OSPrioHighRdy LDRB R6,[R5] STRB R6,[R4] 以下三条指令完成将当前任务栈指针Sp存放到被抢占任务的TCB 中 LDR R4,addr_OSTCBCur LDR R5,[R4] LDR SP!,[R5] 将SP保存在被抢占任务的TCB第一个字段 以下三条指令得到最高优先级任务的TCB地址,并将它存入SP寄存器 LDR R6,addr_OSTCBHighRby LDR R6,[R6] LDR SP,[R6] 以下单条指令实现了TCB指针的福祉操作:OSTCBCur=OSTCBHighRdy STR R6,[R4] 将抢占任务的TCB指针值给当前任务TCB 指针 LDMFD SP!,{R4} 恢复SPSR MSR SPSR_cxsf,R4 LDMFD SP!,{R4} 恢复CPSR MSR CPSR_cxsf,R4 LDMFD SP!,{R0-R12,LR,PC} 恢复寄存器R0-r12,LR和PC,执行抢占任务的执行函数
相关文章推荐
- [uC/OS-II原理及应用]uC/OS-II的中断和时钟
- UC/OS-II的中断和时钟
- 第三章uc/os-2的中断和时钟
- uC/OS-II的中断和时钟_读书笔记_4
- uc/os iii(一) 系统时钟及其中断服务函数
- uc/os软件中断与硬件中断处理流程分析
- uC/OSIII时钟节拍处理过程
- uC/OSIII时钟节拍处理过程
- uc/OS II移植中软件中断的理解
- [笔记分享] [OS] Linux的中断处理
- Linux的时间与时钟中断处理
- eCos和μC/OS-II的中断处理比较 (一)
- 学习札记--uC/OS-II处理临界区代码的三种方法小结
- Linux的时间与时钟中断处理
- uC/OS-II任务栈处理的一种改进方法
- uc/OS II移植中软件中断的理解与应用
- 时钟中断处理程序
- uC/OS 的中断——uC/OS学习笔记(三)
- μC/OSII中的时钟中断技术研究
- μC/OSII中的时钟中断技术研究