Hi,
I've run into a strange problem using cmsis_os (keil rtx), retargetting of semi-hosting to uart, and interrupts.
I have a simple project set up to use cmsis-rtos (importing rtx_cm4.lib) and uart rx interrupts (using the stm32f4xx hal libraries). Using microlib everything works fine, but as soon as I move to retargetting semihosting (using basically just the retarget.c file from keil) I end up in the hardfault handler.
My code for main is just:
int main() { // initialise the real time kernel osKernelInitialize(); // we need to initialise the hal library and set up the SystemCoreClock // properly HAL_Init(); configure_168MHz(); // set up the uart (with rx interrupts enabled) init_uart(9600); enable_rx_interrupt(); // print a status message printf("we are alive!\r\n"); // start everything running osKernelStart(); }
and I get the "we are alive!" message displayed on the uart, but as soon as I type anything into the uart window, the uart rx interrupt triggers and then dumps me into the hardfault handler. However, there isn't much information in the registers. This is what I get:
in hard fault handler SCB->HFSR = 0x40000000 SCB->CFSR = 0x00000000 SCB->MMFAR = 0xe000ed34 SCB->BFAR = 0xe000ed38 stack dump: SP = 0x20001d40 R0 = 0x20001730 R1 = 0x0000ffff R2 = 0x080005ed R3 = 0x0000000a R12 = 0x0800425d LR = 0x080038ef PC = 0x08000ac0 PSR = 0x21000057
So I can tell I have ended up with a forced hard fault, but the CFSR register is empty so I can't tell what caused it.
Could anybody give me any pointers here? The same code works with no rtos, and the same code works with no retargetting - just not with both rtos and retargetting!
Thanks for your time!
Alex
You'd want to look *around* the PC address, perhaps a couple of instructions prior. The PC points to the next instruction after the failing one, and stuff that's in write buffers can be queued from even earlier instructions.
ie before and including 0x080059F2
For the stack you'd want a clear understanding of the size and usage. Keil by default creates a 1KB stack which typically inadequate for most use cases, especially if stack hogs like printf/scanf are used. Fill the stack allocation with a fixed, non-zero character, that you can recognize when you display memory in the debugger, or code that walks the stack frame to determine maximal depth.
Thanks for your help and patience!
I tried increasing the stack size to 5Kb, but this didn't make any difference. However, I thought that each thread had its own stack? In the debugger "system and thread viewer" window, there is some information about the stack load of each thread and nothing is above 32%.
The instructions immediately around 0x080059F2 are:
0x080059E6 2301 MOVS r3,#0x01 0x080059E8 788C LDRB r4,[r1,#0x02] 0x080059EA E000 B 0x080059EE 0x080059EC 4610 MOV r0,r2 0x080059EE 6842 LDR r2,[r0,#0x04] 0x080059F0 B112 CBZ r2,0x080059F8 0x080059F2 7895 LDRB r5,[r2,#0x02] 0x080059F4 42A5 CMP r5,r4
but these don't mean anything to me I'm afraid :~(
I haven't yet tried your suggestion of filling the stack allocation with a fixed, non-zero character - I will try to find time for that tomorrow - but I'm pretty sure that I'm not just overflowing the stack (otherwise I would have thought that increasing the stack size by 5 times would have produced a different error at least!).
Again = thanks for all your time!
Regards,