I am trying to understand this Assembly macro that sets the stack pointer to the location of a Task Stack of a RTOS. There are a few Assembly commands that I don't know and where I can't find that much information of.
This code points the User stack pointer to the stack of a Micrium Task (uC/OS III RTOS). But these tasks are only allowed to lay into near memory, and that is probably because of these assembly functions.
That's why I'm trying to find out what exactly is happening here. And why the stack can only be in near memory. After that I would like to find out if I can rewrite this to support tasks stacks outside of the near memory.
This assembly code is running on a XE169 chip (C166 Family):
LOAD_USRSTK_PTR .MACRO
EXTP #PAG _OSTCBHighRdyPtr,#02h ; R4/R5 = OSTCBHighRdyPtr
MOV R4,POF _OSTCBHighRdyPtr
MOV R5,POF (_OSTCBHighRdyPtr+2)
EXTP R5,#01h ; user stack ptr = OSTCBHighRdyPtr->OSTCBStkPtr
MOV R15,[R4]
.ENDM
This is how far I've found out what each line of code does:
LOAD_USRSTK_PTR .MACRO
Start of macro with the name LOAD_USRSTK_PTR
EXTP #PAG _OSTCBHighRdyPtr,#02h
Begin Extended Page Sequence, the next 2 instructions are part of the Extended Page Sequence
What does the #PAG _OSTCBHighRdyPtr part in this instruction mean, does this get the Page part of of the address where OSTCBHighRdyPtr is pointing to.
So the bits 23-14 of the pointer. When looking at the below image:
MOV R4,POF _OSTCBHighRdyPtr
Write _OSTCBHighRdyPtr into Register 4. What does POF mean in this instruction, does it get the value of the pointer and store that in Register 4?
MOV R5,POF (_OSTCBHighRdyPtr+2)
Write the value of at 2 addresses further as the address of OSTCBHighRdyPtr to Register 5. What does POF mean in this instruction Is it in this case copying the ExtPtr address? because this address is 4 bytes long, and the Register only 2 bytes?
EXTP R5,#01h ; user stack ptr = OSTCBHighRdyPtr->OSTCBStkPtr
Begin Extended Page Sequence. Next 1 instruction is part of the Extended Page Sequence. R5 = Register 5 what exactly is done with this register
MOV R15,[R4]
Move the value of Register 4 into Register 15, R15 is the User Stack Pointer
.ENDM
End of Macro
The _OSTCBHighRdyPtr is a pointer to a struct, the (beginning) of this struct looks like this:
struct os_tcb {
CPU_STK *StkPtr; /* Pointer to current top of stack */
void *ExtPtr; /* Pointer to user definable data for TCB extension */
CPU_CHAR *NamePtr; /* Pointer to task name */
CPU_STK *StkLimitPtr; /* Pointer used to set stack 'watermark' limit */
....
}
CPU_STK is a typedef of unsigned short __near.
The sizes of the items in this struct are:
StkPtr = 2 bytes (in near memory thus 2 bytes is enough)
ExtPtr = 4 bytes
NamePtr = 4 bytes
StkLimitPtr = 2 bytes (in near memory thus 2 bytes is enough)