My playground for learning STM32 MCUs. Setting up Eclipse: * Install the GNU ARM Eclipse plugin: use http://gnuarmeclipse.sourceforge.net/updates as URL in Eclipse * Install Mentor Sourcery CodeBench toolchain and add it to PATH * Install the stlink tool from https://github.com/texane/stlink. OpenOCD is also a possibility, but the stlink tool is very easy to setup: just run it, no config is needed! * In Eclipse, add new project using the Sourcery G++ toolchain. Remember the -mcpu setting and linker script. * Setting up debugging in Eclipse: 1) Create a new "External Tools Configurations -> Program" thing, point it to st-util binary, e.g. /usr/local/bin/st-util. Click Run to see that it works. 2) Go to "Debug configurations" and create a new "GDB Hardware Debugging" profile. Select the "Standard GDB Hadware Debugging Launcher" in the lower right corner. In the debugger tab, set "arm-none-eabi-gdb" and port number 4242 (the default for st-util). The rest can be default. 3) The last part is to create a launch group that combines the st-util tool and the GDB debug session into one single-click operation. Go to Debug Configurations and create a new Launch Group. Press the "Add" button and select "run" from the drop-down list to be able to select the st-util tool you created earlier. Press "OK" and then "Add" again. This time, select "debug" from the drop-down list to be able to select GDB Hardware Debugging. Press "OK" and "Debug". * Debugging should now be a single-click operation! Resources: www.st.com/ http://www.bravegnu.org/gnu-eprog/ : awesome tutorial on using GNU toolchains for embedded (ARM) work Build errors with STM32F0xx_StdPeriph_Driver library ---------------------------------------------------- If you get something like this ---- ../Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c: In function 'DAC_DeInit': ../Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c:151:3: warning: implicit declaration of function 'RCC_APB1PeriphResetCmd' [-Wimplicit-function-declaration] ../Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c:151:26: error: 'RCC_APB1Periph_DAC' undeclared (first use in this function) ../Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c:151:26: note: each undeclared identifier is reported only once for each function it appears in ../Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c: In function 'DAC_Init': ../Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.c:172:3: warning: implicit declaration of function 'assert_param' [-Wimplicit-function-declaration] make: *** [Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_dac.o] Error 1 ---- you have forgotten to compile with `-DUSE_STDPERIPH_DRIVER`. Building the STMF0 Discovery demo in Eclipse -------------------------------------------- Create a new C project in Eclipse and select the Sourcery G++ Lite toolchain. Download the STM32F0xx_StdPeriph_Lib_V1.0.0 package from http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f0_stdperiph_lib.zip and unzip it. The following must be copied to the project directory, perhaps into a subdirectory called "cmsis": Libraries/CMSIS/Include/ Libraries/CMSIS/ST/STM32F0xx/Include/ # If you build the demo, a slightly modified version of system_stm32f0xx.c # file is in Project/Demonstration/, look at them and select *one* to copy into # your project. Acutally, system_stm32f0xx.c is/can be generated by the # STM32F0xx_Clock_Configuration_VX.Y.Z.xls utility, as described in "AN4055 # Clock configuration tool for STM32F0xx microcontrollers" Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c # see comment above Libraries/CMSIS/Device/ST/STM32F0xx/Source/Templates/TrueSTUDIO/startup_stm32f0xx.s Rename the extension of startup_stm32f0xx.s from .s to .S (it will not be included in the build unless you do this, it's an Eclipse build system thing...). If you don't do this you'll get a build warning like this: "cannot find entry symbol Reset_Handler; defaulting to 08000000". The following must be copied to the project directory, perhaps into a subdirectory called "stdperiph": Libraries/STM32F0xx_StdPeriph_Driver/ The following must be copied into the project, for example in the top level directory: Project/Demonstration/*.c # remember comment about system_stm32f0xx.c above Project/Demonstration/*.h Project/Demonstration/TrueSTUDIO/STM32F0-Discovery_Demo/stm32_flash.ld Utilities/STM32F0-Discovery/stm32f0_discovery.c Utilities/STM32F0-Discovery/stm32f0_discovery.h Press F5 in Eclipse to refresh the Project Explorer view. You should now see all the files that were copied above. In the project properties, add the "USE_STDPERIPH_DRIVER" preprocessor symbol and add the include paths ./cmsis/Include, ./stdperiph/inc and ./ (under the ARM Sourcery Linux GCC C Compiler section). Set the processor to "cortex-m0". Under the ARM Sourcery Linux GCC C Linker tool setting, add the path to stm32_flash.ld in the "Script file (-T)" field. Now build the project (Ctrl-b). NOTE: If you get "undefined reference to _init" build error, you have two choices. One is to uncheck "-nostartfiles" (i.e. build without the -nostartfiles flag) under ARM Sourcery Linux GCC C Linker. The other option is to comment out "bl __libc_init_array" from startup_stm32f0xx.S, because it is __libc_init_array that calls _init. The startup_stm32f0xx.s file in the gcc_ride7/ directory (ride7 is an Eclipse-based IDE from Raisonance) is almost identical to the Atollic one, with the notable exception that it doesn't call __libc_init_array. So using that file would solve the problem as well. TIP: Enable "-fdata-sections", "-ffunction-sections" and "-Xlinker --gc-sections" for smaller code. Flashing with OpenOCD --------------------- OpenOCD v0.6.0 comes with a config file for the STM32F0Discovery board. This is how to use only openocd to flash a binary file (main.bin) to the STM32F0Discovery board: ---- openocd -f board/stm32f0discovery.cfg -c "init; reset halt; flash write_image erase main.bin 0x08000000; reset run; shutdown" ---- Flashing with stlink (from https://github.com/texane/stlink/) ------------------------------------------------------------- ---- st-flash write main.bin 0x08000000 ---- Using OpenOCD as a gdbserver ---------------------------- This way the target is always reset when GDB attaches (so the reset operation doesn't have to be specified in each GDB config): openocd -f board/stm32ldiscovery.cfg -c 'gdb_port 4242; $_TARGETNAME configure -event gdb-attach { reset init }' Read more here: http://openocd.sourceforge.net/doc/html/GDB-and-OpenOCD.html http://openocd.sourceforge.net/doc/html/CPU-Configuration.html (in the "Target Events" section) Eclipse, OpenOCD and CMake -------------------------- If you have an STM32 project that is using CMake, do the following to get smooth build and debug experience using Eclipse. * Download "Eclipse IDE for C/C++ Developers". I tested this with version 4.2.2 (Juno) on 64-bit Linux. * Make a build dir for eclipse and use cmake to generate project files there. (Eclipse doesn't like it if the build dir is inside the source dir, so don't do that.) mkdir build-eclipse cmake path/to/source -G"Eclipse CDT4 - Unix Makefiles" * Start eclipse and select File -> Import -> General -> Existing Projects into Workspace. Select the build-eclipse dir and leave the rest at default settings. You can now build the project, jump to errors, get code completion support etc. * Install the GDB hardware debugging plugin through Help -> Install New Software. Create a new GDB Hardware Debugging configuration, set the gdb command (arm-none-eabi-gdb for example) and select "OpenOCD (via pipe)" as JTAG device. In the openocd connect string field, put something like this: | openocd -f board/stm32ldiscovery.cfg -c "gdb_port pipe; log_output openocd.log; init; reset init" The rest can be default. Just click "Debug" and enjoy. (If you experience issues with debugging, try unchecking "Reset and Delay" and "Halt" under the "Startup" tab in the debugging configuration. This issue happened to me once when the MCU was programmed to disable the JTAG/SWD pins and I couldn't get the Eclipse gdb to halt the target.) The ONLY thing left now that is a bit annoying is this warning (harmless): warning: RMT ERROR : failed to get remote thread list ...and that the debug button seems to "fall back" to local application debug (not jtag/hardware) when in C/C++ perspective. So the debug configuration has to be selected from the drop-down menu. But once in debug perspective its state is handled correctly (the last debug config is used when the button is pressed). TIP: Bind "Terminate and relaunch" to Ctrl-r (or something you like) in debug mode. You can edit just fine in the debug perspective. I actually find it most productive for intense edit/compile/debug sessions to just stay in the debug perspective and press ctrl-r to start over (Eclipse builds and flashes (if needed)).