You are here

HOWTO: Installing NuttX on the STM32F4 Discovery board (using Debian Linux)

Last night I installed the NuttX RTOS on a new STM32F4 Discovery board I bought at Mauser a couple of days ago for $15. Of course, I was working from Debian Linux. This would not have been possible without extensive help from the Interwebs. I used too many different references to list most of them here. Instead, I'm just going to tell you how I would do it if I had it to do over. Got to give something back, y'know. Here goes…

Hardware Needed

  • The board, of course.

  • A computer running Debian Linux with two available USB ports (a hub should work fine).

  • One USB mini cable (should have come with the board) and one USB micro cable.

Software Needed

  • The latest NuttX tarball and NuttX apps tarball from their website. I used version 6.32. Unpack the tarballs according to the instructions in the top-level NuttX README.

  • A "toolchain" for compiling, loading and debugging code. I used Keith Packard's Debian package for stlink, but he has upstreamed the other packages to Debian.

    • Add a file called 96-keithp.list to /etc/apt/sources.list.d with contents:

        deb unstable/

    I then ran apt-get update to refresh the cache. "I may have also added Keith's GPG key somehow so that it didn't whine? You'll likely also need to make sure you have a Debian unstable feed enabled.

    I used apt-get -t unstable install to install needed packages.

    • binutils-arm-none-eabi
    • gcc-arm-none-eabi
    • gdb-arm-none-eabi
    • stlink
  • The STM firmware bundle for the F4 Discovery. The one I have is called There's a newer firmware bundle available, but I haven't yet tried it.

  • The minicom terminal program, installable via apt-get.

Getting Ready To Go

  • Start by powering up the Discovery using the mini-USB cable. You should get lots of pretty colored lights.

    • If the Discovery has been messed with previously, the default demo firmware may have been overwritten. See "Recovering the Demo Firmware" below for how to get the default demo firmware load back onto the board.
  • Tap the blue button and the lights will disappear. Tilt or move the board to see the lights light up in the direction the onboard Inertial Measurement Unit (IMU) thinks the board is going right now.

  • Have big fun with connecting the micro-USB port and noticing that the board IMU now acts like a (terrible) mouse.

Discovery Board Architecture

This is probably a good point to explain a little bit about the Discovery board architecture. The board consists of two loosely-coupled sections.

One section of the Discovery board has the STM32F407VG microcontroller, the audio subsystem, the buttons, and the micro-USB OTG port. (USB "On-The-Go" is a standard by which a USB port can serve as either a gadget port or a host port, and can auto-negotiate endpoints when plugged into another OTG port.) There is a JTAG-ish port here, labeled SWD (for "Single-Wire Debug").

The other Discovery board section has the mini-USB gadget port, which provides power to the board and also serves as a connection to the ST-Link processor on the board. ST-Link is an ST semi-proprietary protocol by which a USB host can manipulate the operation of the STM32 microcontroller. As near as I can work out, ST-Link works by forcing a bootstrap program into RAM and then executing that program. Thus, ST-Link will only work when the STM32 is in an awake state and capable of being programmed.


The software we will use to talk to the ST-Link on the Discovery board is texane stlink. texane stlink is an open source Linux version of ST's proprietary ST-Link software for Windows.

From the point of view of a host talking to the Discovery board via ST-Link, the 1MB of flash memory lives at addresses 0-0x100000 if you want to read it, and 0x8000000-0x8100000 if you want to write it. The distinction is important: trying to write to the lower address range will silently fail.

Install texane stlink with apt-get -t unstable install stlink and then try

        sudo udevadm control --reload-rules

just to make sure that the device will be recognized. If the mini-USB port is plugged in, unplug and replug it.

Backing Up the Firmware

While it is true that the ZIP from ST contains the demo firmware, I'm never comfortable with that; who knows whether it will be OK? To back up the firmware sitting on your Discovery board, you can follow the steps below. Of course, if you have no idea what firmware is on your Discovery board, there's little point in this exercise.

  • If you haven't already, install the stlink package as described above.

  • Plug the mini-USB port in. The board should power up and start its little demo dance. You will likely not unplug the mini-USB for the rest of this HOWTO.

  • Say

        st-flash read /tmp/stm32f4discovery-demo.bin 0x100000

    Obviously, you can use whatever path and filename you want. Put the resulting file somewhere safe, in case you want to revert your board to how it was when you got it.

Configuring NuttX

If you haven't yet, now is a good time to grab NuttX tarballs (or from the repo, I guess—haven't yet tried). There are two tarballs you need, a nuttx tarball and an apps tarball with the same version number. They must be unpacked into the same parent directory, as the former refers to the latter. Make a symlink from the versioned apps directory to just apps.

Next, you need to make sure the gcc-arm-none-eabi and binutils-arm-none-eabi cross-packages are installed as described above. The configuration process wants to know that they are there.

