cgdbembeddedclionsegger-jlink

GDB debugging breaks without breakpoints with Infineon XMC4800 MCU and Segger


We have a EtherCAT project and for this we are using the XMC4800 MCU from Infineon. I was working in Dave (their IDE) first, but because it is not CMAKE based I ran into issues with adding re-usable libs (we use CPM for this).

So I decided to try and create a CMakeLists.txt file for the Dave project and see if I could open/compile the project in CLion.

After a couple of hours I was able to get the project building in CLion. (I just open Dave to make changes to the Hardware settings)

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
cmake_minimum_required(VERSION 3.17)

# specify cross compilers and tools
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_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
set(SIZE arm-none-eabi-size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# project settings
project(L16_V2 C CXX ASM)
set(CMAKE_CXX_STANDARD 99)
set(CMAKE_C_STANDARD 99)


add_compile_definitions(XMC4800_F144x2048)
add_compile_options(-O0 -lm -ffunction-sections -fdata-sections -Wall 
    -std=gnu99 -mfloat-abi=softfp -Wa,-adhlns="$@.lst" -pipe -c 
    -fmessage-length=0 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mthumb -g -gdwarf-2)

# uncomment to mitigate c++17 absolute addresses warnings
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register")

if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    message(STATUS "Maximum optimization for speed")
    add_compile_options(-Ofast)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
    message(STATUS "Maximum optimization for speed, debug info included")
    add_compile_options(-Ofast -g)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
    message(STATUS "Maximum optimization for size")
    add_compile_options(-Os)
else ()
    message(STATUS "Minimal optimization, debug info included")
    add_compile_options(-Og -g)
endif ()

include_directories(SSC/Src Dave/Generated/PWM 
    Dave/Generated/SYSTIMER Dave/Generated/INTERRUPT 
    Dave/Generated/PIN_INTERRUPT Dave/Generated/SPI_MASTER 
    Dave/Generated/ECAT_SSC Dave/Generated/GLOBAL_CCU4 
    Dave/Generated/GLOBAL_CCU8 Dave/Generated/EVENT_DETECTOR 
    Dave/Generated/EVENT_GENERATOR Dave/Generated/E_EEPROM_XMC4 
    Dave/Generated/GLOBAL_ADC Dave/Generated/ADC_MEASUREMENT 
    Dave/Generated/BUS_IO Dave/Generated/CLOCK_XMC4 
    Dave/Generated/CPU_CTRL_XMC4 Dave/Generated/DIGITAL_IO Startup 
    Dave/Generated Libraries/CMSIS/Include 
    Libraries/CMSIS/Infineon/XMC4800_series/Include 
    Libraries/XMCLib/inc SSC/Src)

add_definitions(-DXMC4800_F144x2048 -O0 -ffunction-sections -fdata-sections 
    -Wall -std=gnu99 -mfloat-abi=softfp -Wa,-adhlns="$@.lst" 
    -pipe -c -fmessage-length=0 -mcpu=cortex-m4 
    -mfpu=fpv4-sp-d16 -mthumb -g -gdwarf-2)

file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} 
    "Dave/Generated/*.c" "Startup/*.*" "Libraries/*.c" 
    "SSC/Src/*.c")

set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/linker_script_IAP.ld)

add_link_options(-Wl,-gc-sections,--print-memory-usage,
    -Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)

add_link_options(-T ${LINKER_SCRIPT})

add_link_options(-nostartfiles -Xlinker --gc-sections 
    -specs=nano.specs -specs=nosys.specs -mfloat-abi=softfp 
    -mfpu=fpv4-sp-d16 -mcpu=cortex-m4 -mthumb -g -gdwarf-2)


SET(CMAKE_C_FLAGS_DEBUG "-D_DEBUG")

add_executable(${PROJECT_NAME}.elf ${SOURCES} main.c lamp.c PID.c 
    firmwareupdate_SSC.c firmwareupdate_SSC.h 
    flashprog.c ad5328.c ${LINKER_SCRIPT})

target_link_libraries(${PROJECT_NAME}.elf m)

set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)


add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
        COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
        COMMENT "Building ${HEX_FILE}
    Building ${BIN_FILE}")

I then setup the "Embedded GDB Server" debug target in combination with a Segger J-link Plus (SWD)

This uploads the compiled application and the target starts running fine. (I make it blink a LED)

The issue is that when I enable break-points it does not break on the breakpoints that I place, but it just breaks at completely other locations. (in my case on the first line of an int handler)

When I debug with the same setup in Dave it works fine.

I tried with both the bundled GDB as with the GNU GDB, it makes no difference

It could be related that this project uses a bootloader (a separate project that I build and flash from Dave)

this is the used Linker script:

