Skip to content
Henryk Paluch edited this page Apr 2, 2024 · 3 revisions

NuttX

Status: just programmed STM32 NUCLEO-F767ZI board (Nucleo 144 series???)

NuttX is popular RT system for small embedded controllers (for example STM32 Cortex-M family).

Also there exists open source Simulink clone called "pysimCoder" which is able to generate code for NuttX.

I'm newbie to both projects but I want to learn how control systems are designed.

Project Homepages:

Setup

There are generally needed two systems:

  • Host OS for development (usually Linux)
  • Target where NuttX is run (usually small embedded controller with ARM Cortex-M7)

Setup Host OS

Installing required packages:

# first we have to install most of development environment:
sudo apt install \
  bison flex gettext texinfo libncurses5-dev libncursesw5-dev xxd \
  gperf automake libtool pkg-config build-essential gperf genromfs \
  libgmp-dev libmpc-dev libmpfr-dev libisl-dev binutils-dev libelf-dev \
  libexpat-dev gcc-multilib g++-multilib picocom u-boot-tools util-linux

# Now we need kconfig (Kernel config - reused for this project) frontends
sudo apt-get install kconfig-frontends-nox

# we need to install cross-compilers for Targets:
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi

# Programming + usb utilities
sudo apt-get install openocd usbutils git

Common checkout (we will use it as base for different targets):

mkdir -p ~/nuttxspace/common
cd       ~/nuttxspace/common
git clone https://github.com/apache/nuttx.git nuttx
git clone https://github.com/apache/nuttx-apps apps

Common guide to build for target:

List available targets:

cd ~/nuttxspace/common/nuttx
# command below takes lot of time!
./tools/configure.sh -L | tee ~/boards.txt

Example for STM32 Nucleo 767ZI board

Target: STM NUCLEO-F767ZI

Clone common sources:

mkdir -p ~/nuttxspace/stm32
cd       ~/nuttxspace/stm32
# we use ../common to save Internet bandwidth
git clone ../common/nuttx nuttx
git clone ../common/apps apps

Here is list for my board STM32 Nucelo F767ZI:

fgrep 767 ~/boards.txt 

  nucleo-144:f767-evalos
  nucleo-144:f767-netnsh
  nucleo-144:f767-nsh

NSH is nut-shell - nice interface controlled over UART.

