This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

RTX5 on GCC

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. 

Parents
  • I am not sure if this is part of it but looking at the symbol table, I see SVC_Count doesn't have a load address. 

    Output of `arm-none-eabi-readelf.exe" -s Blinky.elf | less`:

    170: 00400271 6 FUNC WEAK DEFAULT 1 DACC_Handler
    171: 00000000 0 NOTYPE GLOBAL DEFAULT 9 SVC_Count
    172: 00400271 6 FUNC WEAK DEFAULT 1 DebugMon_Handler

    Whereas, with the AC5 build:

    554: 0040040b 74 FUNC GLOBAL DEFAULT 1 __user_setup_stackheap
    555: 00400454 4 OBJECT GLOBAL HIDDEN 1 SVC_Count
    556: 00400459 4 FUNC GLOBAL HIDDEN 1 LED_GetCount

Reply
  • I am not sure if this is part of it but looking at the symbol table, I see SVC_Count doesn't have a load address. 

    Output of `arm-none-eabi-readelf.exe" -s Blinky.elf | less`:

    170: 00400271 6 FUNC WEAK DEFAULT 1 DACC_Handler
    171: 00000000 0 NOTYPE GLOBAL DEFAULT 9 SVC_Count
    172: 00400271 6 FUNC WEAK DEFAULT 1 DebugMon_Handler

    Whereas, with the AC5 build:

    554: 0040040b 74 FUNC GLOBAL DEFAULT 1 __user_setup_stackheap
    555: 00400454 4 OBJECT GLOBAL HIDDEN 1 SVC_Count
    556: 00400459 4 FUNC GLOBAL HIDDEN 1 LED_GetCount

Children