/**
 * @file XMC4800x2048.ld
 * @date 2019-08-02
 *
 * @cond
 *********************************************************************************************************************
 * Linker file for the GNU C Compiler v1.2
 * Supported devices: XMC4800-E196x2048
 *                    XMC4800-F144x2048
 *                    XMC4800-F100x2048
 *
 * Copyright (c) 2015-2019, Infineon Technologies AG
 * All rights reserved.                        
 *                                             
 * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the 
 * following conditions are met:   
 *                                                                              
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following 
 * disclaimer.                        
 * 
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
 * disclaimer in the documentation and/or other materials provided with the distribution.                       
 * 
 * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote 
 * products derived from this software without specific prior written permission.                                           
 *                                                                              
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR  
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                  
 *                                                                              
 * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with 
 * Infineon Technologies AG dave@infineon.com).                                                          
 *********************************************************************************************************************
 *
 * Change History
 * --------------
 *
 * 2015-05-22:
 *     - Initial version
 *
 * 2015-07-13:
 *     - Updates from ARM template for C++ and fixes for GCC 4.9q2
 * 
 * 2016-03-08:
 *     - Fix size of BSS and DATA sections to be multiple of 4
 *     - Add assertion to check that region SRAM_combined does not overflowed no_init section  
 *             
 * 2019-08-02
 *     - Fix size of flash reserved to application to 896KB     
 * 
 * @endcond 
 *
 */