NOTE: If you are daring you can even try netnsh target (using LAN interface on F767ZI board - I don't use it)

Trying:

cd ~/nuttxspace/stm32/nuttx
./tools/configure.sh -l nucleo-144:f767-nsh
# easy wasy to customize:
make menuconfig

In menu config try:

  • Modified version from: https://www.youtube.com/watch?v=heSkSd-_70g
  • Device Drivers -> LED Support:
    • Enable: LED driver
    • Enable: Generic Lower Half LED Driver
  • Application Configuration -> Examples:
    • Enable: LED driver example
    • TODO: which LEDs to enable
  • Application Configuration -> NSH Library -> Disable Individual commands
    • ensure that "Disable printf" is NOT checked

Now you can go to Exit as long as you exit from menuconfig. To build binary for target:

# may take lot of time...
time make

Above command should build target ELF file: nuttx (unlike example in guide there is no longer extension .elf)

Flashing

We will follow https://elinux.org/Accessing_Devices_without_Sudo to grant openocd USB access without root privileges:

  • Debian already contains group plugdev so just add your user to it:
    $ sudo /usr/sbin/usermod -G plugdev -a $USER
  • now logout and login to ensure that you are member of group plugdev
  • try command id or groups and notice if output contains group plugdev
  • now connect your Nucleo board to PC - so we can see idVendor and idProduct
  • find Vendor:Product IDs:
    $ lsusb | fgrep ST-LINK
    
    Bus 002 Device 002: ID 0483:374b STMicroelectronics ST-LINK/V2.1
  • in our case idVendor=0x483, idProduct=0x374b
  • create /etc/udev/rules.d/10-st-link.rules with content:
    # Enable group "plugdev" to access ST-LINK V2 programmer
    ATTRS{idProduct}=="0x374b", ATTRS{idVendor}=="0x483", MODE="660", GROUP="plugdev"
    
  • reload rules with:
    sudo udevadm trigger
  • now again recall Bus and Device number:
    $ lsusb | fgrep ST-LINK
    
    Bus 002 Device 002: ID 0483:374b STMicroelectronics ST-LINK/V2.1
  • examine (in our case Bus=002, Device=002) device directory:
    $ ls -l /dev/bus/usb/002/002 
    
    crw-rw---- 1 root plugdev 189, 129 Apr  2 16:00 /dev/bus/usb/002/002
  • notice that group is now plugdev and group has read-write (rw) permissions.

Now run picocom to see bootup messages:

# in my case /dev/ttyACM0 already granted access to group "plugdev"
picocom -b 115200 /dev/ttyACM0

And then program board with:

cd ~/nuttxspace/stm32/nuttx/
openocd -f board/st_nucleo_f7.cfg -c init -c 'program nuttx verify reset' -c shutdown

Important!

Congratulations! You should see NSH on your picocom console:

NuttShell (NSH) NuttX-12.5.0-RC0
nsh> uptime
00:03:52 up  0:03, load average: 0.00, 0.00, 0.00

Problem:

  • there is no /dev/userleds device
    nsh> ls /dev
    
    /dev:
     console
     null
     ttyS0
    

Example: pic32mx

There are two PIC classes supported:

  • SAM - Cortex-M from acquisition of Atmel
  • PIC32MX and PIC32MZ, MIPS-4K core.

I have two boards with PIC32MX (MicrostickII with PIC32MX250 and Curiosity PIC32MX470). There are:

fgrep pic32mx ~/boards.txt 

  pic32mx7mmb:nsh
  pic32mx-starterkit:nsh
  pic32mx-starterkit:nsh2
  sure-pic32mx:nsh
  sure-pic32mx:usbnsh

Trying:

mkdir ~/nuttxspace/pic32mx
cd ~/nuttxspace/pic32mx
# trick to save bandwidth:
git clone  ../common/apps
git clone  ../common/nuttx

Actually most close board is here:

  • ~/nuttxspace/pic32mx/nuttx/boar~/mips/pic32mx/mirtoo/configs/nsh/defconfig

  • Microstick II uses PIC32MX250F128B while mirtoo uses PIC32MX250F128D

  • targets:

    mirtoo:nsh
    mirtoo:nxffs
    
  • trying:

cd ~/nuttxspace/pic32mx/nuttx
./tools/configure.sh -l mirtoo:nsh
make menuconfig
make

Oops:
sh: 1: mips-elf-gcc: not found 
ERROR: mips-elf-gcc failed: 127
       command: mips-elf-gcc -MT ./nsh_init.c.home.azureuser.nuttxspace.pic32mx.apps.nshlib.o  -M '-fno-common' '-Wall' 
'-Wstrict-prototypes' '-Wshadow' '-Wundef' '-Wno-attributes' '-Wno-unknown-pragmas' '-O2' '-fno-strict-aliasing' '-fomit
-frame-pointer' '-ffunction-sections' '-fdata-sections' '-mlong32' '-membedded-data' '-msoft-float' '-march=m4k' '-EL' '
-isystem' '/home/azureuser/nuttxspace/pic32mx/nuttx/include' '-D__NuttX__' '-DNDEBUG' '-D__KERNEL__' '-pipe' '-I' '/home
/azureuser/nuttxspace/pic32mx/apps/include' ./nsh_init.c

Other way

mkdir -p ~/gcc
cd ~/gcc
sudo apt-get install curl unzip
curl -fLO https://github.com/PinguinoIDE/pinguino-compilers/releases/download/v20.10/pinguino-linux64-p32.zip
unzip pinguino-linux64-p32.zip
sudo mkdir /opt/p32-2020
sudo mv p32/ /opt/p32-2020
cd /opt/p32-2020/p32/bin
for i in gcc ar ld nm objcopy;do sudo ln -s p32-$i mips-elf-$i;done

cd ~/nuttxspace/pic32mx/nuttx
export PATH=/opt/p32-2020/p32/bin:$PATH
make
# WOW! got:
nuttx.hex

TODO: Program

openocd -f interface/XXXXX.cfg -f target/pic32mx.cfg -c 'init' \
  -c 'program nuttx/nuttx.bin verify reset' -c 'shutdown'

Hmm, unable to see proper interface in usr/share/openocd/scripts/interface

Fallback: using MPLAB IPE

TODO: Test

Pic32mx and Nuttx or Pinguino resources:

Resources

Here are popular videos on these topics:

Clone this wiki locally