Skip to main content

Getting started with OpenSTM32 on OSX


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
That said, not everything is sunshine, rainbows and unicorns when it comes to developing for this powerful platform, at least not if you are a Mac user (and prefer Open Source development tools).

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.
  1. Eclipse for C/C++ Developers
  2. GNU ARM Eclipse OpenOCD: Used for flashing and debugging (I used version 0.9.0-201505191004
  3. 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.

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/tools
In 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/ compiler
When 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/tools
You 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 ;)

Comments

  1. This comment has been removed by the author.

    ReplyDelete
  2. Great 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?

    ReplyDelete
    Replies
    1. Hi! Thank you very much! :)

      I haven't tried C++ myself (I've just worked with C so far). What kind of error are you getting?

      Delete
  3. 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
    fr.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!

    ReplyDelete
    Replies
    1. Hi! Thanks!
      Which 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

      Delete
    2. 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

      Thanks so much for your help.

      Delete
    3. 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?

      Delete
    4. Ah, 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.

      Yes, 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.

      Delete
    5. Everything worked up until the debugging. The program seems to compile, but upon debugging I receive this:
      Fixing 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!

      Delete
    6. Do you get the same result if you just Run it (as opposed to start it in debug mode)?

      To 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!)

      Delete
    7. I tried your suggestion of modifying to stm32lx and I did make some progress. Now I receive the following:
      Warn : 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?

      Delete
    8. 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.

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

      Delete
  4. Cool! I'm glad it worked for you :). Yes, it seems to be a bit random which one actually gets installed.

    ReplyDelete
  5. I 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.

    ReplyDelete
  6. Hmm, 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?

    ReplyDelete
  7. I 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!!

    ReplyDelete
  8. Hey,
    i 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?

    ReplyDelete
    Replies
    1. Hi,

      Hmm, 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)?

      Delete
  9. 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 :)
    but 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

    ReplyDelete
    Replies
    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)

      This 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

      Delete
  10. fixed that problem too ;)

    debugging is working but how do i flash the release?

    CHeers

    ReplyDelete
  11. Howdy! Thanks for posting this, really big help. I'm trying to run the first blank program but am getting this error:

    OpenOCD 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?

    ReplyDelete
  12. 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"

    I appear to be in business, blinking and all. Thanks bra!

    ReplyDelete
  13. This comment has been removed by the author.

    ReplyDelete
  14. Same for me. Instructions work on mac 10.10.5 , thank you !

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

    ReplyDelete
  15. i discoverd a wired behavior:
    when 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

    ReplyDelete
    Replies
    1. 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

      * 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?

      Delete
    2. Hi,
      i 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

      Delete
  16. yes exactly, neither debug nore relase flashing is working. works after reboot

    ReplyDelete
    Replies
    1. tried some reinstalling but still happens. any idea what i can do?

      Delete
    2. you have to kill your running openocd process
      ps ax | grep openocd
      and then kill -9 openocd_process_number

      Delete

Post a Comment

Popular posts from this blog

Simple outline for multi-sprite characters in Unity 2D using Shader Graph

For the last 6 months I've been working on a new (untitled) 2D game project in Unity both as a way to learn C# and also to play around with some game concepts I've been thinking about for quite a while. Since I'm not much of an artist or a graphic designer I purchased a set of rather nice looking character sprites from  https://tokegameart.net/  that also came with animations and ready to use Unity packages. Since my game has multiple characters on screen at one and each one can be given orders I needed a way to show which one was selected or active. One common way to handle this which felt like a good fit for me is to show an outline around the selected character. Luckily there's a lot of examples and guides explaining how to do this in Unity (and I based this one on a great article by Daniel Ilett). There was one snag though, my characters consist of multiple sprites (one for reach part of the body) that are drawn and animated separately. This meant that it w...

Nucleo STM32F446RE and OV7670

After many hours of trial and failure I finally managed to get my OV7670 camera module to work properly with the Nucleo STM32F446RE board. I will try to put together a longer article about some of the issues I encountered and how I solved them but for now the source code is available on GitHub .