OUTPUT_FORMAT("elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(Reset_Handler)

stack_size = DEFINED(stack_size) ? stack_size : 2048;
no_init_size = 64;

MEMORY
{
  FLASH_0_cached(RX) : ORIGIN = 0x08000000, LENGTH = 0x00010000
  FLASH_0_uncached(RX) : ORIGIN = 0x0C000000, LENGTH = 0x00010000
  FLASH_1_cached(RX) : ORIGIN = 0x08020000, LENGTH = 0x000E0000
  FLASH_1_uncached(RX) : ORIGIN = 0x0C020000, LENGTH = 0x000E0000
  PSRAM_1(!RX) : ORIGIN = 0x1FFE8000, LENGTH = 0x18000
  DSRAM_1_system(!RX) : ORIGIN = 0x20000000, LENGTH = 0x20000
  DSRAM_2_comm(!RX) : ORIGIN = 0x20020000, LENGTH = 0x20000
  SRAM_combined(!RX) : ORIGIN = 0x1FFE8000, LENGTH = 0x00058000
}

SECTIONS
{
  /* TEXT section */

  .text : ALIGN (4)
  {
    sText = .;
    KEEP(*(.reset));
    *(.text .text.* .gnu.linkonce.t.*);

    /* C++ Support */
    KEEP(*(.init))
    KEEP(*(.fini))

    /* .ctors */
    *crtbegin.o(.ctors)
    *crtbegin?.o(.ctors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    *(SORT(.ctors.*))
    *(.ctors)

    /* .dtors */
    *crtbegin.o(.dtors)
    *crtbegin?.o(.dtors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    *(SORT(.dtors.*))
    *(.dtors)

    *(.rodata .rodata.*)
    *(.gnu.linkonce.r*)
        
  } > FLASH_1_cached AT > FLASH_1_uncached

  .eh_frame_hdr : ALIGN (4)
  {
    KEEP (*(.eh_frame_hdr))
  } > FLASH_1_cached AT > FLASH_1_uncached
  
  .eh_frame : ALIGN (4)
  {
    KEEP (*(.eh_frame))
  } > FLASH_1_cached AT > FLASH_1_uncached

  /* Exception handling, exidx needs a dedicated section */
  .ARM.extab : ALIGN(4)
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } > FLASH_1_cached AT > FLASH_1_uncached

  . = ALIGN(4);
  __exidx_start = .;
  .ARM.exidx : ALIGN(4)
  {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  } > FLASH_1_cached AT > FLASH_1_uncached
  __exidx_end = .;
  . = ALIGN(4);
    
    /* DSRAM layout (Lowest to highest)*/
  Stack (NOLOAD) : 
  {
    __stack_start = .;
    . = . + stack_size;
    __stack_end = .;
    __initial_sp = .;
  } > SRAM_combined

  /* functions with __attribute__((section(".ram_code"))) */
  .ram_code :
  {
    . = ALIGN(4); /* section size must be multiply of 4 */        
    __ram_code_start = .;
    *(.ram_code)
    . = ALIGN(4); /* section size must be multiply of 4 */
    __ram_code_end = .;
  } > SRAM_combined AT > FLASH_1_uncached
  __ram_code_load = LOADADDR (.ram_code);
  __ram_code_size = __ram_code_end - __ram_code_start;

  /* Standard DATA and user defined DATA/BSS/CONST sections */
  .data :
  {
    . = ALIGN(4); /* section size must be multiply of 4 */        
    __data_start = .;
    *(vtable)        
    * (.data);
    * (.data*);
    *(*.data);
    *(.gnu.linkonce.d*)
      
    . = ALIGN(4);
    /* preinit data */
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP(*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);

    . = ALIGN(4);
    /* init data */
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP(*(SORT(.init_array.*)))
    KEEP(*(.init_array))
    PROVIDE_HIDDEN (__init_array_end = .);

    . = ALIGN(4);
    /* finit data */
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP(*(SORT(.fini_array.*)))
    KEEP(*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);

    . = ALIGN(4); /* section size must be multiply of 4 */
    __data_end = .;
  } > SRAM_combined AT > FLASH_1_uncached
  __data_load = LOADADDR (.data);
  __data_size = __data_end - __data_start;
        
  /* BSS section */
  .bss (NOLOAD) : 
  {
    . = ALIGN(4); /* section size must be multiply of 4 */        
    __bss_start = .;
    * (.bss);
    * (.bss*);
    * (COMMON);
    *(.gnu.linkonce.b*)
    . = ALIGN(4); /* section size must be multiply of 4 */
    __bss_end = .;
  } > SRAM_combined
  __bss_size = __bss_end - __bss_start;

  /* Shift location counter, so that ETH_RAM and USB_RAM are located above DSRAM_1_system */    
  __shift_loc =  (__bss_end >= ORIGIN(DSRAM_1_system)) ? 0 : (ORIGIN(DSRAM_1_system) - __bss_end);

  USB_RAM  (__bss_end + __shift_loc) (NOLOAD) :
  {
    . = ALIGN(4); /* section size must be multiply of 4 */        
    USB_RAM_start = .;
    *(USB_RAM)
    . = ALIGN(4); /* section size must be multiply of 4 */
    USB_RAM_end = .;
  } > SRAM_combined
  USB_RAM_size = USB_RAM_end - USB_RAM_start;

  ETH_RAM (USB_RAM_end) (NOLOAD) :
  {
    . = ALIGN(4); /* section size must be multiply of 4 */        
    ETH_RAM_start = .;
    *(ETH_RAM)
    . = ALIGN(4); /* section size must be multiply of 4 */
    ETH_RAM_end = .;
    . = ALIGN(8);
    Heap_Bank1_Start = .;
  } > SRAM_combined
  ETH_RAM_size = ETH_RAM_end - ETH_RAM_start;

  /* .no_init section contains chipid, SystemCoreClock and trimming data. See system.c file*/
  .no_init ORIGIN(SRAM_combined) + LENGTH(SRAM_combined) - no_init_size (NOLOAD) : 
  {
    Heap_Bank1_End = .;
    * (.no_init);
  } > SRAM_combined

  /* Heap - Bank1*/
  Heap_Bank1_Size  = Heap_Bank1_End - Heap_Bank1_Start;

  ASSERT(Heap_Bank1_Start <= Heap_Bank1_End, "region SRAM_combined overflowed no_init section")

  /DISCARD/ :
  {
    *(.comment)
  }

  .stab   0 (NOLOAD) : { *(.stab) }
  .stabstr  0 (NOLOAD) : { *(.stabstr) }

  /* DWARF 1 */
  .debug        0 : { *(.debug) }
  .line       0 : { *(.line) }

  /* GNU DWARF 1 extensions */
  .debug_srcinfo    0 : { *(.debug_srcinfo) }
  .debug_sfnames    0 : { *(.debug_sfnames) }

  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges    0 : { *(.debug_aranges) }
  .debug_pubnames   0 : { *(.debug_pubnames) }
  .debug_pubtypes   0 : { *(.debug_pubtypes) }

  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo    0 : { *(.debug_macinfo) }

  /* DWARF 2.1 */
  .debug_ranges   0 : { *(.debug_ranges) }

  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames  0 : { *(.debug_weaknames) }
  .debug_funcnames  0 : { *(.debug_funcnames) }
  .debug_typenames  0 : { *(.debug_typenames) }
  .debug_varnames   0 : { *(.debug_varnames) }

  /* Build attributes */
  .build_attributes 0 : { *(.ARM.attributes) }
}

EDIT:

I found this in the docs for the EtherCAT example:

enter image description here

enter image description here

enter image description here

Also they mention this:

Inside the linker file the start address of your application is defined The default linker file of DAVE projects defines the location of the vector table and program data to the flash start address 0x0C000000 To reserve space for EEPROM emulation the ECAT_SSC APP used inside your project , overwrites this default linker file with every code generation to remap the program data start address 0x0C000000 vector table 0x0C020000 program data This setting does not match to flash partitioning used for this example , because the vector table overlaps with the bootloader partition Instead , the following setting is needed 0x0C020000 vector table + program data

Could that have something todo with my issue?


Solution

  • I was able to get it working. After digging into the settings of the Dave project I copied the exact command line parameters for the GDB server from Dave into CLion and from then on the debugging worked as it should.

    -if swd -device XMC4800-F144x2048 -endian little -speed auto -port 2331 -swoport 2332 -telnetport 2333 -vd -ir -localhostonly 1 -singlerun -strict -timeout 0