/stm32-test

My playground for learning STM32 microcontrollers

Primary LanguageC

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)).