- 打卡等级:以坛为家II
- 打卡总天数:435
- 最近打卡:2025-05-04 20:54:20
荣誉版主
- 积分
- 4275
|
发表于 2024-7-26 22:24:19
|
显示全部楼层
本帖最后由 CosyOS 于 2024-7-26 23:04 编辑
一、首先,用各任务的任务栈,做为各任务的可重入栈;
二、而后,各任务栈数据初始化时,“XBP”指向 (任务栈顶+1);
#if MCUCFG_XBPSTACK == __ENABLED__
#define mXBP_INIT \
*(s_u16_t *)(node_news->bsp + 15 + MCUCFG_USERREGSIZE) \ // 这里是任务栈中,XBP对应的两个字节
= node_news->bsp + node_news->stacksize // bsp为任务栈起始指针,加上任务栈size正好为 任务栈顶+1
#else
#define mXBP_INIT
#endif
#define mTaskStack_INIT \
do{ \
node_news->stacklen = ( \
(MCUCFG_TASK_REGBANK == MCUCFG_SYSINT_REGBANK ? 15 : 7) + \
(MCUCFG_USERREGCONFIG == 1 ? MCUCFG_USERREGSIZE : 0) \
); \ // 初始化 stacklen:任务栈的初始长度
*(s_u16_t *)node_news->bsp = ( \
((s_u16_t)s_task_starter->entry << 8) | \
((s_u16_t)s_task_starter->entry >> 8) \
); \ // 初始化 任务函数入口
*(s_u8_t *)(node_news->bsp + 7 - 1) = MCUCFG_TASK_REGBANK * 8; \ // 初始化 PSW
mUserReg_INIT; \ // 用户自定义任务切换现场保护汇编语言保护方案,用户寄存器的初始化
mXBP_INIT; \ // 初始化XBP
mUserReg_CINIT; \ // 用户自定义任务切换现场保护C语言保护方案,用户寄存器的初始化
}while(false)
三、最后,任务切换时,保护/恢复现场,要保护/恢复 ?C_XBP;
其中恢复 ?C_XBP 时,必须关闭 总中断EA。
IF MCUCFG_XBPSTACK == __ENABLED__ ; 保护 ?C_XBP
MOV A, ?C_XBP ; 先保存XBP高字节
MOVX @DPTR, A
INC DPTR
MOV A, ?C_XBP+1 ; 再保存XBP低字节
MOVX @DPTR, A
ENDIF
IF MCUCFG_XBPSTACK == __ENABLED__ ; 恢复 ?C_XBP
MOVX A, @DPTR
MOV R0, A ; XBP高字节缓存至R0
INC DPTR
MOVX A, @DPTR ; XBP低字节缓存至A
JBC EA, __EA ; 如果总中断EA开着呢,就跳转至__EA并关中断,而后再恢复,最后开中断;否则说明EA已经关了,继续往下直接恢复
MOV ?C_XBP, R0 ; 恢复 高字节
MOV ?C_XBP+1, A ; 恢复 低字节
SJMP RETURN
__EA: MOV ?C_XBP, R0
MOV ?C_XBP+1, A
SETB EA
ENDIF
以上描述为基本原理,详情请自行分析源码。。。
|
|