Now you are going to configure NuttX for the platform. Most of the work has already been done for us. Go into the nuttx directory, then one level down into tools. Say

        sh ./ stm32f4discovery/usbnsh

and then go back up a level.

Custom NuttX configuration is intended to be done using the kconfig-frontend tools as liberated from the Linux kernel. Go download the latest kconfig-frontend tarball, unpack it, and build and install it using the usual methods. Make sure that you have libncurses5-dev installed before you try to configure kconfig-frontend or it will fail to build the kconfig-mconf you will need.

Now, type make menuconfig at the nuttx root and you should be presented with a fairly familiar-looking configurator.

You have several choices at this point.

  1. You could carefully read all the configuration documentation, and meditate over what you might turn on to get desired functionality.

  2. You could read the README files in the various config/stm32f4discovery directories, which describe a lot of what to do.

  3. You could move aside the .config file that is sitting at the top of the nuttx tree and instead use mine. Note that this will only work for NuttX 7.8, but it is probably the quickest route. You can run make oldconfig to bring this file up to date for your newer NuttX version.

Having done all this, you should be ready to go.

Building and Installing NuttX

Building NuttX is easy. Just say make and wait. NuttX builds quite quickly.

When the build is complete, you should have files named nuttx and nuttx.bin sitting in the root directory. You now have two choices. You can install directly using st-flash or by using gdb as a loader. The gdb method is slightly less error-prone, but the st-flash method is easier if you're careful.

  • To install using st-flash... If you haven't already, install texane stlink as described above. Then

        st-flash write nuttx.bin 0x8000000

    You should see a long sequence of interactions, after which all the lights on the board should be red. This probably means that you have successfully installed NuttX.

  • To install using gdb... If you haven't already, apt-get -t unstable install gdb-arm-none-eabi and also install texane stlink as described above.

    Next, open a new terminal on your Linux box and run st-util -v. You should see a set of reports that ends with "Listening at *:4242". This last is an indication of how you can connect with gdb.

    Finally, in a separate terminal from st-util, run arm-none-eabi-gdb nuttx (note the weird flip from the package name) and at the gdb prompt say:

        target extended-remote :4242
        monitor halt
        monitor reset

    You should see a long sequence of interactions after the load, culminating in "Jolly good!" Now exit gdb, which should cause st-util to die.

Now unplug the mini-USB, plug a cable from the host to the micro-USB if you haven't already, and then plug the mini-USB back in.

If all is well, you should see /dev/ttyACM0 on your host, and some dmesg -T output that indicates that this USB is OK.

Talking To NSH

The NuttShell NSH is a simplistic application designed mainly for light debugging and to show what the OS can do. At this point, you should be ready to talk to NSH.

If you have not already, apt-get install minicom. Once it is up, you should be able to use minicom -s as root. Edit the "Serial port setup" to point minicom at /dev/ttyACM0. No other changes should be needed. Then "Save setup as dfl" and "Exit".

Now hit return three times. You should see the NSH prompt. Play around with NSH; when you are done, you can use '^AQ' to quit minicom. Always say "OK" to "Leave without reset?"

Congratulations on installing NuttX!

Recovering The Demo Firmware

At some point it may seem that the Discovery board is "bricked" because the texane stlink tools can no longer talk to it. Unless you have managed to damage the hardware physically by shorting things or something, you are almost certainly still OK. Here's how to get back to where we started:

  • If you have a file stm32f4discovery-demo.bin containing a backup of the firmware as described earlier: Go to the directory where that file is. Now flash the firmware file with:

        st-flash write stm32f4discovery-firmware.bin 0x8000000
  • If you do not have a backup: unpack Change to the directory STM32F4-Discovery_FW_V1.1.0/Project/FW_upgrade/Binary/. Now flash the firmware file with:

        st-flash write STM32F4-Discovery_Demo_0x08008000.bin 0x08008000

If either of the above steps fails, the probable cause is that the STM32F4 side of the Discovery board is in a state that makes it unable to accept the boot program from the ST-Link side of the board. To fix this, you can put the Discovery board in Direct Firmware Upload (DFU) mode.

  • Power down the Discovery board by unplugging the mini-USB.

  • Get one of the little jumper "feet" off the bottom of the Discovery board.

  • Use this jumper to connect the BOOT0 and VDD pins in the double row of pins on the right side of the board when the lettering on the board is upside-up. Be careful to connect exactly these two pins, or you could damage the Discovery board on powerup.

  • Plug the mini-USB back in to power the Discovery board.

  • Push the black RESET button on the board.

You should now be in a state where texane stlink can talk to the Discovery board without problem. Proceed with uploading firmware as above.


The STM32F4 Discovery board is an incredible value at $15. NuttX seems to be a fairly nice BSD-licensed RTOS with great support for this board. Getting this all running is a great preliminary to the software stage of Summer Hardware Project, about which more soon. Fob