Hi All,
I'm trying to port an already working blinky application to GCC. I have it working on Keil uVision (AC6) and I'm using RTX5.
I'm targeting the SAMV71Q21B. I'm using CMSIS-Build (cbuild) provided with CMSIS 5.7.0 to generate the necessary .cprj which then, using cbuild, generates the necessary make files.
So far I can get the application to start but it seems to be hardfaulting within the RTOS.
It's hardfaulting within HAL_CM4.S. To the best of my knowledge, I've configured the application in the same way as it was in the uVision based build. I.e. same stack size. One difference is that in the uVision based build, I'm using the Keil SAM-ESV7_SFP pack but in the GCC build I'm using Atmel's SAMV71_DFP (version 2.4.182). I had to edit the accompanying samv71q21_flash.ld file as the linker was complaining about missing __bss_start__, __bss_end__ and end symbols.
I also had to tweak startup_samv71q21 as it was bundling in a dummy handler for SVCall_Handler. So it wasn't picking up the SVC_Handler bundled with RTX5.
Incidentally I had to comment the following within: samv71q21.h. I don't know what that's about!
/* Defines for Deprecated Interrupt and Exceptions handler names */ #define MemManage_Handler MemoryManagement_Handler /**< \deprecated Backward compatibility for ASF */ #define DebugMon_Handler DebugMonitor_Handler /**< \deprecated Backward compatibility for ASF */ #define NMI_Handler NonMaskableInt_Handler /**< \deprecated Backward compatibility for ASF */ #define SVC_Handler SVCall_Handler /**< \deprecated Backward compatibility for ASF */
Anyway, after that modification, it builds and runs - up until the aforementioned hardfault.
Specifically it dies here:
/*------------------- User SVC ------------------------------*/ SVC_User: PUSH {R4,LR} /* Save Registers */ LDR R2,=SVC_Count LDR R2,[R2] CMP R1,R2 BHI SVC_Done /* Overflow */ LDR R4,=SVC_Table-4 LDR R4,[R4,R1,LSL #2] /* Load SVC Function Address */ LDM R0,{R0-R3,R12} /* Read R0-R3,R12 from stack */ BLX R4 /* Call SVC Function */ MRS R12,PSP STM R12,{R0-R3} /* Function return values */ SVC_Done: POP {R4,PC} /* RETI */ .fnend .size SVC_Handler, .-SVC_Handler
Specifically, on line 259 in the source. (Though I'm linking against ARM/CMSIS/5.7.0/CMSIS/RTOS/RTX/LIB/GCC/libRTX_CM4.a.
The routine looks identical to the associated routine within CMSIS\RTOS\RTX\SRC\ARM\HAL_CM4.c so I assume this is merely a symptom of the actual problem.
It *appears* to me that the address of SVC_Table isn't being read correctly from memory.
I'm debugging with Segger's Ozone and single stepping through HAL_CM4.S (I had to manually find HAL_CM4.S and point the Ozone to it but it appears to be working) and the instruction:
`LDR R4=SVC_Table-4` gets skipped for some reason (if someone could shed some light on that, it would be great)
As can be seen in the screenshot, R4 is 0 prior to the next LDR instruction. Though, my understanding of what this syntax of LDR means is at odds with what Ozone is elaborating that instruction to mean. Anyway, R4 gets set to 0xFFFFFFFC which then get's branched to in 259.
My understanding is that this instruction should do the following: R4 = [R4 + (R1 << 2)] which in my case would read the address 0x380. (Garbage address?).
Another question I have here is after the call to LDM on line 258, R4 changes to 0x68FB71FB. I have no idea where this comes from. The current value of 0x380 isn't that value by the way. Is the latency in updating this value got to do with instruction pipelining?
Reading this address appears to result in a bus fault.
Any suggestions you may have as to where I'm going wrong would be greatly appreciated.
Thanks.
My application "just works" with RTX5 and RTOS2.