1
\$\begingroup\$

I've recently run into this error where openocd wont flash the binary to my discovery board. I'm using the same linker script that i've been using all along.

arm-none-eabi-objdump gives the following output:

src/stm32_uavcan/stm32test: file format elf32-littlearm

Disassembly of section .init:

00008000 <_init>:
    8000: b5f8        push  {r3, r4, r5, r6, r7, lr}
    8002: bf00        nop
    8004: bcf8        pop {r3, r4, r5, r6, r7}
    8006: bc08        pop {r3}
    8008: 469e        mov lr, r3
    800a: 4770        bx  lr

Disassembly of section .text:

00008040 <exit>:
    8040: b508        push  {r3, lr}
    8042: 2100        movs  r1, #0
    8044: 4604        mov r4, r0
    8046: f002 fe91   bl  ad6c <__call_exitprocs>
    804a: 4b04        ldr r3, [pc, #16] ; (805c <exit+0x1c>)
    804c: 6818        ldr r0, [r3, #0]
    804e: 6bc3        ldr r3, [r0, #60] ; 0x3c
    8050: b103        cbz r3, 8054 <exit+0x14>
    8052: 4798        blx r3
    8054: 4620        mov r0, r4
    8056: f000 ff03   bl  8e60 <_exit>
    805a: bf00        nop
    805c: 0000eec8  .word 0x0000eec8

The flash addresses are completely off.

From what i know this is the correct address "0x08000000". And is defined as such in my linker script. Below is the copy of the relevant part of the linker script

MEMORY
{
  RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
  CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
  FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
  FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  MEMORY_ARRAY (xrw)  : ORIGIN = 0x20002000, LENGTH = 32
}

I'm using CMake. The project uses other third-party libraries as well, uavcan, chibios and stm32plus. I dont think that should be an issue. Below is the CMakeLists for this project.

cmake_minimum_required(VERSION 3.2)
project(stm32_uavcan)

list(APPEND CMAKE_PREFIX_PATH /usr/local/arm-none-eabi /usr/arm-none-eabi CACHE STRING "Library Search Paths")
set(MCU_FAMILY f429)

if((CMAKE_BUILD_TYPE MATCHES RelWithDebInfo))
  set(STM32PLUS_CONFIGURATION fast-${MCU_FAMILY}-8000000)
endif((CMAKE_BUILD_TYPE MATCHES RelWithDebInfo))

if((CMAKE_BUILD_TYPE MATCHES MinSizeRelease))
  set(STM32PLUS_CONFIGURATION small-${MCU_FAMILY}-8000000)
endif((CMAKE_BUILD_TYPE MATCHES MinSizeRelease))

if((CMAKE_BUILD_TYPE MATCHES Debug))
  set(STM32PLUS_CONFIGURATION debug-${MCU_FAMILY}-8000000)
endif((CMAKE_BUILD_TYPE MATCHES Debug))


set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")

find_package(stm32plus REQUIRED)


add_executable(stm32test 
        src/AX2550.cpp 
        src/main.cpp 
        src/LibraryHacks.cpp  
        src/ringbuf.c  
        src/system_stm32f4xx.c
        )
target_sources(stm32test
        PRIVATE
        ${CHIBIOS_SOURCES}
        )


target_include_directories(stm32test 
        PUBLIC 
            include 
            ${PROJECT_CONF_DIR}
            ${CHIBIOS_INCLUDE_DIRS} 
            ${STM32PLUS_INCLUDE_DIRS} 
            ${STM32PLUS_FWLIB_DIR} 
            ${STM32PLUS_DEVINC})

target_link_libraries(stm32test ${STM32PLUS_LIBS})

set_target_properties(stm32test PROPERTIES 
    CXX_STANDARD 14
    CXX_STANDARD_REQUIRED YES
    CXX_EXTENSIONS NO
)

I dont know how to solve this. Any advice or suggestions could really help me out.

Regards.

\$\endgroup\$
2
  • \$\begingroup\$ Where's the part of your linker script which specifies what goes into each type of memory? And what happened to your vector table? 0x800 0000 shouldn't be the initialization code itself, it should be the initial stack pointer value, followed by the address of the reset handler, followed by the other vectors. You program can only follow after that. \$\endgroup\$ Commented May 1, 2018 at 12:42
  • \$\begingroup\$ @ChrisStratton : sorry for not including the necessary files. I only showed the part where different memory regions where being defined. I fixed the issue though. I had another Cmake include file which was resetting my CMAKE_EXE_LINKER_FLAGS. Removing that part fixed the issue. If for future reference, to help anyone having a similar issue you'd like me to post the linker scripts here. I'd be happy to do so. But these are standard Chibios provided linker scripts for STM32F429I-Discovery. \$\endgroup\$
    – Asusrog
    Commented May 1, 2018 at 13:52

1 Answer 1

1
\$\begingroup\$

I'm posting this to clarify what fixed the issue. Although i dont quite understand how this resolved the issue. Probably @chrisStratton would be able to help me figure it out. Below is my Toolchain File.

cmake_minimum_required(VERSION 3.2)
include(CMakeForceCompiler)

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CPU "-mcpu=cortex-m4")
set(FPU "-mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1")


set(CMAKE_C_FLAGS "${CPU} ${FPU} -Wall -Werror -Wno-unused-but-set-variable -ffunction-sections -fdata-sections -MD -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops -ffast-math --specs=rdimon.specs -lgcc -lc -lm -lrdimon -fno-exceptions -mthumb -gdwarf-2 -pipe -DHSE_VALUE=8000000 -DSTM32PLUS_F429 -O0 -g3" CACHE INTERNAL "c compiler flags")
set(CMAKE_CXX_FLAGS "${CPU} ${FPU} -Wall -Werror -Wno-register -Wno-implicit-fallthrough -fno-builtin -ffunction-sections -nostartfiles -fdata-sections -fno-exceptions -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops --specs=nosys.specs -mthumb -lgcc -lc -lm -lrdimon -gdwarf-2 -pipe -DHSE_VALUE=8000000 -DSTM32PLUS_F429 -O0 -g3 -Wno-error=attributes -pedantic-errors -fno-rtti -flto" CACHE INTERNAL "cxx compiler flags")
set(CMAKE_ASM_FLAGS "-mthumb ${CPU} ${FPU} -x assembler-with-cpp" CACHE INTERNAL "asm compiler flags")

set(CMAKE_EXE_LINKER_FLAGS "-Xlinker --gc-sections -mthumb -g3 -gdwarf-2 -mcpu=cortex-m4" CACHE INTERNAL "executable linker flags")
set(CMAKE_MODULE_LINKER_FLAGS "-Xlinker --gc-sections -mthumb -g3 -gdwarf-2 -mcpu=cortex-m4" CACHE INTERNAL "module linker flags")
set(CMAKE_SHARED_LINKER_FLAGS "-Xlinker --gc-sections -mthumb -g3 -gdwarf-2 -mcpu=cortex-m4" CACHE INTERNAL "shared linker flags")

set(LINKER_SCRIPT_T1 ${CMAKE_CURRENT_LIST_DIR}/../mem.ld CACHE INTERNAL "mem linker script")
set(LINKER_SCRIPT_T2 ${CMAKE_CURRENT_LIST_DIR}/../sections.ld CACHE INTERNAL "sections linker script")
set(LINKER_SCRIPT_T3 ${CMAKE_CURRENT_LIST_DIR}/../libs.ld CACHE INTERNAL "libs linker script")
set(LINKER_SPECS ${CMAKE_CURRENT_LIST_DIR}/../stm32.specs CACHE INTERNAL "stm32 specs")

set(CHIBIOS_LINKER ${CMAKE_CURRENT_LIST_DIR}/../STM32F429xI.ld CACHE INTERNAL "chibios linker")
set(CHIBIOS_LINKER_data ${CMAKE_CURRENT_LIST_DIR}/../rules_data.ld CACHE INTERNAL "chibios data linker")
set(CHIBIOS_LINKER_stack ${CMAKE_CURRENT_LIST_DIR}/../rules_stacks.ld CACHE INTERNAL "chibios stack linker")
set(CHIBIOS_LINKER_code ${CMAKE_CURRENT_LIST_DIR}/../rules_code.ld CACHE INTERNAL "chibios code linker")

#__process_stack_size__ and __main_stack_size__ are Chibios specific symbols.

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-wrap,__aeabi_unwind_cpp_pr0 -Wl,-wrap,__aebi_unwind_cpp_pr1 -Wl,-wrap,__aeabi_unwind_cpp_pr2 -T${CHIBIOS_LINKER} -Wl,-Map=memmap.map -Wl,--defsym=__process_stack_size__=0x400 -Wl,--defsym=__main_stack_size__=0x400")

cmake_force_c_compiler(arm-none-eabi-gcc GNU)
cmake_force_cxx_compiler(arm-none-eabi-g++ GNU)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
#enable_language(ASM)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy CACHE INTERNAL "objcopy tool")
set(CMAKE_OBJDUMP arm-none-eabi-objdump CACHE INTERNAL "objdump tool")


set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

This gets included from the TopLevel and i had another cmake include file which set the install and include variables for a third-party library. Provided by the library itself. What i didn't notice earlier was that it was doing all the Compiler and linker related flag setting again. Below is the aforementioned cmake file:

Culprit Code from Here
include(CMakeForceCompiler)

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_FLAGS "-Wall -Werror -Wno-implicit-fallthrough -Wno-error=attributes -ffunction-sections -fdata-sections -fno-exceptions -mthumb -gdwarf-2 -pipe -DHSE_VALUE=8000000 -mcpu=cortex-m4 -DSTM32PLUS_F407 -mfloat-abi=hard -O3" CACHE INTERNAL "c compiler flags")
set(CMAKE_CXX_FLAGS "-Wall -Werror -Wno-implicit-fallthrough -Wno-error=attributes -ffunction-sections -fdata-sections -fno-exceptions -mthumb -gdwarf-2 -pipe -DHSE_VALUE=8000000 -mcpu=cortex-m4 -DSTM32PLUS_F407 -mfloat-abi=hard -O3 -Wextra -pedantic-errors -fno-rtti -std=gnu++0x -fno-threadsafe-statics" CACHE INTERNAL "cxx compiler flags")
set(CMAKE_ASM_FLAGS "-mcpu=cortex-m4" CACHE INTERNAL "asm compiler flags")

set(CMAKE_EXE_LINKER_FLAGS "-Xlinker --gc-sections -mthumb -g3 -gdwarf-2 -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16" CACHE INTERNAL "executable linker flags")
set(CMAKE_MODULE_LINKER_FLAGS "-Xlinker --gc-sections -mthumb -g3 -gdwarf-2 -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16" CACHE INTERNAL "module linker flags")
set(CMAKE_SHARED_LINKER_FLAGS "-Xlinker --gc-sections -mthumb -g3 -gdwarf-2 -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16" CACHE INTERNAL "shared linker flags")

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-wrap,__aeabi_unwind_cpp_pr0 -Wl,-wrap,__aeabi_unwind_cpp_pr1 -Wl,-wrap,__aeabi_unwind_cpp_pr2 -Wl,-wrap,atexit")

set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER (arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy CACHE INTERNAL "objcopy tool")
set(CMAKE_OBJDUMP arm-none-eabi-objdump CACHE INTERNAL "objdump tool")

cuplrit Code ends here

get_filename_component(INSTALLDIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
message(STATUS "Using stm32plus install: ${INSTALLDIR}")
message(STATUS "Using stm32plus prefix:  stm32plus-040100")
add_definitions("-DSTM32PLUS_BUILD")

set(STM32PLUS_INSTALLDIR "${INSTALLDIR}" CACHE INTERNAL "stm32plus installdir")
set(STM32PLUS_LIBS "${INSTALLDIR}/lib/stm32plus-040100/libstm32plus-fast-f4-8000000e-hard.a" CACHE INTERNAL "library location")

# These paths cover your bases if you're using pure stm32plus interfaces.
set(STM32PLUS_INCLUDE_DIRS
  ${INSTALLDIR}/include/stm32plus-040100/
  ${INSTALLDIR}/include/stm32plus-040100/stl)

# You'll need include paths under here if you're calling into stdperiph or cmsis directly.
set(STM32PLUS_FWLIB_DIR ${INSTALLDIR}/include/stm32plus-040100/fwlib)

function(add_bin_target TARGET)
  if(EXECUTABLE_OUTPUT_PATH)
    set(FILENAME "${EXECUTABLE_OUTPUT_PATH}/${TARGET}")
  else()
    set(FILENAME "${TARGET}")
  endif()
  add_custom_target(${TARGET}.bin ALL COMMAND ${CMAKE_OBJCOPY} -Obinary ${FILENAME} ${FILENAME}.bin)
  add_dependencies(${TARGET}.bin ${TARGET})
endfunction()

Although

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ....")

is supposed to append to the already existing linker flags. I wonder if include(CMakeForceCompiler) line deletes the old CMake cross-compiling macros. Please do let me know if you have a better explanation to this. As i'm new to CMake and not very well versed at its nuances. Would be great if i end up learning something out of this.

Regards.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.