To aid debugging our OS, request from JLink the RTOS SDK. They also give you an example based off their embOS.
At first I had much trouble getting it to work. I find that if you use the pfLogOutf function, then you can start the GDBserver with -log option and you will see your DLL output.
If you use Eclipse, here is an example string you can use to start your RTOSPlugin DLL. Note that you need to add ‘GDBServer\’ to the -rtos switch. This did catch me out at the start wondering why it would not load.
- Monitor the GDB Client output. Here are some useful commands
- i th -info threads
- i s -info call stack
- i f -info frame
- t <id> – change to thread id
In Eclipse the Interactive GDBConsole is under the DebuggingConsole tab !! Sometimes accessible only via the Window->Show View->Other->Debug->Debugger Console
Once you have your DLL working you should see something like:
You won’t be able to step through the other threads, but at least you can see their call stack when in a breakpoint.
- The GetThreadDisplay function should not return 0; I found doing so prevented it being called again by the GDB client. So make sure you return something even if your Thread is not named.
- GetThreadRegList – Make sure you return the right number of bytes (17 for Cortex M3/4 without VFP, r0-r12,SP, LR, PC + xPSR)
- It’s a good idea to have the ThreadPointer (aka ThreadControlBlock / TCB ) have it’s first member be the PSP.
- Make sure you get the callee stacked registers pushed and popped off correctly. During initialisation of the exception stack init them with R0=0x010, R1=0x11 etc so that after each LDMIA / STMIA you can confirm that the right values were stacked in the right order.
- When passing the SP pointer, it is given an offset of ‘-2’ to signify that this value is to take the TCB->PSP value. Hovever PSP value is based off the presumption that the PSP is NOT in exception, thus it must not include the exception frame that all suspended tasks will be in.To exclude the exception frame (+0x20) and all callee stacked registers (+0x20) add a total of 0x40 to the PSP.
- A crude way for non FP is to use StackPtrValToRetrun = TCB->PSP + 0x40;
- If it looks like is failing… pfReadMem, it is because it returns the number of bytes read (or non zero?). Whereas all other read functions of the GDB API return 0 on success. I think this is an error in the documentation as the Segger example has ==0 on success.
- The threadID that is returned to and from the GDB Server to index the threads do NOT have to be the TCB address, it can be sequential starting from 1 if you like.