Calling __mainCRTStartup from Reset_Handler ISR causes hardfault

Asked by Nitin on 2017-03-17

Using MSP432(Cortex M4) running freeRTOS blinky demo( simple program toggling on board LED).
Toolchains version tried : 5_3-2016q1-20160330 and 6-2017-q1-update.

Start up and linker files are provided by TI. they can be found at http://www.ti.com/tool/msp432-gcc-opensource.
Definition of Reset_Handler that causes hardfault:
void Reset_Handler(void)
{
  SystemInit();
     _mainCRTStartup();
}

if we replace _mainCRTStartup() by adding code for
1. Zero filling the bss segment
2. Call main() directly.
It works fine.

crt0 file used(obtained from linker map file): arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/crt0.o

Could you explain why this happens? Cant we use c run time code for start up instead of manually zero filling the bss?

Question information

Language:
English Edit question
Status:
Expired
For:
GNU ARM Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
2017-03-26
Last reply:
2017-04-11

Hi Nitin,

The toolchain needs to be usable for bare-metal targets without MMU so that there is no zero page to be mapped to bss section. The init code contains instruction to zero the bss section but relies on some symbol being defined: __bss_start__ and __bss_end__.

I'd recommend using nm to check the value of these symbols in your executable.

Best regards.

Nitin (bietian) said : #2

Thank you for the reply, Thomas.
The target used does not have an MMU.
I used the nm to check if the symbols are defined. attached is a segment of the nm output:
20004208 B __bss_end__
20000070 B __bss_start__

If I add the instruction to zero the bss section in Reset_Handler , it works fine. But if I use the _mainCRTStartUp() in Reset_handler, it hardfaults. Could you provide some inputs on how to debug this issue?

Hi Nitin,

Could you try running it in GDB and show the output of "disassemble" and "bt" commands?

Best regards.

Nitin (bietian) said : #4

Hi Thomas,

Attached outputs of disassemble and bt commands of two versions: The only difference between two versions is the the definition of Reset_Handler ISR and its assembler outputs can be seen in the logs below:
1. LOG 1 (hardfault): disassemble and bt commands output for Reset_handler definition:
void Reset_Handler(void)
{
   SystemInit();
   _mainCRTStartup();
}

2. LOG 2 (works): disassemble and bt commands output for Reset_handler definition:
void Reset_Handler(void)
{
    /* Call system initialization routine */
    SystemInit();

 /* Copy the data segment initializers from flash to SRAM. */
    uint32_t *pui32Src, *pui32Dest;

    pui32Src = &__data_load__;
    for(pui32Dest = &__data_start__; pui32Dest < &__data_end__; )
    {
        *pui32Dest++ = *pui32Src++;
    }

    /* Zero fill the bss segment. */
    __asm(" ldr r0, =__bss_start__\n"
          " ldr r1, =__bss_end__\n"
          " mov r2, #0\n"
          " .thumb_func\n"
          "zero_loop:\n"
          " cmp r0, r1\n"
          " it lt\n"
          " strlt r2, [r0], #4\n"
          " blt zero_loop");

    main();
}

LOG 1(hardfault):

Dump of assembler code for function Reset_Handler:
   0x00002c12 <+0>: push {r3, lr}
   0x00002c14 <+2>: bl 0x2c20 <SystemInit>
   0x00002c18 <+6>: bl 0x15c <_start>
   0x00002c1c <+10>: pop {r3, pc}
End of assembler dump.
Remote debugging using localhost:2331
0x00000328 in vPortRaiseBASEPRI () at freertos/portable/GCC/ARM_CM4F/portmacro.h:237
237 __asm volatile
Resetting target

