Getting Started with (Apache) NuttX RTOS Part 2 - Looking Inside and Creating Your Customized Image
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:
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: *** [/home/alan/nuttxspace/apps/Application.mk:223: hello_rust_main.rs.home.alan.apps.examples.hello_rust.o] Error 127 make: *** [Makefile:53: /home/alan/nuttxspace/apps/examples/hello_rust_all] Error 2 make: *** [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: nuttxLet'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 "
Remember to press Enter inside this "
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!
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: