Summer Nights

A blog on embedded and real-time systems as well as on general computing issues

Tutorial: Setting-up ARM Cortex-M3 Development Enviroment using Codesourcery Toolchain, Eclipse, and Segger J-Link Debugger

As can also be inferred from the title, we need three basic components:

  1. Eclipse CDT
  2. Codesourcery Lite for ARM Toolchain
  3. Segger J-Link Debugger/Emulator

Eclipse CDT is a C/C++ development IDE based on Eclipse (which defaults to Java development).

Codesourcery Lite is gcc-based ARM toolchain which provides all the basic ingredients (compiler, assembler, archiver, linker, libraries, newlib, binutils, etc.) in console based executables. The best thing about Codesourcery is that they also offer commercial solutions which result in quarterly updates to the Lite tool-chain also. This way you always stay inline with the latest gcc developments.

Segger J-Link is a very good JTAG/SWD debugger for ARM targets. If you are not for the commercial development, you can purchase an EDU version which costs around 70 Euro (incl. postage) and is worth every penny.

Installation

  • Download and install Eclipse CDT on your computer. In most cases, installation is merely creating a shortcut to eclipse.exe in the downloaded and uncompressed eclipse folder.
  • Install all necessary components in Eclipse CDT required for embedded development and debugging as shown in the following image. These can be installed from “Help->Install New Software”. Especially important are “GDB Hardware Debugging” and “Eclipse Debugger for C/C++”.

  • Download and install Codesourcery. Let it change your PATH so that Eclipse can find the proper tools it needs during compilation.
  • Test the Codesourcery install by opening a command prompt and typing the following:

    C:\>arm-none-eabi-gcc --version
    arm-none-eabi-gcc (Sourcery G++ Lite 2010q1-188) 4.4.1
    Copyright (C) 2009 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    You should see a response similar to given above. If windows complains about unknown or unrecognized command, then Codesourcery has not been properly installed or the PATH information is not updated. Please follow Codesourcery Getting Started Guide for further information to solve this problem.

  • Now download and import (hint: import existing projects into workspace) the following two projects in an Eclipse workspace from here:
    1. libSTM32F103
    2. Blinky_STM32F103
  • After import, the workspace should look similar to the following:


    As you can see, it contains the library for STM32 device and a blinky project to flash an LED.

  • If you right click on the libSTM32F103 (or any project for that sake), you can go into “Build Configuration -> Set Active” to set Debug or Release configuration as active. Here we choose Debug as shown in the figure below:

  • Now if you right click on libSTM32F103 project and select “Build Project”, you should see the output similar to the following in Console:

    **** Build of configuration Debug for project libSTM32F103 ****

    cs-make all
    Building file: stm32f10x_adc.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_adc.o ../src/stm32f10x_adc.c
    Finished building: stm32f10x_adc.c

    Building file: stm32f10x_bkp.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_bkp.o ../src/stm32f10x_bkp.c
    Finished building: stm32f10x_bkp.c

    Building file: stm32f10x_can.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_can.o ../src/stm32f10x_can.c
    Finished building: stm32f10x_can.c

    Building file: stm32f10x_dma.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_dma.o ../src/stm32f10x_dma.c
    Finished building: stm32f10x_dma.c

    Building file: stm32f10x_exti.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_exti.o ../src/stm32f10x_exti.c
    Finished building: stm32f10x_exti.c

    Building file: stm32f10x_flash.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_flash.o ../src/stm32f10x_flash.c
    Finished building: stm32f10x_flash.c

    Building file: stm32f10x_gpio.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_gpio.o ../src/stm32f10x_gpio.c
    Finished building: stm32f10x_gpio.c

    Building file: stm32f10x_i2c.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_i2c.o ../src/stm32f10x_i2c.c
    Finished building: stm32f10x_i2c.c

    Building file: stm32f10x_iwdg.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_iwdg.o ../src/stm32f10x_iwdg.c
    Finished building: stm32f10x_iwdg.c

    Building file: stm32f10x_lib.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_lib.o ../src/stm32f10x_lib.c
    Finished building: stm32f10x_lib.c

    Building file: stm32f10x_nvic.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_nvic.o ../src/stm32f10x_nvic.c
    Finished building: stm32f10x_nvic.c

    Building file: stm32f10x_pwr.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_pwr.o ../src/stm32f10x_pwr.c
    Finished building: stm32f10x_pwr.c

    Building file: stm32f10x_rcc.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_rcc.o ../src/stm32f10x_rcc.c
    Finished building: stm32f10x_rcc.c

    Building file: stm32f10x_rtc.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_rtc.o ../src/stm32f10x_rtc.c
    Finished building: stm32f10x_rtc.c

    Building file: stm32f10x_spi.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_spi.o ../src/stm32f10x_spi.c
    Finished building: stm32f10x_spi.c

    Building file: stm32f10x_systick.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_systick.o ../src/stm32f10x_systick.c
    Finished building: stm32f10x_systick.c

    Building file: stm32f10x_tim.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_tim.o ../src/stm32f10x_tim.c
    Finished building: stm32f10x_tim.c

    Building file: stm32f10x_tim1.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_tim1.o ../src/stm32f10x_tim1.c
    Finished building: stm32f10x_tim1.c

    Building file: stm32f10x_usart.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_usart.o ../src/stm32f10x_usart.c
    Finished building: stm32f10x_usart.c

    Building file: stm32f10x_wwdg.c
    Invoking: MCU C Compiler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -I .. -I ../inc -c -o objs/stm32f10x_wwdg.o ../src/stm32f10x_wwdg.c
    Finished building: stm32f10x_wwdg.c

    Building file: cortexm3_macro.s
    Invoking: MCU Assembler
    arm-none-eabi-gcc -O0 -ggdb -Wall -fno-strict-aliasing -fmessage-length=0 -fno-builtin -mthumb -mcpu=cortex-m3 -c -o objs/cortexm3_macro.o ../src/cortexm3_macro.s
    Finished building: cortexm3_macro.s

    arm-none-eabi-ar cr libstm32f103.a objs/stm32f10x_adc.o objs/stm32f10x_bkp.o objs/stm32f10x_can.o objs/stm32f10x_dma.o objs/stm32f10x_exti.o objs/stm32f10x_flash.o objs/stm32f10x_gpio.o objs/stm32f10x_i2c.o objs/stm32f10x_iwdg.o objs/stm32f10x_lib.o objs/stm32f10x_nvic.o objs/stm32f10x_pwr.o objs/stm32f10x_rcc.o objs/stm32f10x_rtc.o objs/stm32f10x_spi.o objs/stm32f10x_systick.o objs/stm32f10x_tim.o objs/stm32f10x_tim1.o objs/stm32f10x_usart.o objs/stm32f10x_wwdg.o objs/cortexm3_macro.o
    Finished building target: libstm32f103.a

    cs-make –no-print-directory post-build
    Performing post-build steps
    arm-none-eabi-size –totals libstm32f103.a
    text data bss dec hex filename
    2856 0 0 2856 b28 stm32f10x_adc.o (ex libstm32f103.a)
    460 0 0 460 1cc stm32f10x_bkp.o (ex libstm32f103.a)
    4088 0 0 4088 ff8 stm32f10x_can.o (ex libstm32f103.a)
    940 0 0 940 3ac stm32f10x_dma.o (ex libstm32f103.a)
    676 0 0 676 2a4 stm32f10x_exti.o (ex libstm32f103.a)
    204 0 0 204 cc stm32f10x_flash.o (ex libstm32f103.a)
    1652 0 0 1652 674 stm32f10x_gpio.o (ex libstm32f103.a)
    2776 0 0 2776 ad8 stm32f10x_i2c.o (ex libstm32f103.a)
    208 0 0 208 d0 stm32f10x_iwdg.o (ex libstm32f103.a)
    0 0 0 0 0 stm32f10x_lib.o (ex libstm32f103.a)
    2420 0 0 2420 974 stm32f10x_nvic.o (ex libstm32f103.a)
    500 0 0 500 1f4 stm32f10x_pwr.o (ex libstm32f103.a)
    2620 0 8 2628 a44 stm32f10x_rcc.o (ex libstm32f103.a)
    880 0 0 880 370 stm32f10x_rtc.o (ex libstm32f103.a)
    1520 0 0 1520 5f0 stm32f10x_spi.o (ex libstm32f103.a)
    428 0 0 428 1ac stm32f10x_systick.o (ex libstm32f103.a)
    6308 0 0 6308 18a4 stm32f10x_tim.o (ex libstm32f103.a)
    6488 0 0 6488 1958 stm32f10x_tim1.o (ex libstm32f103.a)
    2296 0 0 2296 8f8 stm32f10x_usart.o (ex libstm32f103.a)
    316 0 0 316 13c stm32f10x_wwdg.o (ex libstm32f103.a)
    110 0 0 110 6e cortexm3_macro.o (ex libstm32f103.a)
    37746 0 8 37754 937a (TOTALS)

    I have intentionally put the complete output because it can help to compare your output while looking for possible problems. This shows that the library has been properly compiled and put in an archive.

  • Now that everything is working properly, we need to know how we came to realize it. The magic lies in the Makefile which contains all the necessary commands to set the compiler, their flags, paths, etc. Beside the Makefile that we will discuss shortly, there are only two settings required in Eclipse for the compilation to occur correctly. The first is to make Eclipse aware of the Codesourcery make (called cs-make) and the second is to let Eclipse know where the “make” should be called. Both of these settings are shown in the figure below:

    As can be seen, we use Eclipse macros to define the location of the Makefile as:
    ${workspace_loc:/${ProjName}/Debug}. Similarly, for Release configuration, the location would change to:
    ${workspace_loc:/${ProjName}/Release}.

  • In addition to that, we must also choose proper Binary Parsers and addr2line tools. To this end, please make appropriate changes according to the following image:

  • The Makefile is the most important file in the build process. In our case, for compilation of the library, we use the following Makefile:

    #################################################################
    # Makefile to generate “archived” library for embedded targets.
    # Author: Asif Iqbal (a.iqbal@ieee.org)
    # Date: 6th October, 2010
    #################################################################

    CPU := cortex-m3
    INSTRUCTION_MODE := thumb
    TARGET := libstm32f103
    TARGET_EXT := a
    COMPILER_OPTIONS := -O0 -ggdb -Wall -fno-strict-aliasing \
    -fmessage-length=0 -fno-builtin -m$(INSTRUCTION_MODE) -mcpu=$(CPU)
    INCLUDE := -I ..
    INCLUDE += -I ../inc
    SRC_FOLDER := ../src
    OBJ_FOLDER := objs

    CC = arm-none-eabi-gcc
    CFLAGS = $(COMPILER_OPTIONS) $(INCLUDE) -c

    CXX = arm-none-eabi-g++
    CXXFLAGS = $(COMPILER_OPTIONS) $(INCLUDE) -c

    AS = arm-none-eabi-gcc
    ASFLAGS = $(COMPILER_OPTIONS) -c

    OBJCP = arm-none-eabi-objcopy
    OBJCPFLAGS = -O ihex

    AR = arm-none-eabi-ar
    ARFLAGS = cr

    RM := rm -rf

    O_SRCS :=
    C_SRCS :=
    S_SRCS :=
    C_OBJS :=
    S_OBJS :=

    # All of the sources participating in the build are defined here

    C_SRCS += $(wildcard $(SRC_FOLDER)/*.c)
    S_SRCS += $(wildcard $(SRC_FOLDER)/*.s)
    C_OBJS += $(notdir $(patsubst %.c,%.o,$(C_SRCS)))
    S_OBJS += $(notdir $(OBJ_FOLDER)/$(patsubst %.s,%.o,$(S_SRCS)))

    # First compile C sources
    $(C_OBJS) : $(C_SRCS)
    @echo ‘Building file: $(@:%.o=%.c)’
    @echo ‘Invoking: MCU C Compiler’
    $(CC) $(CFLAGS) -o $(OBJ_FOLDER)/$@ $(SRC_FOLDER)/$(@:%.o=%.c)
    @echo ‘Finished building: $(@:%.o=%.c)’
    @echo ‘ ‘
    # Now compile ASS sources
    $(S_OBJS) : $(S_SRCS)
    @echo ‘Building file: $(@:%.o=%.s)’
    @echo ‘Invoking: MCU Assembler’
    $(AS) $(ASFLAGS) -o $(OBJ_FOLDER)/$@ $(SRC_FOLDER)/$(@:%.o=%.s)
    @echo ‘Finished building: $(@:%.o=%.s)’
    @echo ‘ ‘

    # All Target
    all: $(TARGET).$(TARGET_EXT)

    # Tool invocations
    $(TARGET).$(TARGET_EXT): $(C_OBJS) $(S_OBJS)
    $(AR) $(ARFLAGS) $@ $(addprefix $(OBJ_FOLDER)/,$(C_OBJS)) $(addprefix $(OBJ_FOLDER)/,$(S_OBJS))
    @echo ‘Finished building target: $@’
    @echo ‘ ‘
    $(MAKE) –no-print-directory post-build

    # Other Targets
    clean:
    -$(RM) $(TARGET).$(TARGET_EXT) $(addprefix $(OBJ_FOLDER)/,$(C_OBJS)) $(addprefix $(OBJ_FOLDER)/,$(S_OBJS))
    -@echo ‘ ‘

    post-build:
    -@echo ‘Performing post-build steps’
    arm-none-eabi-size –totals $(TARGET).$(TARGET_EXT)
    -@echo ‘ ‘

    .PHONY: all clean dependents
    .SECONDARY: post-build

    The Makefile first defines the CPU and instruction mode. Then it defines the compiler options. As the compiler options are dependent on the output, so we have a different Makefile for each Debug and Release target. Please refer to GNU Make to understand the Makefile syntax.

  • The Blinky project flashes an LED and uses libstm32f103.a for accessing the microcontroller. In this case, the Makefile is a bit different and is shown below:

    ###################################################
    # Makefile to generate “elf” compiled binary for embedded targets.
    # Author: Asif Iqbal (a.iqbal@ieee.org)
    # Date: 7th October, 2010
    ###################################################

    CPU := cortex-m3
    INSTRUCTION_MODE := thumb
    TARGET := blinky_stm32f103
    TARGET_EXT := elf
    LD_SCRIPT := ../stm32.ld

    LIBS := ../../libSTM32F103/Debug/libstm32f103.a

    INCLUDE += -I ../src
    INCLUDE += -I ../../libSTM32F103
    INCLUDE += -I ../../libSTM32F103/inc
    INCLUDE += -I “C:\Program Files\CodeSourcery\Sourcery G++ Lite\lib\gcc\arm-none-eabi\4.4.1\include”

    OBJ_FOLDER := objs

    COMPILER_OPTIONS = -O0 -g -ggdb -Wall -fno-strict-aliasing \
    -fmessage-length=0 -fno-builtin -m$(INSTRUCTION_MODE) \
    -mcpu=$(CPU) -MMD -MP

    DEPEND_OPTS = -MF $(OBJ_FOLDER)/$(patsubst %.o,%.d,$(notdir $@)) \
    -MT $(OBJ_FOLDER)/$(patsubst %.o,%.d,$(notdir $@))

    CC = arm-none-eabi-gcc
    CFLAGS = $(COMPILER_OPTIONS) $(INCLUDE) $(DEPEND_OPTS) -c

    CXX = arm-none-eabi-g++
    CXXFLAGS = $(COMPILER_OPTIONS) $(INCLUDE) $(DEPEND_OPTS) -c
    AS = arm-none-eabi-gcc
    ASFLAGS = $(COMPILER_OPTIONS) $(INCLUDE) $(DEPEND_OPTS) -c

    LD = arm-none-eabi-gcc
    LD_OPTIONS = -Wl,-Map=$(TARGET).map $(COMPILER_OPTIONS) -L ../ -T $(LD_SCRIPT) $(INCLUDE)

    OBJCP = arm-none-eabi-objcopy
    OBJCPFLAGS = -O ihex

    AR = arm-none-eabi-ar
    ARFLAGS = cr

    RM := rm -rf

    USER_OBJS :=
    C_SRCS :=
    S_SRCS :=
    C_OBJS :=
    S_OBJS :=

    # Every subdirectory with source files must be described here
    SUBDIRS := ../src

    C_SRCS := $(foreach dir,$(SUBDIRS),$(wildcard $(dir)/*.c))
    C_OBJS := $(patsubst %.c,$(OBJ_FOLDER)/%.o,$(notdir $(C_SRCS)))
    S_SRCS := $(foreach dir,$(SUBDIRS),$(wildcard $(dir)/*.s))
    S_OBJS := $(patsubst %.c,$(OBJ_FOLDER)/%.o,$(notdir $(S_SRCS)))

    VPATH := $(SUBDIRS)

    $(OBJ_FOLDER)/%.o : %.c
    @echo ‘Building file: $(@F)’
    @echo ‘Invoking: MCU C Compiler’
    $(CC) $(CFLAGS) $< -o $@ @echo 'Finished building: $(@F)' @echo ' ' $(OBJ_FOLDER)/%.o : %.s @echo 'Building file: $(@F)' @echo 'Invoking: MCU Assembler' $(AS) $(ASFLAGS) $< -o $@ @echo 'Finished building: $(@F)' @echo ' ' # All Target all: $(TARGET).$(TARGET_EXT) # Tool invocations $(TARGET).$(TARGET_EXT): $(C_OBJS) $(S_OBJS) @echo 'Building target: $@' @echo 'Invoking: MCU Linker' $(LD) $(LD_OPTIONS) $(C_OBJS) $(S_OBJS) $(USER_OBJS) $(LIBS) -o$(TARGET).$(TARGET_EXT) @echo 'Finished building target: $@' @echo ' ' $(MAKE) --no-print-directory post-build # Other Targets clean: -$(RM) $(TARGET).$(TARGET_EXT) $(TARGET).bin $(TARGET).map $(OBJ_FOLDER)/*.* -@echo ' ' post-build: -@echo 'Performing post-build steps' arm-none-eabi-size --totals $(TARGET).$(TARGET_EXT); arm-none-eabi-objcopy -O binary $(TARGET).$(TARGET_EXT) $(TARGET).bin ; -@echo ' ' .PHONY: all clean dependents .SECONDARY: post-build

    As we can see, it references the library using LIBS variable. The compiler options must be noted as they are optimized for debugging. During my development, I have found that using -ffunction-sections and -fdata-sections for compilation as well as –gc-sections for linking results in very hard to debug code and sometimes even wrong output. So stay away from these gcc options during debugging. They can be safely added to the Release version and result in considerably smaller binaries. The Release Makefile reflects this point.

  • Now you should also build the Blinky project by right-clicking and Build Project command. After the build has been completed successfully, you have a blinky_stm32f103.elf file in the Debug folder of the project. We need to download this to the target and execute it. Here we need the Segger debugger.
  • To use the debugger, download and install the J-Link drivers from the SEGGER website.
  • Now connect your target using SWD connections and start the SEGGER GDB server as following:

    C:\>cd “C:\Program Files\SEGGER\JLinkARM_V420e”
    C:\Program Files\SEGGER\JLinkARM_V420e>
    C:\Program Files\SEGGER\JLinkARM_V420e>JLinkGDBServer.exe -if swd
    C:\Program Files\SEGGER\JLinkARM_V420e>

    Do not forget to include the -if swd switch as it instructs the J-Link to use the SWD interface. Once the debugger is correctly connected to the device and the device is powered, the J-Link interface look similar to the following image:

    This shows that SEGGER GDB server is ready and connected to the device. The server is waiting on localhost:2331 to accept remote GDB connections.

  • Now we must configure Eclipse to use GDB server to download and debug our Blinky application to the target. For this open “Debug Configurations” as shown below:

  • Create a new node under “GDB Hardware Debugging” named “Blinky_STM32F103 Debug” with settings as shown in the following figures:

    The script in the “Startup” tab is not visible completely and is therefore given in the following:

    target remote localhost:2331
    monitor interface SWD
    monitor speed 2000
    monitor flash device = STM32F103CB
    monitor flash download = 1
    monitor flash breakpoints = 1
    monitor endian little
    monitor reset

    Save this configuration.

  • Once all the settings are made, click next to the “green bug” icon and select “Blinky_STM32F103 Debug”. Eclipse will open the Debug perspective similar to the following:

  • Now that is really something. You have access to the disassembly, registery, breakpoints and if you hover over a variable, you will see its value, live! You have a fully-functional Cortex-M IDE without any limitations on compiling, debugging, downloading, etc. And the best part is, it is open-source.

    18 Responses to “Tutorial: Setting-up ARM Cortex-M3 Development Enviroment using Codesourcery Toolchain, Eclipse, and Segger J-Link Debugger”

    • […] This post was mentioned on Twitter by Summer Nights, L. Edlic. L. Edlic said: Setting-up ARM Cortex-M Development Enviroment using Codesourcery … http://bit.ly/9esTl8 […]

    • GT says:

      Thanks – very helpful.

      I am in the throws of getting codesourcery to load and debug my lm3x9b96 board using the lm3s1968 evaluation board for communications. They start to talk but I get ‘failed to complete programming flash’ error.
      The trace on the logic analyser looks promising, switches to SWD mode, gets a reasonable looking device ID, then a few more exchanges , and stops.
      Still fiddling.

      Is there a spec for coretex SWD somewhere ?

    • admin says:

      Hello GT
      Thanks for stopping by. It can be very painstaking to get things working using open-source tools. I also spent lot of time on the above. Segger J-Link has spared me from getting into swd details myself. Its GDB server is wonderful. I don’t have any document describing SWD for cortex processors in detail. Perhaps ARM official website can provide more information.

    • AF says:

      Very nice tutorial. I am trying to setup my eclipse IDE with Codesourcery for the mbed (NXP ARM Cortex M3 1768) board.

    • Mark says:

      Too bad the Segger J-Link support is not available on anything else than windows so please add the license cost to your estimated costs of the debugger. Too bad because I’s liked to have had one otherwise.

      Besides this. it’s a very nice tutorial!

    • admin says:

      AF: Thanks. I have used eclipse with Codesourcery for MBED too. But it is not very interesting because of lack of JTAG on mbed.

      Mark: Thanks. Absence of Segger software for Linux is certainly a disadvantage, I agree.

    • cartier watch tank Excuse for that I interfere ?I understand this question. Is ready to help. I am final, I am sorry, but it not absolutely approaches me. Perhaps there are still variants? I congratulate, what necessary words…, a brilliant idea In it something is. Clearly, I thank for the information.

    • Pascal says:

      Thanks for this tutorial! I found it very helpful! By the way, I would like to know if I could build a C++ project for STM32 by using Codesourcery?

      Thanks in advance!

    • Andreas says:

      Has anyone got this development setup (Eclipse, Code Sourcery, J-Link GDB ) to be able to get real time expression/watches to work? I would like to read and write to variables without having to step the debugger.

      Thanks,
      Andreas

    • […] Tutorial: Setting-up ARM Cortex-M3 Development Enviroment using Codesourcery Toolchain, Eclipse, and… […]

    • Thank you a bunch for sharing this with all of us you really recognise what you are talking about! Bookmarked. Please also talk over with my web site =). We could have a hyperlink change arrangement between us

    • Strongman says:

      It’s really a nice and useful piece of info. I am satisfied that you shared this helpful info with us. Please keep us informed like this. Thanks for sharing.

    • Hi my loved one! I wish to say that this post is amazing, nice written and include approximately all significant infos. I would like to look more posts like this .

    • cfb says:

      Thanks! Very apreciated!

      It seems to have a minor error in the makefile related to assembler dirs:

      S_OBJS := $(patsubst %.c,$(OBJ_FOLDER)/%.o,$(notdir $(S_SRCS)))

      must be replaced by:

      S_OBJS := $(patsubst %.s,$(OBJ_FOLDER)/%.o,$(notdir $(S_SRCS)))

      Note “%.c” is replaced by “%.s”

      • Pascal says:

        Hi all,

        Could you please tell me how to get compiled the startup .s file which defines all interrupt vectors? Can we still use arm-none-eabi-gcc to compile it or arm-none-eabi-as instead?

        Thanks,

    • Stephane Bujold says:

      Thank you very much, it was very useful for me.

    • […] ARM development¬†tool-chain. There are quite a number of good resources online, for example, here, here¬†and here. I’m not going to write “Yet Another …”, just document my […]

    Leave a Reply

    Your email address will not be published. Required fields are marked *