Search code examples
eclipsecortex-mopenocd

__libc_init_array failure on STM32L0


I'm starting with a STM32L053 on linux, using Eclipse IDE, crosscompiling with gcc-arm-none-eabi-7-2017-q4 and debugging with openocd.

Before entering in the main(), I fall in the WWDG_IRQHandler(). On the debugger stack I can see :

  ↓ Reset_Handler() at 0x8002812
  ↓ __libc_init_array() at 0x8002836
  ↓ <signal handler called>() at 0xfffffff9
    WWDG_IRQHandler() at 0x8002830

Few lines from Reset_Handler(), btw I think the arrow shows the wrong line because the stack says __libc_init_array().

    Reset_Handler:
...
    08002806:   cmp     r2, r3
    08002808:   bcc.n   0x80027fe <Reset_Handler+30>
    0800280a:   bl      0x8000128 <SystemInit>
    0800280e:   bl      0x8002834 <__libc_init_array>
 -> 08002812:   bl      0x80027d8 <main>
...

for __libc_init_array(), I hope the arrow is showing the right line and not showing the wrong next one.

    __libc_init_array:
    08002834:   eors    r0, r6
 -> 08002836:   stmdb   sp!, {r2, r3, r5, r6, sp, lr}
    0800283a:   b.n     0x800237c <SPIx_Write+8>
    0800283c:   str     r4, [r5, r1]
...

For WWDG_IRQHandler(), it isn't important, but post it anyway

    WWDG_IRQHandler:
 -> 08002830:   b.n     0x8002830 <WWDG_IRQHandler>
    08002832:   movs    r0, r0

My "c" code only contains include (the main function is not reached) :

#include <stm32l0538_discovery.h>
#include <sys/types.h>

For the configuration on eclipse, I didn't use any plugin, I set it as :

C/C++ Build
|
|_Cross Settings
| |_Prefix : arm-none-eabi-
| \_Path : /.../gcc-arm-none-eabi-7-2017-q4-major/bin
|
|_Cross Gcc Compiler
| |_Command : gcc
| |_All Options : -nostdinc
| |               -I/.../gcc-arm-none-eabi-7-2017-q4-major/lib/gcc/arm-none-eabi/7.2.1/include
| |               -I/.../gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/include
| |               -I/.../STM32Cube_FW_L0_V1.10.0/Drivers/BSP/STM32L0538-Discovery
| |               -I/.../STM32Cube_FW_L0_V1.10.0/Drivers/CMSIS/Include
| |               -I/.../STM32Cube_FW_L0_V1.10.0/Drivers/STM32L0xx_HAL_Driver/Inc
| |               -I/.../STM32Cube_FW_L0_V1.10.0/Drivers/CMSIS/Device/ST/STM32L0xx/Include
| |               -Os
| |               -g3
| |               -Wall
| |               -Wextra
| |               -mcpu=cortex-m0plus
| |               -march=armv6s-m
| |               -mlittle-endian
| |               -mthumb
| |               -DSTM32L053xx
| |               -c
| |               -v
| \_Command line pattern : ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
|
|_Cross Gcc Linker
| |_command : gcc
| |_All Options : -static
| |               -L/.../gcc-arm-none-eabi-7-2017-q4-major/
| |               -L/.../gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/lib
| |               -L/.../gcc-arm-none-eabi-7-2017-q4-major/lib
| |               -L/.../gcc-arm-none-eabi-7-2017-q4-major/lib/gcc/arm-none-eabi/7.2.1
| |               -mcpu=cortex-m0plus
| |               -march=armv6s-m
| |               -mlittle-endian
| |               -mthumb
| |               -DSTM32L053xx
| |               -T/.../STM32Cube_FW_L0_V1.10.0/Projects/STM32L053C8-Discovery/Templates/TrueSTUDIO/STM32L053C8_Discovery/STM32L053C8_FLASH.ld
| |               -Wl,--gc-sections
| |               -Os
| \_Command line pattern: ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
|
\_Cross GCC Assembler
  |_command : as
  |_all options: /*blank*/
  \_Command line pattern : ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

In the LD file, I see only two things maybe interesting, I don't CP the whole file :

    /* Entry Point */
    ENTRY(Reset_Handler)
...
    /* Remove information from the standard libraries */
    /DISCARD/ :
    {
      libc.a ( * )
      libm.a ( * )
      libgcc.a ( * )
    }
...

The startup is the one provided by ST, easily recoverable on Gogole, like this file :
https://github.com/AndiceLabs/STM32L053R8-Nucleo/blob/master/Drivers/CMSIS/Device/ST/STM32L0xx/Source/Templates/gcc/startup_stm32l053xx.s
Except, the line 151 is set to 0 by me, and off course lines 205/206 are not in the file I have.

I'm not the master of libc and setting environments, I tried many things like (un)cheking "nostdlibs", "nostartfiles" or "nodefaultlibs". But it results always with failing the compilation.

I don't really know what trying yet, please light me the path ! Thank you !

Jibz


After some research, I'm sure that it isn't a problem related to the stack pointer SP.
Back to the code :

    __libc_init_array:
    08002834:   eors    r0, r6
 -> 08002836:   stmdb   sp!, {r2, r3, r5, r6, sp, lr}
    0800283a:   b.n     0x800237c <SPIx_Write+8>
    0800283c:   str     r4, [r5, r1]
