Getting Started with NuttX -- Nucleo STM32F303 (Arch Linux)

Here we will try to set up a functional Nuttx environment on a STM32F303 Nucleo-64 evaluation board on Arch Linux OS.

We will install the required software components, configure the board in order to be able to display the “hello world !” string on a serial terminal to the emulated ST-LINK/V2-1 serial port (through the USB cable).

Installing the ARM tool chain

Install the following Arch software packages:

# pacman -S gdb arm-none-eabi-gcc arm-none-eabi-gdb python-pyserial openocd

Some requirements are fulfilled by AUR, namely:

  • kconfig-frontends
  • genromfs

Packaging from AUR, despite being very simple, is out of scope of this document. Please refer to Arch Wiki and install these above packages.

Install Nuttx
$ mkdir nucleo; cd nucleo
$ git clone https://bitbucket.org/nuttx/nuttx
$ git clone https://bitbucket.org/nuttx/apps

$ cd nuttx
$ tools/configure.sh nucleo-f303re/hello

Now let's adapt the provided configuration to our needs:

$ cd ..
$ make menuconfig

Although they have already been set in this configuration, let's review the important options here:

  • Build Setup / Optimization Level: select “Suppress Optimization” in order to step into your code with the debugger.
  • Build Setup / Debug Options: select “Generate Debug Symbols” in order to debug with gdb
  • System Type / STM32 Peripheral Support: select “USART2” which is conncted to the STLINK serial interface through the USB bridge (will be seen as /dev/ttyACM0 in Linux)
  • RTOS Features / Tasks and Scheduling / Application entry point: type “hello_main” which is the main function of the hello example
  • RTOS Features / Files and I/O: select “Enable /dev/console” to enable console at boot time
  • Device Drivers / Serial Driver Support / Serial console: select “USART2”
  • Device Drivers / Serial Driver Support / USART2 Configuration: review serial parameters (default is fine)
  • Application Configuration / Examples: select ”“Hello, World!” example”

Now compile Nuttx (output truncated):

$ make
...
LD: nuttx
make[1]: Leaving directory '/home/myhome/projets/myproject/nuttx/arch/arm/src'
CP: nuttx.hex

One can see the firmware nuttx.hex has been successfully generated.

Flash & debug with openocd and gdb

The good thing with the nucleo kit is that it embarks the latest st-link/V2-1 which may be used as a JTAG programmer/debugger, and also a USB to serial bridge which is already routed to the STM32 UART1. Therefore one can use it to redirect sdtout and the Nuttx console.

In the nuttx directory, perpare a openocd.cfg file with the following:

# This is an ST NUCLEO F303RE board with a single STM32F303RET6 chip.

source [find interface/stlink-v2-1.cfg]
 
source [find target/stm32f3x.cfg]

# use hardware reset, connect under reset
reset_config srst_only srst_nogate

init
reset init
halt

Also you may prepare a .gdbinit file with:

target remote localhost:3333

It will allow gdb to automatically connect to the openocd server.

udev rules:

Make sure your udev rules allow regular user to read/write on ttyUSB and ttyACM devices. For example in /etc/udev/rules.d, create a file 99-myrules.rules with the following content:

SUBSYSTEM!="tty", GOTO="serial_end"

ACTION=="add", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", MODE="666"

LABEL="serial_end"

ACTION!="add|change", GOTO="openocd_rules_end"
SUBSYSTEM!="usb|tty|hidraw", GOTO="openocd_rules_end"

# STM32_STLink v2-1
ATTRS{idProduct}=="374b", ATTRS{idVendor}=="0483", MODE="666"

LABEL="openocd_rules_end"

Make sure your STLINK is recognized properly. Unplug and plug again your STLINK to the USB connector. Check that it is detected properly:

ls -l /dev/ttyA*
crw-rw-rw- 1 root uucp 166, 0 25 oct.  08:11 /dev/ttyACM0

let's try to connect to STM32

Now connect your ST-LINK with the USB cable and start openocd server in a dedicated terminal session (cd in nuttx before):

$ openocd
Open On-Chip Debugger 0.9.0 (2016-04-27-23:18)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
none separate
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : clock speed 950 kHz
Info : STLINK v2 JTAG v25 API v2 SWIM v14 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.239448
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Unable to match requested speed 1000 kHz, using 950 kHz
Info : Unable to match requested speed 1000 kHz, using 950 kHz
adapter speed: 950 kHz
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000438 msp: 0x200015d0
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
Info : Unable to match requested speed 8000 kHz, using 4000 kHz
adapter speed: 4000 kHz

In another dedicated terminal session (cd in nuttx before), start dbg. It should automatically connect to openocd server:

$ arm-none-eabi-gdb nuttx
GNU gdb (GDB) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from nuttx...done.
__start () at chip/stm32_start.c:243
243	{
(gdb)

Now load the firmware into the STM32. In gdb type “load”:

(gdb) load
Loading section .text, size 0x6044 lma 0x8000000
Loading section .ARM.exidx, size 0x8 lma 0x8006044
Loading section .data, size 0x5c lma 0x800604c
Start address 0x8000434, load size 24744
Transfer rate: 21 KB/sec, 6186 bytes/write.
(gdb) 

Run the code. In gdb type “c” (continue).

The RED and GREEN LEDS should be both ON on the nucleo board.

To stop the code, press Ctlrl+C

For more information on openocd: http://openocd.org/doc/html/index.html and for GNU gdb: https://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_toc.html

GNU Make doc may be also valuable: https://www.gnu.org/software/make/manual/make.html

Connect to the STLINK serial console

Open a new terminal and run the minterm:

$ miniterm.py /dev/ttyACM0 115200
miniterm.py /dev/ttyACM0 115200
--- Miniterm on /dev/ttyACM0  115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---

Press the black RESET button on the nucleo board, one should see the following in the terminal window:

miniterm.py /dev/ttyACM0 115200
--- Miniterm on /dev/ttyACM0  115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Hello, World!!

Congratulation ! You are started with Nuttx !