This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MCU-PLUS-SDK-AM243X: M4F C++11 -O1 tries to execute 0xE000ED88 - Hard fault when using constructors

Part Number: MCU-PLUS-SDK-AM243X

With -O1 (Default) on the M4F, run_pinit() is trying to call 0xE000E088, and creating a hard fault.

All global classes have empty constructors ( ClassName() = default; ).


What is the best way to handle this? Do I tell the MPU to allow execution here? Is it something tricky with compiler flags (I use example defaults + C++11)? There's no explicit .pinit section in the linker cmd file. Should there be?

My workaround so far, discovered by accident, is to use -Og. But I'd like to fix this so I can use normal optimizations in the long run. I have not tested what other optimizations crash beyond -O1.

<EDIT> After some more pain with this I figured out that the __STACK_END was starting at the address of .init_array. I've updated my linker cmd file with a buffer as follows:

.stack: {} palign(8) > M4F_IRAM /* This is where the main() stack goes */
.buffer: fill=0xff { . += 0x008; } palign(8) > M4F_IRAM

/* Sections needed for C++ projects */
.ARM.exidx: {} palign(8) > M4F_IRAM /* Needed for C++ exception handling */
.init_array: {} palign(8) > M4F_IRAM /* Contains function pointers called before main */
.fini_array: {} palign(8) > M4F_IRAM /* Contains function pointers called after main */

If this is due to a bad project configuration, I'd like to understand what that is. If it's a bug, that would also be good to know. 

  • Hi Traveler,

    Our expert for this topic is out of office and will return by Nov 27th, please expect a response early that week.

    Best Regards,

    Sahana

  • Hi,

    Will it be possible for you to share the sample code and linker for us to check the issue?

    Regards,

    Ankur

  • It will be some time before I am able to create a stripped down example. Is there an email I can send it to?

    The ti sdk examples linker cmd file with clang v2.1.3.LTS is what I was using. I would expect that any c++ object with global construction that triggers the .init_array would trigger the bug if it's a bug.

    The link command is: -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mlittle-endian -mthumb -O -DSOC_AM243X -D_DEBUG_=1 -g -Wall -Wno-gnu-variable-sized-type-not-at-end -Wno-unused-function -Wl,-m"project_m4fss0-0.Debug.map" -Wl,-i"C:/ti/mcu_plus_sdk_am243x_09_00_00_35/source/kernel/freertos/lib" -Wl,-i"C:/ti/mcu_plus_sdk_am243x_09_00_00_35/source/drivers/lib" -Wl,-i"C:/ti/mcu_plus_sdk_am243x_09_00_00_35/source/board/lib" -Wl,-i"C:/ti/ccs1240/ccs/tools/compiler/ti-cgt-armllvm_2.1.3.LTS/lib" -Wl,--reread_libs -Wl,--diag_wrap=off -Wl,--display_error_number -Wl,--warn_sections -Wl,--xml_link_info="project_m4fss0-0_linkInfo.xml" -Wl,--ram_model

  • The following minimum example triggers this issue: SDK 9.0.0.3 hello_world_cpp example with hello_world.cpp contents as follows:


    #include <stdio.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"

    struct bubba{
        int x;
        bubba(){
            for (int i=0;i<10;i++)
                x = i;
        }

    };

    bubba hotep;

    void hello_world_main(void *args)
    {
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();

        DebugP_log("Hello World!\r\n");

        Board_driversClose();
        Drivers_close();
    }

  • Hi Traveler,

    I tried to make the above changes to the hello_world_cpp_am243x-lp_m4fss0-0_nortos_ti-arm-clang example. The load error did happen, but it happens on all the versions (No optimization, O1 etc.) and the error happens during the loading verification time. When I remove the 

        bubba(){
            for (int i=0;i<10;i++)
                x = i;
        }

    from the structure definition, the error goes away.

    Best regards,

    Ming

    ---------------------

    BLAZAR_Cortex_M4F_0: File Loader: Verification failed: Values at address 0x000118B8 do not match Please verify target memory and memory map.
    BLAZAR_Cortex_M4F_0: GEL: File: C:\ti\ccs_ws_1240_am243x_09.00.35\hello_world_cpp_am243x-lp_m4fss0-0_nortos_ti-arm-clang\Debug\hello_world_cpp_am243x-lp_m4fss0-0_nortos_ti-arm-clang.out: a data verification error occurred, file load failed.

  • Hi Ming,

    This issue is unrelated to load errors and per other threads workaround recommendations, I had target memory verification disabled.

    My recollection is that the address 0xE000ED88 was a constant in the init code so you should get exactly the same failure.

    Because the problem is with how the linker creates the __STACK_END symbol when there is .init_array code, the constructor `bubba()` is needed to trigger the problem.

  • Hi Traveler,

    I will try to disable the data verification and try to re-produce the problem you reported. Will get back to you early next week.

    Best regards,

    Ming

  • The first part of my original post has the symptom: A hard fault in the M4F, which if you step through the initialization you will see is caused by trying to execute address 0xE000ED88. This is early in the program initialization at the  run_pinit() code. Just a few instructions from the very start.

    0xE000ED88 gets pushed onto the stack as a normal part of the init sequence, but since the stack is overlapping the .init_array call table, the push clobbers the init_array call table.

    The second part of my original post (after <edit>) details the problem as I was able to understand it (__STACK_END is not set correctly by the linker), and my workaround (Insert some buffer space so that __STACK_END does not clobber .init_array).

    I originally thought I might have misconfigured the compile/link settings, but later reproducing the problem with the TI CPP example, I guess it might be with the ti build of lld?

  • Hi Traveler,

    I think the problem is caused by the linker. Usually, the code or data are allocated as start_address then extended to the start_address+size-1. The stack however is started with end_address and extended to the end_address-size-1. Here the .stack start at 0x0000d8b8, it size is 0x4000 and the STACK_END is 0x000118b8. According to the usual way of memory allocation, 0x0000d8b8 + 0x4000, i.e. 0x000118b8 should be usable for next data allocation. That is why the .init_array was allocated there by linker. Since the stack uses different way to allocate stack space. It starts at 0x000118b8 and the 0x0000d8b8 is free instead of the 0x000118b8. This allocation difference between normal data section vs the stack caused the overlap which in turn caused the hard failure.

    I will forward this thread to our CCS and CGT team for further help. Meanwhile, the workaround you have should work with no side effects.

    Best regards,

    Ming