在线时间0 小时
UID319034
注册时间2008-8-6
NXP金币0
该用户从未签到
新手上路

- 积分
- 8
- 最后登录
- 1970-1-1
|
发表于 2011-11-26 09:26:44
|
显示全部楼层
回复:关于UCOS-II任务压栈的问题
在UCOS-II接管系统后并不使用系统栈(对于μC/OS-II原始的中断处理的设计, 中断处理过程中的中断嵌套中所需要压栈的寄存器大小和局部变量的内存大小,都需要算在每个任务的任务堆栈中,则对于每一个任务都需要预留这一部分内存,所以大量的RAM被浪费。从这里可以看出,解决这一问题的直接方法就是把中断堆栈和每个任务自己的堆栈分开。这样,在计算每个任务堆栈的时候,就不需要把中断处理中(包括中断嵌套过程中)的内存的占用计算到每个任务的任务堆栈中,只需要计算每个任务本身需要的内存大小,从而提高了RAM的利用率,可以缓解内存紧张的问题。),哪个任务在运行,其堆栈段基值SS和堆栈段偏移量指针SP,就指向相应的任务堆栈段—因为任务切换时并没保存SS和SP,入栈是,调用中断子程序,软中断(INT)也只是将PSW,CS,IP入栈,而这些也可以压入任务堆栈,然后PUSHA,将接着把执行软中断指令的任务(调用OS_TASK_SW()函数的任务)的中断返回地址(段地址DS和偏移量地址ES)压入任务堆栈,然后,把所有cpu其他寄存器压栈到当前任务堆栈中(注:在这个过程中有把SP压入任务堆栈段),最后,将指向这个堆栈结构的指针保存在当前任务的任务控制块中,这个指针包括堆栈段寄存器(SS)和堆栈指针寄存器(SP)-这样说明SP一直是指向当前任务的任务堆栈;出栈时,先获取最高优先级任务的相关数据及任务堆栈地址,并把任务堆栈的段基值存放入SS,偏移量存放入SP,接着把新任务的中断返回地址(段地址DS和偏移量地址ES)从新任务堆栈出栈到相应的寄存器中,然后,把任务堆栈中所有数据出栈到相应的寄存器,最后,中断返回(IRET)把存储在新任务的任务堆栈中的PSW,CS,IP出栈到相应寄存器。代码如下:
OSCtxSw PROC FAR; PSW,CS,IP入栈
;将寄存器值压人当前任务堆栈
PUSHA
PUSH ES;压栈中断返回地址(段地址DS和偏移量地址ES)
PUSH DS
;获取指向任务控制块全局指针的段基值
MOV AX, SEG _OSTCBCur
MOV DS, AX
; 将任务堆栈的SS:SP存入任务控制块的指针中
LES BX, DWORD PTR DS:_OSTCBCur
MOV ES:[BX+2], SS
MOV ES:[BX+0], SP
CALL FAR PTR _OSTaskSwHook
;获取最高优先级任务并置为当前任务
MOV AX, WORD PTR DS:_OSTCBHighRdy+2
MOV DX, WORD PTR DS:_OSTCBHighRdy
MOV WORD PTR DS:_OSTCBCur+2, AX
MOV WORD PTR DS:_OSTCBCur, DX
;当前任务相关信息
MOV AL, BYTE PTR DS:_OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL
; 获取当前任务(即新任务)的任务堆栈地址并存入SS:SP
LES BX, DWORD PTR DS:_OSTCBHighRdy
MOV SS, ES:[BX+2]
MOV SP, ES:[BX]
;装载新任务—新任务信息存入相应寄存器
POP DS ; 出栈中断返回地址(段地址DS和偏移量地址ES)
POP ES
POPA
IRET; PSW,CS,IP出栈—新任务开始运行
_OSCtxSw ENDP
|
|