For some time now I have been doing projects (or should I rather say "been playing around") with AVR microcontrollers. Both in the form of different types of Arduinos but also in stand-alone projects (including the USB KVM and a battery powered ATTINY85 board, which I still haven't written a post about). For the most part I really like these microcontrollers, they are versatile, low powered and the development tools available are excellent (and importantly, available on all major platforms).
However, In one of my latest projects I encountered a situation where AVRs just might not be enough. What I wanted to do was to capture images from a digital camera module (OV7670) and process them to determine movement speed and direction. While it might in theory be possible to do so on an ATMEGA microcontroller or similar, the small amount of memory available would make such an operation tricky at best.
At that point I started looking for a more powerful microcontroller, and one that aso included a hardware digital camera interface. What I found was the STM32F4, a microcontroller which operates at between 84 to 180 Mhz, has up to 384 KB of RAM and a dedicated camera interface. Some of the high end models also includes such nice features as graphics acceleration and a built in LCD controller (none of which I really need for this project though).
Another great thing about the STM32F4 is that it has several very affordable evaluation boards available. I'm not sure if STM are selling these at cost (or even below) but paying just £7.19 including shipping is a great deal, especially compared to buying an original (non knock-off) Arduino.
![]() |
The STM32F446 Nucleo eval board |
OpenSTM32
System Workbench for STM32 is the open source (Eclipse based) development environment for the STM32 family of microcontrollers. The package which you can download from openstm32.org contains the development environment plus all drivers and tools needed in one bundle. Since it's based on Eclipse it provides you with a very powerful development environment and combined with SWD debug (over ST-LINKv2) support it should be enough for most projects.
There is a catch however, and that is that there is only official support for Windows and Linux. OpenSTM32 is also available in the form of an Eclipse plugin which you can install on any computer running Eclipse. Sadly though, since the packages contain binaries (for the cross compiler and other build tools) this does not help you much if you are on OSX (at least not at first...).
The following part of the post will describe the steps I took in order to get the OpenSTM32 build environment up and running under OSX. There are probably many things that can be improved so if anyone has some suggestions, please do let me know!
1. Installing the software
Before we get started on tweaking things in order to get it to actually work on OSX there are a number of software packages that you need to install. I will not got into details about how to install them as the process itself it quite straightforward and also documented on the respective websites.
- Eclipse for C/C++ Developers
- GNU ARM Eclipse OpenOCD: Used for flashing and debugging (I used version 0.9.0-201505191004
- GCC ARM Embedded toolchain (I used version 4_9-2015q2-20150609). You should be able to replace this with the ARM cross compilation toolchain of your choice.
2. Configuring Eclipse
Now we need to install the OpenSTM32 plugins. Even though they will not work out of the box we still need to install them to provide us with a starting point for modifications. Installation instructions are available here but in summary you need to install the plugin from the following Update Site:
http://www.ac6-tools.com/Eclipse-updates/org.openstm32.system-workbench.site
Select and install all the available packages (don't worry about some of them being Linux/Windows for now). The install process might take some time and before it finishes you will get a warning telling you that some of the selected packages are incompatible. When given the choice, select to "Modify the packages to become compatible...". After Eclipse restarts you now have a completely broken installation of OpenSTM32! All's not lost though, let's fix it!
3. Fixing the toolchain
OpenSTM32 comes packaged with GCC ARM cross compilation toolchain build by AC6.
Strangely enough, even though we were told during the install process that it was not possible to install this plugin, somehow it still ends up installing it. This however, is a good thing for us, because it makes it much easier to get things up and running.
Strangely enough, even though we were told during the install process that it was not possible to install this plugin, somehow it still ends up installing it. This however, is a good thing for us, because it makes it much easier to get things up and running.
First of all we need to locate where the AC6 toolchain is installed. In my case it was installed here:
/Users/erikandre/Downloads/EclipseOpenSTM32.app/Contents/Eclipse/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.3.0.201507241045/toolsIn this folder there will be a folder named compiler, go ahead and remove it since we will not be needing it any more. Now we need to replace the old compiler folder with the GCC ARM Embedded toolchain which you previously installed. You can either copy the whole thing over, or simply create a symlink to the install folder (change the install folder to something appropriate for your setup):
ln -s ~/CliApplications/gcc-arm-none-eabi-4_9-2015q2/ compilerWhen you enter the compiler folder, the contents should look something like this:
4. Fixing OpenOCD integration
Making OpenOCD work is quite similar to the toolchain but with one additional step. First you to locate where the OpenOCD plugin is installed. If you've already found the toolchain this should be simple, but just in case here is where I found it:
/Users/erikandre/Downloads/EclipseOpenSTM32.app/Contents/Eclipse/plugins/fr.ac6.mcu.externaltools.openocd.win32_1.4.0.201509171409/toolsYou could probably replace the whole openocd folder contained within with the files from GNU ARM Eclipse OpenOCD which you installed earlier. However, since I was not 100% whether they had changed any of the config files, I instead opted to just replace the binaries, like this:
- Delete the files under openocd/bin.
- Copy all files from "GNU ARM Eclipse/OpenOCD/0.9.0-xxxx/bin into openocd/bin in the plugin folder.
As I mentioned, there is one additional step needed to get OpenOCD working. You need to rename the binary (bin/openocd) to openocd2 and create a new file in that folder called openocd. Put the following content into the new file:
#!/bin/sh echo "Fixing parameters for openocd" echo "Input $@" temp="${8%\"}" temp="${temp#\"}" "$02" $1 $2 $3 "$4" $5 "$6" $7 "$temp"Also, make sure that you make the new file executable:
chmod +x openocd
5. Let see if it works!
Hopefully at this point we have a working OpenSTM32 build environment but let's not just hope, let's see if it actually works!
Back in Eclipse, create a new C project using the "Ac6 STM32 MCU Project" template.

Select which board you want to deploy it to on the MCU Configuration step.
Next you will need to select which firmware (if any) to include in the project. For this first project we are going to pick "Hardware Abstraction Layer (Cube HAL)"
OK, we now have our first project. Don't be alarmed if you at first see some errors about "arm-non-eabi-g++" not found in path, this one is harmless and should not come back if you remove the error.
At this point you can go ahead and connect the eval board. Let's see if we can run (the empty) project. Right click on the project module (in my case it's named "blink") and click on Run As and then Run Configurations... Double click on the Ac6 STM32 Debugging option to create a new configuration. There should be no need to change any of the settings, so let's just click Run.
Hopefully, the project should now build and the resulting .elf file be flashed onto the board. The console output should look something like this:
Fixing parameters for openocd Input -f nucleo_f446re.cfg -s /Users/erikandre/Downloads/EclipseOpenSTM32.app/Contents/Eclipse/plugins/fr.ac6.mcu.debug_1.4.0.201509171409/resources/openocd/scripts/st_board -s /Users/erikandre/Downloads/EclipseOpenSTM32.app/Contents/Eclipse/plugins/fr.ac6.mcu.debug_1.4.0.201509171409/resources/openocd/scripts -c "program Debug/blinky.elf verify reset exit" GNU ARM Eclipse 64-bits Open On-Chip Debugger 0.9.0-00073-gdd34716 (2015-05-19-12:55) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD adapter speed: 2000 kHz adapter_nsrst_delay: 100 srst_only separate srst_nogate srst_open_drain connect_deassert_srst Info : Unable to match requested speed 2000 kHz, using 1800 kHz Info : Unable to match requested speed 2000 kHz, using 1800 kHz Info : clock speed 1800 kHz Info : STLINK v2 JTAG v24 API v2 SWIM v10 VID 0x0483 PID 0x374B Info : using stlink api v2 Info : Target voltage: 3.242436 Info : STM32F446.cpu: hardware has 6 breakpoints, 4 watchpoints target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x080002a4 msp: 0x20020000 configuring PLL ** Programming Started ** auto erase enabled Info : device id = 0x10006421 Info : flash size = 512kbytes target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x20000042 msp: 0x20020000 wrote 16384 bytes from file Debug/blinky.elf in 0.609009s (26.272 KiB/s) ** Programming Finished ** ** Verify Started ** target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x2000002e msp: 0x20020000 target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x2000002e msp: 0x20020000 verified 2240 bytes in 0.087982s (24.863 KiB/s) ** Verified OK ** ** Resetting Target ** shutdown command invoked
As you've now noticed, the board is not doing much after this. Since everyone likes some flashy LED action, let's knock it up a notch!
In your project, open blink/src/main.c. It should looks something like this:
#include "stm32f4xx.h" #include "stm32f4xx_nucleo.h" int main(void) { for(;;); }
Replace the content with the following code (which will setup the GPIO pin connected to LED2 and then turn it on and off again):
#include "stm32f4xx.h" #include "stm32f4xx_nucleo.h" int main(void) { HAL_Init(); // LED clock initialization LED2_GPIO_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = LED2_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStruct); while (1) { HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN); //Toggle the state of LED2 HAL_Delay(100); //delay 100ms } }
That's it, you've got your first awesomely blink application up and running on your STM32 board. The rest should be a walk in the park ;)
This comment has been removed by the author.
ReplyDeleteGreat howto! However I have a problem with cpp/C++ codes. When I create C++ project for porting Adafruit GFX to STM32 that project does not compile on MAC, but does well on Windows. Any idea what might be wrong?
ReplyDeleteHi! Thank you very much! :)
DeleteI haven't tried C++ myself (I've just worked with C so far). What kind of error are you getting?
Thanks for this! When I try to install the packages at http://www.ac6-tools.com/Eclipse-updates/org.openstm32.system-workbench.site , the external tools will not install. I don't get an option to modify to be compliant. I receive this error: Cannot complete the install because some dependencies are not satisfiable
ReplyDeletefr.ac6.feature.mcu.externaltools.win32.feature.group [1.3.0.201507241045] cannot be installed in this environment because its filter is not applicable.
Have you seen this? Is there a way around this?
Thanks!
Hi! Thanks!
DeleteWhich version of Eclipse are you using?
Also, to confirm, you don't see this screen: https://dl.dropboxusercontent.com/u/12678321/Screen%20Shot%202015-11-06%20at%2009.58.31.png
I'm using Mars 4.5.1. I did get that screenshot and proceeded to install using the selection shown in your screenshot. However, I can't find any created folder for: EclipseOpenSTM32.app/Contents/Eclipse/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.3.0.201507241045/tools
DeleteThanks so much for your help.
I was able to find the folder, but the Win32 version is not there. I only have the linux folders and files. Can I modify these?
DeleteAh, that is interesting :). Actually I got the same result the very first time I tried this procedure (I ended up with the linux toolchain being install) but every time I tried again I always got the Windows toolchain.
DeleteYes, I think you should be able to follow the rest of the instructions and just modify the linux toolchain directory instead. Let me know if you encounter any problems and I'll try to reproduce it on my end.
Everything worked up until the debugging. The program seems to compile, but upon debugging I receive this:
DeleteFixing parameters for openocd
Input -f stm32l476g_disco.cfg -s /Users/ccenten/Eclipse2/Eclipse.app/Contents/Eclipse/plugins/fr.ac6.mcu.debug_1.5.0.201510231435/resources/openocd/scripts/st_board -s /Users/ccenten/Eclipse2/Eclipse.app/Contents/Eclipse/plugins/fr.ac6.mcu.debug_1.5.0.201510231435/resources/openocd/scripts -c gdb_port 3333
GNU ARM Eclipse 64-bits Open On-Chip Debugger 0.9.0-00073-gdd34716 (2015-05-19-12:55)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Warn : use 'STM32L476.cpu' as target identifier, not '0'
Error: flash driver 'stm32l4x' not found
I'm using the STM32L476 discovery board. Thanks!
Do you get the same result if you just Run it (as opposed to start it in debug mode)?
DeleteTo me it looks like the issue might be with the .cfg files for your board (found in the openocd directory).
The one reference to stm32l4x that I found there is this:
scripts/target/stm32l4.cfg:flash bank $_FLASHNAME stm32l4x 0x08000000 0 0 0 0 $_TARGETNAME
If you want to live dangerously you could try changing the stm32l4x to stm32lx and see if you get the same error (please beware that I have no idea what this might do to your board!)
I tried your suggestion of modifying to stm32lx and I did make some progress. Now I receive the following:
DeleteWarn : use 'STM32L476.cpu' as target identifier, not '0'
adapter_nsrst_delay: 100
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
adapter speed: 1800 kHz
Info : clock speed 1800 kHz
Info : STLINK v2 JTAG v24 API v2 SWIM v11 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.241107
Error: init mode failed (unable to connect to the target)
in procedure 'program'
in procedure 'init' called at file "embedded:startup.tcl", line 473
in procedure 'ocd_bouncer'
** OpenOCD init failed **
shutdown command invoked
Do I need to separately install an ST Link driver in OS X?
Good question! I have only worked with the Nucleo board and in that case I did not have to install any drivers. The Discovery boards should work the same as far as I know.
DeleteYou might want to give stlink (https://github.com/texane/stlink) a try instead of openocd, if nothing else, just to see if you can connect and upload a binary to the device.
Cool! I'm glad it worked for you :). Yes, it seems to be a bit random which one actually gets installed.
ReplyDeleteI think the problem for me lies with the selected device. I am using the STM32L476 Discovery board and it appears as though the flash driver is missing for this part in the most recent openocd release. When I look at the linux binary for openocd in workbench, there are multiple references to stm32l4x, but in the openocd mac OSX binary there is no reference to the appropriate flash driver. I tried the stm32lx driver and it gets me to the point of connecting to the programmer, but no further.
ReplyDeleteHmm, that is quite strange. I just cloned the openocd git and built it (on OSX). In the resulting binary there are references to stm32l4x, so perhaps you just need to do the same to get it working?
ReplyDeleteI followed your instructions and everything is working perfectly now. Must have been an outdated version of openocd. Thanks so much for all your help - very much appreciated!!
ReplyDeleteAwesome, I'm glad it helped! :)
ReplyDeleteHey,
ReplyDeletei just followed your instructions, but when i want to debug, i get the following errors:
/Users/Alex/Downloads/Eclipse.app/Contents/Eclipse/plugins/fr.ac6.mcu.externaltools.openocd.linux64_1.5.0.201510231513/tools/openocd/bin/openocd: line 1: {rtf1ansiansicpg1252cocoartf1404cocoasubrtf110: command not found
/Users/Alex/Downloads/Eclipse.app/Contents/Eclipse/plugins/fr.ac6.mcu.externaltools.openocd.linux64_1.5.0.201510231513/tools/openocd/bin/openocd: line 2: syntax error near unexpected token `}'
/Users/Alex/Downloads/Eclipse.app/Contents/Eclipse/plugins/fr.ac6.mcu.externaltools.openocd.linux64_1.5.0.201510231513/tools/openocd/bin/openocd: line 2: `{\fonttbl\f0\fmodern\fcharset0 Courier;}'
any idea, what i did wrong?
Hi,
DeleteHmm, that is quite an odd error! I looked around a bit but I've not managed to come up with anything useful (yet). Out of curiosity, have you upgraded to OSX 10.11 (El Capitan)?
hey, i found the mistake. i used a wrong format for the opened file. i compiled the standard project for my stm32f3 and everything worked, very nice :)
ReplyDeletebut now i have a new problem:
undefined reference to `_sbrk'
i am using sprintf and there i probably have to link a lib. but i have no idea how to do that. maybe you can help me.
this is the error i get when i use sprint:
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -T"/Users/Alex/Documents/workspace/STM32f303VC/LinkerScript.ld" -Wl,-Map=output.map -Wl,--gc-sections -lm -o "STM32f303VC.elf" @"objects.list"
/Users/Alex/dev/Eclipse.app/Contents/Eclipse/plugins/fr.ac6.mcu.externaltools.arm-none.linux64_1.3.0.201507241112/tools/compiler/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
make: *** [STM32f303VC.elf] Error 1
I just tried to reproduce the problem for me it actually seems to work. If I include stdio.h, call sprintf() and then build it, the resulting elf file contains newlib (which I assume contains the symbol that is missing in your case)
DeleteThis is the compiler output:
Building file: ../src/main.c
Invoking: MCU GCC Compiler
/Users/erikandre/Documents/eclipse-ws/dep-demo2/Debug
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -DSTM32F303RETx -DNUCLEO_F303RE -DSTM32F3 -DSTM32 -DSTM32F30 -DDEBUG -I"/Users/erikandre/Documents/eclipse-ws/dep-demo2/inc" -O0 -g3 -Wall -fmessage-length=0 -ffunction-sections -c -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.c"
Finished building: ../src/main.c
Building target: dep-demo2.elf
Invoking: MCU GCC Linker
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -T"/Users/erikandre/Documents/eclipse-ws/dep-demo2/LinkerScript.ld" -Wl,-Map=output.map -Wl,--gc-sections -lm -o "dep-demo2.elf" @"objects.list"
Finished building target: dep-demo2.elf
fixed that problem too ;)
ReplyDeletedebugging is working but how do i flash the release?
CHeers
Howdy! Thanks for posting this, really big help. I'm trying to run the first blank program but am getting this error:
ReplyDeleteOpenOCD Binary cannot be executed
Seems pretty straightforward, heh, but I don't really know what to try. Any ideas for how to get this running?
Well! retried the chmod +x command and got openocd executable, then was running in to null pointer exception stuff, but I noticed that the run configuration that was generated the first time I double-clicked on "Ac6 STM32 Debugging" after "Run As..." had a blank field for "C/C++ Application" I double clicked again and it filled in the field with "Debug/My-Project-Name.elf"
ReplyDeleteI appear to be in business, blinking and all. Thanks bra!
That's awesome! Cheers :)
DeleteThis comment has been removed by the author.
ReplyDeleteSame for me. Instructions work on mac 10.10.5 , thank you !
ReplyDeleteJust confirming those instructions work.
In my case plugins were installed to /Applications/Eclipse.app/Contents/Eclipse/plugins and tools were for Linux, not for Windows.
OSX 10.10.5, Eclipse Version: Mars.1 Release (4.5.1)
Cool! Glad it worked out for you :)
Deletei discoverd a wired behavior:
ReplyDeletewhen i reconnect my stink i can no longer flash/debug.
Error: couldn't bind to socket: Address already in use
any advice to fix this problem?
CHeers
Yes, I encountered the same problem a few time. Sadly, now I don't quite remember how I managed to solve it :(. I think it was either one of these
Delete* Wait a little bit and then try again, and it would work
* Find the process that was keeping that socket open and kill it
What are the steps to reproduce the issue? You first flash the device, then unplug it and then plugin it in again and attempt to flash it a second time?
Hi,
Deletei wrote short script which kills openocd during each build just in case it is hanging.
btw: i found small bug in .cfg file for nucleo 042 worksize should be 0x1800 which caused
that debug and flash did not work if your bin file was larger than ram size
yes exactly, neither debug nore relase flashing is working. works after reboot
ReplyDeletetried some reinstalling but still happens. any idea what i can do?
Deleteyou have to kill your running openocd process
Deleteps ax | grep openocd
and then kill -9 openocd_process_number