Selecting device: MSP432P401R

Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00000328 in vPortRaiseBASEPRI () at freertos/portable/GCC/ARM_CM4F/portmacro.h:237
237 __asm volatile
#0 0x00000328 in vPortRaiseBASEPRI () at freertos/portable/GCC/ARM_CM4F/portmacro.h:237
#1 vApplicationMallocFailedHook () at main.c:48
#2 0x00001fa0 in pvPortMalloc (xWantedSize=400) at freertos/portable/MemMang/heap_4.c:291
#3 0x000009a8 in xTaskCreate (pxTaskCode=0x481 <prvTaskCollector>, pcName=0x2cd0 "CLT", usStackDepth=<optimized out>, pvParameters=0x22 <interruptVectors+34>, uxPriority=2,
    pxCreatedTask=0x0 <interruptVectors>) at rtos/tasks.c:716
#4 0x00000574 in xCreateTask () at create.c:71
#5 0x0000030e in main () at main.c:18

LOG 2(works):
Dump of assembler code for function Reset_Handler:
   0x00002c14 <+0>: push {r3, lr}
   0x00002c16 <+2>: bl 0x2c5c <SystemInit>
   0x00002c1a <+6>: ldr r3, [pc, #44] ; (0x2c48 <Reset_Handler+52>)
   0x00002c1c <+8>: ldr r2, [pc, #44] ; (0x2c4c <Reset_Handler+56>)
   0x00002c1e <+10>: b.n 0x2c28 <Reset_Handler+20>
   0x00002c20 <+12>: ldr r1, [r2, #0]
   0x00002c22 <+14>: str r1, [r3, #0]
   0x00002c24 <+16>: adds r3, #4
   0x00002c26 <+18>: adds r2, #4
   0x00002c28 <+20>: ldr r1, [pc, #36] ; (0x2c50 <Reset_Handler+60>)
   0x00002c2a <+22>: cmp r3, r1
   0x00002c2c <+24>: bcc.n 0x2c20 <Reset_Handler+12>
   0x00002c2e <+26>: ldr r0, [pc, #36] ; (0x2c54 <zero_loop+30>)
   0x00002c30 <+28>: ldr r1, [pc, #36] ; (0x2c58 <zero_loop+34>)
   0x00002c32 <+30>: mov.w r2, #0
   0x00002c36 <+34>: cmp r0, r1
   0x00002c38 <+36>: it lt
   0x00002c3a <+38>: strlt.w r2, [r0], #4
   0x00002c3e <+42>: blt.n 0x2c36 <Reset_Handler+34>
   0x00002c40 <+44>: bl 0x304 <main>
   0x00002c44 <+48>: pop {r3, pc}
   0x00002c46 <+50>: nop
   0x00002c48 <+52>: movs r0, r0
   0x00002c4a <+54>: movs r0, #0
   0x00002c4c <+56>: cmp r5, #112 ; 0x70
   0x00002c4e <+58>: movs r0, r0
   0x00002c50 <+60>: lsls r0, r1, #2
   0x00002c52 <+62>: movs r0, #0
End of assembler dump.
Remote debugging using localhost:2331
Resetting target

Selecting device: MSP432P401R

Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
vPortSuppressTicksAndSleep (xExpectedIdleTime=95) at rtos/portable/GCC/ARM_CM4F/port.c:589
589 __asm volatile( "isb" );
#0 vPortSuppressTicksAndSleep (xExpectedIdleTime=95) at rtos/portable/GCC/ARM_CM4F/port.c:589
        ulReloadValue = 2846473
        ulCompleteTickPeriods = <optimized out>
        ulCompletedSysTickDecrements = <optimized out>
        ulSysTickCTRL = <optimized out>
        xModifiableIdleTime = 95
#1 0x00000dea in prvIdleTask (pvParameters=<optimized out>) at rtos/tasks.c:3218
        xExpectedIdleTime = <optimized out>
#2 0x0000202c in vPortFree (pv=0x5f <interruptVectors+95>) at rtos/portable/MemMang/heap_4.c:338
        puc = 0x5f <interruptVectors+95> ""
        pxLink = <optimized out>
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Launchpad Janitor (janitor) said : #5

This question was expired because it remained in the 'Open' state without activity for the last 15 days.