If anyone's interested we use the following function to dump the stack of a UCOS thread, should be fairly straght forward to modify for none UCOS systems:
// these variables generate by linker, using standard linker script.
extern char _start;
extern char __etext;
extern char __ram_exceptions_start;
extern char __ram_exceptions_end;
void DumpStackTcb(OS_TCB* a_pTCB)
{
void* sp = 0;
//lint -e{522}
__asm ("mov %0, sp" : "=r" (sp) );
void* pTextStart = &_start;
void* pTextEnd = &__etext;
void* pExceptStart = &__ram_exceptions_start;
void* pExceptEnd = &__ram_exceptions_end;
OS_STK* pStackBottom = a_pTCB->OSTCBStkBottom;
OS_STK* pStackTop = a_pTCB->OSTCBStkBottom + a_pTCB->OSTCBStkSize ; // OSTCBStkSize is num of elements, not bytes
OS_STK* pStackCur = a_pTCB->OSTCBStkPtr;
isr_printf("TS(0x%x) TE(0x%x) ES(0x%x) EE(0x%x)\n", (unsigned)pTextStart, (unsigned)pTextEnd, (unsigned)pExceptStart, (unsigned)pExceptEnd);
isr_printf("id(0x%x) sb(0x%x) st(0x%x) ss(0x%x) sp(0x%x) sp(0x%x)\n"
, a_pTCB->OSTCBPrio
, (unsigned)pStackBottom
, (unsigned)pStackTop
, a_pTCB->OSTCBStkSize * sizeof(OS_STK)
, (unsigned)pStackCur
, (unsigned)sp
);
u32 Cnt = 0;
for(OS_STK* pStack = pStackCur; (pStack >= pStackBottom) && (pStack < pStackTop) ; pStack++) {
void* pPossibleAddr = (void*)*pStack;
if(((((unsigned)pPossibleAddr) & 0x3) == 0) &&
(((pPossibleAddr > pTextStart) && (pPossibleAddr <= pTextEnd)) ||
((pPossibleAddr > pExceptStart) && (pPossibleAddr <= pExceptEnd)))) {
u32 PrevInstr = *((OS_STK*)pPossibleAddr-1); // check if instruction before poss. return address is a call
if( ((PrevInstr & 0x3f) == 0) || ((PrevInstr & 0x07ffffff) == 0x003ee83a) ) { // check call / callr
isr_printf("0x%x: ra(0x%x) pi(0x%x)\n", Cnt, (unsigned)pPossibleAddr, PrevInstr);
Cnt++;
}
}
}
}