...

Regarding the instruction set from different cortex (M0 to M4F) the STMDB instruction is not included in the instruction set of the cortex-M0, the cortex-M0+ has only the STM instruction (third white column, 10th line for the STM, and first blue column, 17th line for STMDB).

Right from the page of GNU Arm Embedded Toolchain (https://developer.arm.com/open-source/gnu-toolchain/gnu-rm) it is written that the Cortex-M0(+) is supported, so I guess with the C librairy. On other website they suggest to test the gcc multi-librairies, I try it and :

[jibz@Jazptop bin]$ ./arm-none-eabi-gcc --print-multi-lib
.;
thumb;@mthumb
hard;@mfloat-abi=hard
thumb/v6-m;@mthumb@march=armv6s-m
thumb/v7-m;@mthumb@march=armv7-m
thumb/v7e-m;@mthumb@march=armv7e-m
thumb/v7-ar;@mthumb@march=armv7
thumb/v8-m.base;@mthumb@march=armv8-m.base
thumb/v8-m.main;@mthumb@march=armv8-m.main
thumb/v7e-m/fpv4-sp/softfp;@mthumb@march=armv7e-m@mfpu=fpv4-sp-d16@mfloat-abi=softfp
thumb/v7e-m/fpv4-sp/hard;@mthumb@march=armv7e-m@mfpu=fpv4-sp-d16@mfloat-abi=hard
thumb/v7e-m/fpv5/softfp;@mthumb@march=armv7e-m@mfpu=fpv5-d16@mfloat-abi=softfp
thumb/v7e-m/fpv5/hard;@mthumb@march=armv7e-m@mfpu=fpv5-d16@mfloat-abi=hard
thumb/v7-ar/fpv3/softfp;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=softfp
thumb/v7-ar/fpv3/hard;@mthumb@march=armv7@mfpu=vfpv3-d16@mfloat-abi=hard
thumb/v8-m.main/fpv5-sp/softfp;@mthumb@march=armv8-m.main@mfpu=fpv5-sp-d16@mfloat-abi=softfp
thumb/v8-m.main/fpv5-sp/hard;@mthumb@march=armv8-m.main@mfpu=fpv5-sp-d16@mfloat-abi=hard
thumb/v8-m.main/fpv5/softfp;@mthumb@march=armv8-m.main@mfpu=fpv5-d16@mfloat-abi=softfp
thumb/v8-m.main/fpv5/hard;@mthumb@march=armv8-m.main@mfpu=fpv5-d16@mfloat-abi=hard

I believe that it is installed, as the Cortex-M0+ is on the architecture ARMv6-M. But the result shows ARMv6s-M, does it change something ?

Anyway, I still don't know how to have the right libc.


Solution

  • After writing with someone, he shows me errors I made in the configuration, so I post here (again) the configuration :

    |_Cross Settings : Prefix : arm-none-eabi-
    |                  Path : ${GccPath}/bin
    | 
    |_Cross Gcc Compiler : command : gcc
    | |_Preprocessor : uncheck "Do not search system directories(-nostdinc)",
    | |                I believed that I will search in the native system x64
    | |                machin, but no, it just means that it will search in
    | |                the GCC folder.
    | |                -D STM32L053xx :needed to use some code provided by ST
    | |_Includes : removing all references of path to /gcc/*/include because
    | |            now they are included without the -nostdinc option.
    | |            -I ${DriversPath}/BSP/STM32L0538-Discovery
    | |            -I ${DriversPath}/CMSIS/Include
    | |            -I ${DriversPath}/STM32L0xx_HAL_Driver/Inc
    | |            -I ${DriversPath}/CMSIS/Device/ST/STM32L053xx/Include
    | |_Optimization : Optimization level : Optimization for size (-Os)
    | |_Debugging : Debug Level : Maximum (-g3)
    | |_Warnings : All Warnings (-Wall)
    | |            Extra warnings (-Wextra)
    | \_Miscellaneous : -mcpu=cortex-m0plus   : with march, GCC will know which lib it should use, and not using the first found in the paths provided previously with the linker option -L.
    |                   -march=armv6s-m
    |                   -mlittle-endian
    |                   -mthumb
    |                   -c
    |                   -ffunction-sections   : it permits to remove not necessary code
    |                   -fdata-sections       : it permits to remove not necessary data.
    |                   -v (Verbose)
    |
    \_Cross GCC Linker : command : gcc
      |_general : No shared libraries (-static)
      |_Libraries : it should stay blank, I removed all -L options.
      \_Miscellaneous : -mcpu=cortex-m0plus
                        -mtune=cortex-m0plus  :Actually, I believe it is just an optimization for **that** cpu.
                        -march=armv6s-m
                        -mlittle-endian
                        -mthumb
                        -T${ProjDirPath}/LinkerScripts/STM32L053C8_FLASH.ld
                        -Wl,-Map=${ProjDirPath}/Logs/Pluviographe.map : The map file is a kind of log, showing links between elements. 
                        -Wl,-gc-sections : It removes some unused code, provided by the -ffunctions-sections and -fdata-sections from the compiler.
    

    There is maybe still "small" errors in the code, but it is more clean.