|
|
楼主 |
发表于 2005-9-10 07:11:35
|
显示全部楼层
一、 没有函数调用;
二、 调用非reentrant函数,函数中没有嵌套调用其他函数;
三、 调用非reentrant函数,函数中嵌套调用其他函数;
四、 调用reentrant函数。
t0_isr:
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
MOV PSW,#00H
PUSH AR0
PUSH AR1
PUSH AR2
PUSH AR3
PUSH AR4
PUSH AR5
PUSH AR6
PUSH AR7
用户代码
POP AR7
POP AR6
POP AR5
POP AR4
POP AR3
POP AR2
POP AR1
POP AR0
POP PSW
POP DPL
POP DPH
POP B
POP ACC
RETI
因为uCOS中所有的函数都必须是重入函数,因此我们只需要研究第四种情况下的堆栈保护,
对于其他情况有兴趣可以在c51中看看。(注意:可能因为c51编译器的版本不同,上述压栈
的顺序可能不同。)
2、uCOS C51任务切换时的堆栈操作;
每个任务都有一个独立的数据堆栈,系统堆栈是公用空间。
保护Task1的CPU寄存器: 首先将CPU寄存器按上例压进Task1系统堆栈,再将整个Task1系统
堆栈压进Task1数据堆栈;
SP切换:?C_XBP = Task2 的数据堆栈栈顶地址。
弹出Task2的CPU寄存器:从Task2的数据堆栈重新恢复整个系统堆栈,然后再从Task2系统堆
栈中恢复CPU寄存器值。
实现的方法有很多种,只要遵循uCOS任务切换的原理就可以了。
<B>关注 [shenxian] 2005-1-24 11:45:55</B> < >
</P><B>Chapter 2 [pwl999] 2005-1-24 11:48:34</B> < >3、INCLUDES.H的移植;
重点:
"pdata"是C51关键字,所以要重新定义
源代码:
#include <reg52.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <setjmp.h>
#define TASK_REENTRANT large reentrant
#define KCREENTRANT large reentrant
#include "os_cpu.h"
#include "os_cfg.h"
#define data ucos51_data
#define idata ucos51_idata
#define pdata ucos51_pdata
#define xdata ucos51_xdata
#include "ucos_ii.h"
4、OS_CPU.H的移植;
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned int INT16U;
typedef signed int INT16S;
typedef unsigned long INT32U;
typedef signed long INT32S;
typedef float FP32;
typedef unsigned char OS_STK;
#define BYTE INT8S
#define UBYTE INT8U
#define WORD INT16S
#define UWORD INT16U
#define LONG INT32S
#define ULONG INT32U
</P><B>Chapter 3 [pwl999] 2005-1-24 11:55:14</B> < >5、OS_CPU_A.ASM的移植;
重点:
1.C51中断时积存器的入栈顺序
2.Asm中对" ?C_XBP"、" ?STACK'的引用
3.堆栈的压栈方向。堆栈是先加指针后存数还是先存数后加指针。
源代码:
NAME OS_CPU_A
;******************************************************************
; PUBLIC and EXTERNAL REFERENCES
;******************************************************************
?PR?_?OSStartHighRdy?OS_CPU_A SEGMENT CODE
?PR?_?OSCtxSw?OS_CPU_A SEGMENT CODE
?PR?_?OSIntCtxSw?OS_CPU_A SEGMENT CODE
?PR?_?OSTickISR?OS_CPU_A SEGMENT CODE
?STACK SEGMENT IDATA
DT?OS_CPU_A SEGMENT DATA
PUBLIC _?OSTickISR
PUBLIC _?OSStartHighRdy
PUBLIC _?OSCtxSw
PUBLIC _?OSIntCtxSw
PUBLIC OSTickRate
PUBLIC OSTickCtr
EXTRN DATA (?C_XBP)
EXTRN XDATA (OSTCBCur)
EXTRN XDATA (OSTCBHighRdy)
EXTRN XDATA (OSPrioCur)
EXTRN XDATA (OSPrioHighRdy)
EXTRN XDATA (OSRunning)
EXTRN CODE (_?OSIntEnter)
EXTRN CODE (_?OSIntExit)
EXTRN CODE (_?OSTimeTick)
EXTRN CODE (_?OSTaskSwHook)
</P><B>云~ [pwl999] 2005-1-24 12:04:14</B> <P>管理员,你们16k限制是怎么算的啊。太小了,我晚上再把剩下的发上来。
</P><B> [caoqing] 2005-1-24 12:56:40</B> <P>
</P><B>收藏,顶 [huzimax] 2005-1-24 13:32:38</B> <P>
</P><B> [李贝] 2005-1-24 13:42:43</B> <P>
</P><B>这种原创的文章可以做成博客的栏目文章了,博客功能完成时一定收录。 [龙啸九天] 2005-1-24 13:56:47</B> <P>
</P><B>good! [leifeng] 2005-1-24 18:33:31</B> <P>
</P><B>Chapter 4 [pwl999] 2005-1-24 19:31:46</B> <P>;******************************************************************
; MACRO DEFINE
;******************************************************************
PUSHALL MACRO
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
IRP REG, <R0, R1, R2, R3, R4, R5, R6, R7>
MOV A, REG
PUSH ACC
ENDM
ENDM
POPALL MACRO
IRP REG, <R7, R6, R5, R4, R3, R2, R1, R0>
POP ACC
MOV REG, A
ENDM
POP PSW
POP DPL
POP DPH
POP B
POP ACC
ENDM
</P><B>Chapter 5 [pwl999] 2005-1-24 19:34:13</B> <P>LoadXBP MACRO
MOV DPH, ?C_XBP
MOV DPL, ?C_XBP+1
ENDM
SaveXBP MACRO
;PUSH IE
;CLR EA
MOV ?C_XBP, DPH
MOV ?C_XBP+1,DPL
;POP IE
ENDM
LoadReg MACRO REG
MOVX A, @DPTR
MOV REG, A
ENDM
SaveReg MACRO REG
MOV A, REG
MOVX @DPTR, A
ENDM
</P><B>Chapter 6 [pwl999] 2005-1-24 19:34:59</B> |
|