EmbeddedRelated.com
Blogs
The 2024 Embedded Online Conference

Getting Started with (Apache) NuttX RTOS Part 2 - Looking Inside and Creating Your Customized Image

Alan C AssisJuly 5, 2023

In the previous article (https://www.embeddedrelated.com/showarticle/1524.p...) we saw how to run NuttX RTOS using the SIMulator. Today we will see how NuttX's directory tree is organized and how to use the menuconfig to enable some applications, including some tricks to search and solve dependencies.

NuttX Directories organization:

This article is available in PDF format for easy printing

If you have previously compiled the Linux kernel or the U-Boot bootloader you will see that the NuttX source tree organization is very similar. By looking inside the "nuttx/" directory that you cloned from GitHub you will see these files and sub-directories:



Let’s look inside each one:

arch - this is the directory where all chips (microcontrollers, microprocessors, etc) are implemented. Inside this directory you will have all the semiconductors' vendors chips organized by their architecture (arm, arm64, avr, mips, misoc, risc-v, etc) and for each architecture you will have the families of chips (i.e. for arm: efm32, imx6, lpc31xx, nrf52, stm32, etc; for avr: at32uc3, at90usb, atmega, xmega; for mips: pic32mx, pic32mz; for risc-v: bl602, esp32c3, fe310, k210, etc).

audio - Audio subsystem support (for audio devices look at nuttx/drivers/audio/).

binfmt - Binary format support, i.e.: ELF file support.

boards - This is the directory where all the boards supported by NuttX will be found. Just like "arch/" this directory is organized by architectures and families.

crypto - Cryptography algorithms supported by NuttX.

Documentation - NuttX documentation in reStructuredText format. This folder’s files are rendered to  https://nuttx.apache.org/docs/latest/.

drivers - All generic drivers of NuttX are found inside this directory.

dummy - Just a placeholder directory with Kconfig to support external integration with NuttX build.

fs - All filesystems supported by NuttX are found here.

graphics - The original NuttX Graphics (NX Graphics) lives here, other graphics libraries like LVGL exist inside the Application repository at apps/graphics.

include - header files of all features and drives supported by NuttX, including POSIX libc library.

libs - All libraries such as libc and libm (System), libdsp (Digital Signal Processing), libnx (Graphics), libxx (C++ support), live here.

mm - Memory Management support.

net - Network support (ARP, IP, TCP, UDP, etc).

openamp - OpenAMP support integration for asymmetrical computing support.

pass1 - NuttX requires two passes compilation in some cases, like in Protected and Kernel mode, so the artifacts generated during the first compilation are saved here.

sched - Scheduler algorithms implementation.

syscall - Syscall used when compiling NuttX in Kernel mode. NuttX supports three memory modes: FLAT (for microcontrollers without Memory Protection), Protected (for microcontrollers with Memory Protection Unit (MPU) hardware) and Kernel mode (for microprocessors with Memory Management Unit (MMU)).

tools - Tools and scripts used by the build system or to help users to solve some specific subject.

video - Video mode support like VESA and EDID protocol.

wireless - All "wire-less" support (not Wireless, for that look at drivers/wireless/ieee80211), including Bluetooth, IEEE802.15.4, packet radio (non-standard radio protocols).

The remaining files in the root directory are common in almost all open-source projects, so nothing new here.

Listing all board profiles for a board:

In the previous article we tested the board profile "nsh" from the board "sim" (so sim:nsh). Now let us list all board profiles for this board "sim" (technically "sim" is not a board, but the abstract idea of this simulator as a board is the same). For that we will use the command:


$ ls boards/sim/sim/sim/configs/


Running a Rust application:

As you can see in the board profiles of sim (sim/configs/) there is an example called "rust", this is a Hello World implemented in Rust. Let's compile and test it.

Before testing a new board profile we need to clear the build:

$ make distclean

So now we can configure to use the board profile sim:rust this way:

$ ./tools/configure.sh sim:rust
  Copy files
  Select CONFIG_HOST_LINUX=y
  Refreshing...

If you don't have the Rust compiler (rustc) installed you will get this error message:

$ make
Create version.h
LN: platform/board to /home/alan/nuttxspace/apps/platform/dummy
Register: gpio
Register: hello_rust
Register: nsh
Register: sh
CP:  /home/alan/nuttxspace/nuttx/include/nuttx/config.h
RUSTC:  hello_rust_main.rs /usr/bin/bash: line 1: rustc: command not found
make[3]: *** [/home/alan/nuttxspace/apps/Application.mk:223:
hello_rust_main.rs.home.alan.apps.examples.hello_rust.o] Error 127
make[2]: *** [Makefile:53: /home/alan/nuttxspace/apps/examples/hello_rust_all] Error 2
make[1]: *** [Makefile:47: all] Error 2
make: *** [tools/LibTargets.mk:232: /home/alan/nuttxspace/apps/libapps.a] Error 2

Then we need to install the Rust compiler first, if you are using Ubuntu you can use this command:

$ sudo apt install rustc

And finally, compile it again:

$ make
LD:  nuttx
Let's run the SIMulator and execute the Rust example:
$ ./nuttx
login: admin
password: Administrator
User Logged-in!
nsh> ?
help usage:  help [-v] [<cmd>]
.      cat    dmesg  help   mkfatfs   pwd    test   uptime    
[      cd     echo   hexdump   mkrd   readlink  time   usleep    
?      cp     env    kill   mount  rm     true   xd  
alias  cmp    exec   losetup   mv     rmdir  truncate  
unalias   dirname   exit   ln     poweroff  set    uname
basename  dd     false  ls     printf sleep  umount    
break  df     free   mkdir  ps     source unset
Builtin Apps:
gpio     hello_rust  nsh      sh    
nsh> hello_rust
Hello, Rust!!
nsh> poweroff

Cool, but how to create a board profile with the applications you want to use?

Very simple: you can start with the basic profile like sim:nsh and select inside menuconfig the applications and features you want to use:

$ make distclean
$ ./tools/configure.sh sim:nsh
  Copy files
  Select CONFIG_HOST_LINUX=y
  Refreshing...

For this example, I want to select the test application "getprime" that searches for prime numbers and also is used as a kind of benchmark (although NuttX has a better tool for that called: coremark)

$ make menuconfig


Let's suppose that I don't know that getprime is defined at "Application Configuration  ---> Testing  ---> [*] getprime example", I can find it using the search feature from menuconfig: just press the key "/" (without quotes) and then type "getprime" or even only "prime":


Did you notice that "(1)" in front of "-> Testing" ?

If you press the number 1, menuconfig will move you directly to where the getprime is defined:


You can select this "getprime example" by pressing the Space key:



Now you can move the cursor to "" and hit Enter, repeat until asked to save:



Remember to press Enter inside this "" option to save this configuration.

Now you can compile:

$ make -j
Create version.h
LN: platform/board to /home/alan/apps/platform/dummy
Register: gpio
Register: hello
Register: dumpstack
Register: nsh
Register: sh
Register: getprime

And run the SIMulator to confirm that getprime appeared inside NuttX's NuttShell:

$ ./nuttx
login: admin
password: Administrator
User Logged-in!
nsh> ?
help usage:  help [-v] [<cmd>]
.      cat    dmesg  help   mkfatfs   pwd    test   uptime    
[      cd     echo   hexdump   mkrd   readlink  time   usleep    
?      cp     env    kill   mount  rm     true   xd  
alias  cmp    exec   losetup   mv     rmdir  truncate  
unalias   dirname   exit   ln     poweroff  set    uname
basename  dd     false  ls     printf sleep  umount    
break  df     free   mkdir  ps     source unset  
Builtin Apps:
dumpstack  getprime   gpio    hello   nsh     sh   
nsh> getprime
Set thread priority to 10
Set thread policy to SCHED_FIFO
Start thread #0
thread #0 started, looking for primes < 10000, doing 10 run(s)
thread #0 finished, found 1230 primes, last one was 9973
Done
getprime took 50 msec
nsh> poweroff

Since we confirmed that the getprime is working, now we can create a "getprime" board profile (or other name of your preference):

Save the default configuration with getprime enabled:

$ make savedefconfig
$ ls -l defconfig
-rw-r--r-- 1 alan alan 1810 jul  5 17:23 defconfig

Create a getprime board profile directory:

$ mkdir boards/sim/sim/sim/configs/getprime

Move our created defconfig to this directory:

$ cp defconfig boards/sim/sim/sim/configs/getprime/

Now, whenever we want to test the getprime, we don't need to run the menuconfig again and select it, we just need to use this board profile that we just created:

$ make distclean
$ ./tools/configure.sh sim:getprime
$ make -j
$ ./nuttx
login: admin
Password: Administrator
User Logged-in!
nsh> ?
help usage:  help [-v] [<cmd>]
.      cat    dmesg  help   mkfatfs   pwd    test   uptime    
[      cd     echo   hexdump   mkrd   readlink  time   usleep    
?      cp     env    kill   mount  rm     true   xd  
alias  cmp    exec   losetup   mv     rmdir  truncate  
unalias   dirname   exit   ln     poweroff  set    uname
basename  dd     false  ls     printf sleep  umount    
break  df     free   mkdir  ps     source unset
Builtin Apps:
dumpstack  getprime   gpio    hello   nsh     sh   
nsh> getprime
Set thread priority to 10
Set thread policy to SCHED_FIFO
Start thread #0
thread #0 started, looking for primes < 10000, doing 10 run(s)
thread #0 finished, found 1230 primes, last one was 9973
Done
getprime took 50 msec
nsh> poweroff

That's all Folks!

In the next article we will learn how to use NuttX on a real board and blink a LED!


The 2024 Embedded Online Conference

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: