55337575 发表于 2024-4-2 10:06:06

请教杨老师FreeRTOS中的SPX指针存取问题

系统中sp指针的保存和恢复如下:

/* Saves the stack pointer for one task into its TCB. */
#define portSAVE_SPX()                      \
{                                           \
    __asm   { MOV   DR0,DR60    }         \
    __asm   { MOV   DR4,pxCurrentTCB    }   \
    __asm   { MOV   @WR6+0x2,WR2      }   \
}

/* Restores the stack from the new TCB read to
run the task. */
#define portRESTORE_SPX()                   \
{                                           \
    __asm   { MOV   DR4,pxCurrentTCB    }   \
    __asm   { MOV   WR2,@WR6+0x2      }   \
    __asm   { XRL   WR0,WR0   }         \
    __asm   { MOV   DR60,DR0    }         \
}

为什么不直接【 __asm   { MOV   pxCurrentTCB ,DR60    }   】和【__asm   { MOV   DR60,pxCurrentTCB }】呢?
原文中SPX的操作我理解的仅仅是对低字节,高字节有其他信息么?

杨为民 发表于 2024-4-2 12:42:52

本帖最后由 杨为民 于 2024-4-2 13:15 编辑

(1)关于SPX寄存器,参考下图:





确实,SPX只有低16位有效,它对应的存储区域为EDATA空间。


(2)“为什么不直接【 __asm   { MOV   pxCurrentTCB ,DR60    }   】和【__asm   { MOV   DR60,pxCurrentTCB }】呢?”
如果是“MOV   pxCurrentTCB ,DR60”和“MOV   DR60,pxCurrentTCB”,在汇编语言中是“直接寻址”,适合于“pxCurrentTCB”是简单变量的情况,数据存放在地址为pxCurrentTCB地方。


(3)由于“pxCurrentTCB”是C语言中的指针变量,“__asm   { MOV   @WR6+0x2,WR2      }”和“__asm   { MOV   WR2,@WR6+0x2      } ”在汇编语言中是“间接寻址”,适合于“pxCurrentTCB”是指针变量的情况。
这里地址为pxCurrentTCB地方存放的是“指向数据存放地址”,而真正的数据存放在地址为@pxCurrentTCB的地方。
比如上面“__asm   { MOV   @WR6+0x2,WR2      }”指令中的WR6寄存器中,存放的是“pxCurrentTCB”在EDATA里面的内容的低16位,指向了在EDATA中现行任务的TCB表的首地址(这个地址将存放现行任务的4字节的系统堆栈指针SPX),
而这条指令只存了SPX的低16位,这对于64KB的EDATA空间已经够了。


55337575 发表于 2024-4-2 13:21:24

明白了,谢谢杨老师{:4_196:}
页: [1]
查看完整版本: 请教杨老师FreeRTOS中的SPX指针存取问题