Adventures with NuttX
This page is a work in progress. I am documenting my adventures with the Real Time Operating System (RTOS) NuttX in "Real Time" as I learn the system. Last updated December 5th, 2024.
Table of Contents
- Video: NuttX RTOS Beginnings
- Conventions Used In This Article
- July 11, 2019: The Adventure Begins
- July 18, 2019: The Adventure Continues
- July 21, 2019: Using Code::Blocks IDE
- July 22, 2019: Using TI's CCSv9
- July 30, 2019: More on Using TI's CCSv9 with NuttX
- August 1, 2019: Even more on Using TI's CCSv9 with NuttX
- September 3, 2019: Seeing how make invokes the compiler
- December 10, 2019: NuttX to become an Apache Software Foundation (ASF) Project
- March 30, 2020: Updated various links on this page
- August 15-16, 2020: The NuttX Online Workshop (N.O.W.)
- March 31, 2021: An Update...
- August 21-22, 2021: The NuttX International Workshop
- May 15, 2022: Porting Low-Level Code From TivaWare to NuttX
- September 24-25, 2022: The NuttX International Workshop
- October 26, 2022: NuttX community discussing graduation from the Incubator
- November 17, 2022: Happy Graduation, Apache NuttX Top-Level-Project!
- November 25, 2022: NuttX runs on the PINE64 PinePhone!
- January 16, 2023: NuttX 12.0 released!
- September 28-29, 2023: The NuttX International Workshop in Campinas, Brazil
- December 5, 2024: A Worldwide Distributed Embedded Build Farm? (Part 1)
- NuttX Articles On Other Blogs
- References and External Resources
Video: NuttX RTOS Beginnings
This is a video of a presentation by Gregory Nutt, the creator of NuttX, at the NuttX 2019 International Workshop at Gouda, South Holland.
Conventions Used In This Article
In this article, $HOME will refer to the Linux user's home directory (/home/your-user-name-here).
$TOPDIR will refer to the NuttX RTOS source repository's top-level directory. We'll clone several NuttX-related Git repositories under $HOME/NuttX, so $TOPDIR would resolve to $HOME/NuttX/nuttx in our case.
July 11, 2019: The Adventure Begins
This section last updated November 25, 2022 to indicate moved repositories command lines that changed in recent versions of NuttX.
Okay, so I have a cacophony of different microcontroller architectures around here, including: formerly Atmel now Microchip AVR and XMega, Microchip PIC32 (MIPS core), Texas Instruments Tiva-C Series (TM4C12x, ARM core), ST Microelectronics STM32 (ARM core), and probably a few others that have fallen by the wayside. And I also write programs for the PC side of things.
The problem with writing programs for all these different chips is that the programming is different and non-portable between them. That goes for low-level stuff like register programming to operate the various on-chip peripherals as well as high-level stuff like network or USB support.
The different hardware vendors have tried to address portability by implementing software libraries, but generally this is only good within one part family. It's not helpful if your next board uses a different vendor's part.
Why not stick with just one part family then? Well I've tried that. But it's not realistic. Every project has different requirements and ultimately you have to pick the MCU that best fits the requirements.
So recenty I discovered a RTOS called NuttX. It's been around for well over a decade, supports chips from all the part families I mentioned (and then some), has some features I consider very interesting, and comes with a permissive open-source-friendly and business-friendly BSD license. Whether NuttX is the answer to my microcontroller software needs is something I don't know yet, but I've decided to document my adventures...
Getting Started
I have Mac, Windows, and Linux (among others) available to me. The NuttX documentation states that the development environment must be POSIX such as Linux or macOS. It could be Windows if a POSIX layer is installed, such as Cygwin, MSYS, MSYS2, Ubuntu/Bash shell on Windows 10, etc. But it looked to me like the path of least resistance would be to go with Linux. I might try on the other operating systems in the future and document that as well... we'll see.
My preferred Linux distribution is Debian because it's arguably the biggest one in terms of distribution. It seems like most Linux distributions are based on Debian (including Ubuntu and all the ones that are based on it). Debian just released Debian 10 "Buster" but I am still using Debian 9 "Stretch."
In my home directory I made a directory to hold all the NuttX stuff:
$ mkdir NuttX $ cd NuttX
NuttX and related things come in a bunch of different Git repos hosted on BitBucket.
(On a side note, I've seen projects get split across multiple repositories before; one of these days in my writings on Version Control I'll explain why that's less than optimal. I will say, here, that I strongly prefer Apache Subversion over Git because Subversion is both more capable and much simpler and easier to use than Git. That's a subject for another day.)
Anyway so I cloned the Git repos:
$ git clone https://bitbucket.org/nuttx/nuttx.git $ git clone https://bitbucket.org/nuttx/apps.git $ git clone https://bitbucket.org/nuttx/buildroot.git $ git clone https://bitbucket.org/nuttx/tools.git $ git clone https://bitbucket.org/nuttx/pascal.git $ git clone https://bitbucket.org/nuttx/uclibc.git
Update (November 25, 2022): In the time since this section of the article was written, the NuttX project joined the Apache Software Foundation. The nuttx and apps repositories are now at https://github.com/apache/nuttx and https://github.com/apache/nuttx-apps. If following along, make sure to make the necessary changes in your command lines. Note that the above-mentioned buildroot, tools, and uclibc repositories did not move to the ASF and are still at bitbucket.org. The pascal repository was removed entirely at some point. (I never used it so I cannot say whether there is any significance to that.)
I don't know if there are others but I wanted to have all the code available on my system.
Now to get something built.
I have a Texas Instruments (TI) Tiva C Series Crypto Connected LaunchPad, specifically called EK-TM4C129EXL, so I wanted to build NuttX for it. The latest NuttX release at this writing, 7.30, does not contain a port for that specific board but does contain one for the similar Tiva C Series Connected LaunchPad, EK-TM4C1294XL. So I thought I'd start with that.
$ cd $HOME/NuttX/nuttx $ tools/configure.sh -l tm4c1294-launchpad/nsh
Update (November 25, 2022): At some point (around NuttX 8.0 or 9.0, I think?), the board subdirectories were re-organized, owing (I think) to the growth in the number of boards supported by NuttX. To obviate the need to specify longer paths on the command line, the configuration script was modified to introduce a level of abstraction. The command to configure the above-shown board is now tools/configure.sh -l tm4c1294-launchpad:nsh. Notice that a colon (:) now separates the board name from the configuration. The script automatically finds the board and configuration within the new directory structure.
And I was met with an error related to lack of kconfig-conf.
After some searching, I found this page and this page, which led me to install some additional Linux packages that I was missing:
$ sudo apt-get install \ bison \ flex \ gperf \ libgmp-dev \ libmpc-dev \ libmpfr-dev \ libisl-dev \ binutils-dev \ libelf-dev \ libexpat-dev
(My system has numerous other packages on it which are related to development. I'll try to update this page later with all the ones needed, from a default Debian install, to work with NuttX.)
Even after installing all that stuff, kconfig-conf remained missing. After more searching I discovered that this tool is actually packaged with NuttX, in the "tools" repository. I had it under my $HOME/NuttX/tools/kconfig-frontends). So...
$ cd $HOME/NuttX/tools/kconfig-frontends $ ./configure --enable-mconf --disable-gconf --disable-qconf $ make $ sudo make install
Back in $HOME/NuttX/nuttx, when I tried to use it:
cd $HOME/NuttX/nuttx $ tools/configure.sh -l tm4c1294-launchpad/nsh
Update (November 25, 2022): Same note as above: tools/configure.sh -l tm4c1294-launchpad:nsh.
It failed with:
kconfig-mconf: error while loading shared libraries: libkconfig-parser-3.8.0.so: cannot open shared object file: No such file or directory make: *** [menuconfig] Error 127
I found a clue in $HOME/NuttX/tools/README.txt, under "kconfig-mconf Path Issues" where it mentioned that exact error. It turns out that ld didn't know where to find the shared library. There's a file called /etc/ld/so.conf that lists places ld should search, but ld doesn't read that file; you have to run ldconfig as root to make those settings take effect. It turns out that kconfig-conf was installed in /usr/local/bin, the library was installed in /usr/local/lib, and /etc/ld.so.conf did have /usr/local/lib in it (via /etc/ld.so.conf.d/libc.conf). I ran ldconfig as root and the problem went away:
$ sudo ldconfig
Having successfully configured NuttX for this board, I now needed a toolchain.
$ cd $HOME/NuttX/buildroot $ cp configs/cortexm4f-eabi-defconfig-7.3.0 .config $ make menuconfig $ make
Well, that ran for a while but failed somewhere in the middle because texinfo wasn't installed. So:
$ sudo apt-get install texinfo $ make
After a while, that succeeded.
To be continued! I'm going to call it quits for today. Let's recap where we are so far. I have cloned all the NuttX repositories into a NuttX directory under my home directory. I installed a bunch of needed packages and need to come back and make an exhaustive list. I built an ARM Cortex M4F EABI toolchain using the NuttX-provided buildroot, and now I think I'm ready to start building NuttX to run a test on my LaunchPad. Check back for more and feel free to write me with questions, comments, suggestions, criticisms, etc., at high12noon (the name of this blog), at mail, dot com.
July 18, 2019: The Adventure Continues
Building NuttX:
$ cd $HOME/NuttX/nuttx $ export TOOLCHAIN_BIN=(path to buildroot binaries) $ export PATH=$TOOLCHAIN_BIN:$PATH $ make menuconfig
In make menuconfig, make sure System type, Toolchain selection is set to buildroot.
$ make
This ran for a surprisingly short time! I expected a lengthy build given the size of the repository and the sheer number of source files. But then again, this is an operating system for very resource constrained devices and therefore it stands to reason that only a fraction of that code actually gets built.
It produced the files nuttx and nuttx.bin under $HOME/NuttX/nuttx.
Now, to get the code flashed to my microcontroller...
After my first post on July 11, 2019, and this one a week later, I found a bunch of resources regarding NuttX specifically, toolchains, developing for microcontrollers on Linux, etc. Until now, my development has always taken place on a Windows platform using MCU vendor-supplied IDE (Integrated Development Environments, usually based on Eclipse, NetBeans, MS Visual Studio, or a custom interface). This is the first time that I really have to get into the nitty gritty of getting all these different details setup and working. Suddenly compiling, flashing, and debugging are separate things supplied by separate unrelated pieces of software. That's why this is an adventure!
Among other things, I watched some videos on the NuttX YouTube channel, including:
- #001 - Setting the Development Environment for NuttX
- #002 - Compiling the NuttX Source Code
- #003 - Flashing NuttX in the STM32F103 Minimum Board
I also watched the following:
- NXWorld Lee's YouTube channel video: Using Code::Blocks IDE to compile and debug nuttx with OpenOCD.
I opted to build OpenOCD (Open On Chip Debugger) from source as shown in #001 - Setting the Development Environment for NuttX. Note that my commands below contain some modification to the commands shown in the video based on differences in my Linux install (such as installed packages) and the newer available version of OpenOCD since the video was made.
First I needed these packages:
$ sudo apt-get install \ minicom \ libncurses5-dev \ libusb-dev \ libusb-1.0-0-dev
Clone the OpenOCD Git repository:
$ cd $HOME/NuttX $ git clone http://repo.or.cz/r/openocd.git $ cd openocd/ $ ./bootstrap
There are many options. To list them all:
$ ./configure --help
This is how I configured it:
$ ./configure \ --enable-internal-jimtcl \ --enable-maintainer-mode \ --disable-werror \ --disable-shared \ --enable-stlink \ --enable-ti-icdi \ --enable-xds110 \ --enable-jlink \ --enable-rlink \ --enable-vsllink \ --enable-remote-bitbang $ make $ sudo make install $ sudo cp contrib/60-openocd.rules /etc/udev/rules.d/ $ sudo udevadm control --reload
With the board NOT connected to the computer's USB port:
$ lsusb
Showed a bunch of USB devices.
I connected the board to the computer's USB port and:
$ lsusb
Showed a bunch of USB devices, which now included (on my computer):
Bus 001 Device 005: ID 1cbe:00fd Luminary Micro Inc. In-Circuit Debug Interface
Starting up OpenOCD requires either a bunch of command line options or some configuration files that encapsulate the needed options.
According to the OpenOCD documentation, if no configuration files or commands are given on the command line (that is, no -f or -c options), OpenOCD will try to read a configuration file called openocd.cfg by default. In any event, it searches for the configuration file(s) at the following locations, until it finds one with the name it's looking for:
- The current directory
- Any search dir specified on the command line using the -s option
- Any search dir specified using the add_script_search_dir command
- $HOME/.openocd (not on Windows)
- A directory in the OPENOCD_SCRIPTS environment variable (if set)
- The site wide script library $pkgdatadir/site
- The OpenOCD-supplied script library $pkgdatadir/scripts
My computer didn't have a .openocd directory under $HOME. I guessed that pkgdatadir would be something like /usr/local/share/openocd/scripts so:
$ ls /usr/local/share/openocd/scripts/interface
shows:
altera-usb-blaster2.cfg imx-native.cfg stlink.cfg altera-usb-blaster.cfg jlink.cfg stlink-v1.cfg arm-jtag-ew.cfg jtag_vpi.cfg stlink-v2-1.cfg at91rm9200.cfg kitprog.cfg stlink-v2.cfg buspirate.cfg nds32-aice.cfg sysfsgpio-raspberrypi.cfg calao-usb-a9260.cfg opendous.cfg ti-icdi.cfg chameleon.cfg openjtag.cfg ulink.cfg cmsis-dap.cfg osbdm.cfg usb-jtag.cfg dummy.cfg parport.cfg usbprog.cfg estick.cfg parport_dlc5.cfg vsllink.cfg flashlink.cfg raspberrypi2-native.cfg xds110.cfg ft232r.cfg raspberrypi-native.cfg ftdi rlink.cfg
And
$ ls /usr/local/share/openocd/scripts/target
shows:
1986ве1т.cfg lpc1xxx.cfg adsp-sc58x.cfg lpc2103.cfg aduc702x.cfg lpc2124.cfg aducm360.cfg lpc2129.cfg allwinner_v3s.cfg lpc2148.cfg alphascale_asm9260t.cfg lpc2294.cfg altera_fpgasoc_arria10.cfg lpc2378.cfg altera_fpgasoc.cfg lpc2460.cfg am335x.cfg lpc2478.cfg am437x.cfg lpc2900.cfg amdm37x.cfg lpc2xxx.cfg ar71xx.cfg lpc3131.cfg armada370.cfg lpc3250.cfg arm_corelink_sse200.cfg lpc40xx.cfg at32ap7000.cfg lpc4350.cfg at91r40008.cfg lpc4357.cfg at91rm9200.cfg lpc4370.cfg at91sam3ax_4x.cfg lpc84x.cfg at91sam3ax_8x.cfg lpc8nxx.cfg at91sam3ax_xx.cfg lpc8xx.cfg at91sam3nXX.cfg ls1012a.cfg at91sam3sXX.cfg marvell at91sam3u1c.cfg max32620.cfg at91sam3u1e.cfg max32625.cfg at91sam3u2c.cfg max3263x.cfg at91sam3u2e.cfg mc13224v.cfg at91sam3u4c.cfg mdr32f9q2i.cfg at91sam3u4e.cfg nds32v2.cfg at91sam3uxx.cfg nds32v3.cfg at91sam3XXX.cfg nds32v3m.cfg at91sam4c32x.cfg nhs31xx.cfg at91sam4cXXX.cfg nrf51.cfg at91sam4lXX.cfg nrf51_stlink.tcl at91sam4sd32x.cfg nrf52.cfg at91sam4sXX.cfg nuc910.cfg at91sam4XXX.cfg numicro.cfg at91sam7a2.cfg omap2420.cfg at91sam7se512.cfg omap3530.cfg at91sam7sx.cfg omap4430.cfg at91sam7x256.cfg omap4460.cfg at91sam7x512.cfg omap5912.cfg at91sam9260.cfg omapl138.cfg at91sam9260_ext_RAM_ext_flash.cfg or1k.cfg at91sam9261.cfg pic32mx.cfg at91sam9263.cfg psoc4.cfg at91sam9.cfg psoc5lp.cfg at91sam9g10.cfg psoc6.cfg at91sam9g20.cfg pxa255.cfg at91sam9g45.cfg pxa270.cfg at91sam9rl.cfg pxa3xx.cfg at91samdXX.cfg qualcomm_qca4531.cfg at91samg5x.cfg quark_d20xx.cfg atheros_ar2313.cfg quark_x10xx.cfg atheros_ar2315.cfg readme.txt atheros_ar9331.cfg renesas_r7s72100.cfg atheros_ar9344.cfg renesas_r8a7790.cfg atmega128.cfg renesas_r8a7791.cfg atmega128rfa1.cfg renesas_r8a7794.cfg atsame5x.cfg renesas_rcar_gen3.cfg atsaml1x.cfg renesas_s7g2.cfg atsamv.cfg samsung_s3c2410.cfg avr32.cfg samsung_s3c2440.cfg bcm281xx.cfg samsung_s3c2450.cfg bcm4706.cfg samsung_s3c4510.cfg bcm4718.cfg samsung_s3c6410.cfg bcm47xx.cfg sharp_lh79532.cfg bcm5352e.cfg sim3x.cfg bcm6348.cfg smp8634.cfg bluenrg-x.cfg spear3xx.cfg c100.cfg stellaris.cfg c100config.tcl stellaris_icdi.cfg c100helper.tcl stm32f0x.cfg c100regs.tcl stm32f0x_stlink.cfg cc2538.cfg stm32f1x.cfg cs351x.cfg stm32f1x_stlink.cfg davinci.cfg stm32f2x.cfg dragonite.cfg stm32f2x_stlink.cfg dsp56321.cfg stm32f3x.cfg dsp568013.cfg stm32f3x_stlink.cfg dsp568037.cfg stm32f4x.cfg efm32.cfg stm32f4x_stlink.cfg efm32_stlink.cfg stm32f7x.cfg em357.cfg stm32h7x.cfg em358.cfg stm32h7x_dual_bank.cfg epc9301.cfg stm32l0.cfg esi32xx.cfg stm32l0_dual_bank.cfg exynos5250.cfg stm32l1.cfg faux.cfg stm32l1x_dual_bank.cfg feroceon.cfg stm32l4x.cfg fm3.cfg stm32lx_stlink.cfg fm4.cfg stm32_stlink.cfg fm4_mb9bf.cfg stm32w108_stlink.cfg fm4_s6e2cc.cfg stm32w108xx.cfg gp326xxxa.cfg stm32xl.cfg hi3798.cfg stm8l152.cfg hi6220.cfg stm8l.cfg hilscher_netx10.cfg stm8s003.cfg hilscher_netx500.cfg stm8s105.cfg hilscher_netx50.cfg stm8s.cfg icepick.cfg str710.cfg imx21.cfg str730.cfg imx25.cfg str750.cfg imx27.cfg str912.cfg imx28.cfg swj-dp.tcl imx31.cfg test_reset_syntax_error.cfg imx35.cfg test_syntax_error.cfg imx51.cfg ti-ar7.cfg imx53.cfg ti_calypso.cfg imx6.cfg ti_cc13x0.cfg imx6sx.cfg ti_cc13x2.cfg imx6ul.cfg ti_cc26x0.cfg imx7.cfg ti_cc26x2.cfg imx7ulp.cfg ti_cc3220sf.cfg imx8m.cfg ti_cc32xx.cfg imx.cfg ti-cjtag.cfg is5114.cfg ti_dm355.cfg ixp42x.cfg ti_dm365.cfg k1921vk01t.cfg ti_dm6446.cfg k40.cfg ti_msp432.cfg k60.cfg ti_rm4x.cfg ke0x.cfg ti_tms570.cfg ke1xf.cfg ti_tms570ls20xxx.cfg ke1xz.cfg ti_tms570ls3137.cfg kl25.cfg tmpa900.cfg kl25z_hla.cfg tmpa910.cfg kl46.cfg u8500.cfg klx.cfg vybrid_vf6xx.cfg ks869x.cfg xilinx_zynqmp.cfg kx.cfg xmc1xxx.cfg lpc11xx.cfg xmc4xxx.cfg lpc12xx.cfg xmos_xs1-xau8a-10_arm.cfg lpc13xx.cfg zynq_7000.cfg lpc17xx.cfg к1879xб1я.cfg lpc1850.cfg
When I tried to start OpenOCD with:
$ openocd -f interface/ti-icdi.cfg -f target/stellaris.cfg
it didn't work. After some searching, I somehow figured out to start it like this:
$ openocd -f interface/ti-icdi.cfg -c "transport select hla_jtag" -f target/stellaris.cfg Open On-Chip Debugger 0.10.0+dev-00921-g263deb38 (2019-07-18-17:17) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html hla_jtag Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : clock speed 21847 kHz Info : ICDI Firmware version: 1224 Info : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints Info : Listening on port 3333 for gdb connections
And of course I have no idea if that's the right way to do it but it seems to indicate that it connected to the board and is able to communicate.
To be continued! Once again I'm going to call it quits for the day... So far, I have cloned all the NuttX repositories and the OpenOCD repository into a NuttX directory under my home directory. I installed all kinds of needed packages and still need to come back and make that exhaustive list I promised. I built an ARM Cortex M4F EABI toolchain using the NuttX-provided buildroot. I built the NuttX nsh (Nutt Shell) example for TM4C1294 (which is very similar to the TM4C129ENCPDT on my EK-TM4C129EXL Crypto Connected LaunchPad). I built OpenOCD from source and I think it's actually communicating with my board. Check back for more and feel free to write me with questions, comments, suggestions, criticisms, etc., at the name of this blog, which is high12noon, of course, at mail dot com.
July 21, 2019: Using Code::Blocks IDE
Code::Blocks is a free, open source, cross platform, Integrated Development Environment (IDE). It is cross platform and is written with a graphics toolkit I like very much, wxWidgets. Also, it is much lighter weight than Eclipse.
Last time I built OpenOCD from source in preparation to use Code::Blocks IDE to edit, compile, flash program, and single-step debug NuttX. I even built NuttX successfully on the command line but sadly I didn't document it here. I think it was pretty straightforward. The only important thing was to set the PATH environment variable so that make could find the toolchain I built with buildroot. Once I did that, NuttX built.
But I like to work in an IDE. So I watched the following videos:
- NuttX Channel: #004 - Code::Blocks IDE integration to compile and debug NuttX
- NXWorld Lee's YouTube channel video: Using Code::Blocks IDE to compile and debug nuttx with OpenOCD
So I configured Code::Blocks approximately as described in those videos:
I installed Code::Blocks with:
$ sudo apt-get install codeblocks codeblocks-contrib
The NuttX Channel video did not show installing codeblocks-contrib but I thought what the heck, I might as well.
Once Code::Blocks was installed, I ran it and began configuring it to use the buildroot-based GCC ARM compiler and OpenOCD tools that I built earlier, as shown in the above-mentioned NuttX Channel video. I will repeat the steps I took (as well as I can given my sometimes hazy memory) because I diverged in some areas and also for my future reference in case the video becomes inaccessible or something. Most of the following instructions are very similar to the video, though:
- From the menu, I opened "Settings" → "Debugger..." The "Debugger settings" dialog appeared. In its sidebar, I highlighted "GDB/CDB debugger" which caused three buttons to appear to the right: "Create Config," "Delete Config," and "Reset defaults." I created a new configuration using "Create Config" and named it OpenOCD. For the Executable path, I entered $HOME/NuttX/buildroot/build_arm_hf/staging_dir/bin/arm-nuttx-eabi-gdb (I actually entered the full "hardcoded" path without the $HOME variable because I don't know if that would work). I left the settings at their defaults, which were:
- Debugger Type was set to GDB
- Disable startup scripts (-nx) (GDB only) (checked)
- Watch function arguments (checked)
- Watch local variables (checked)
- Enable watch scripts (checked)
- Catch C++ exceptions (checked)
- The other items were not checked.
- As for "Choose disassembly flavor (GDB only)" I left the value "System default."
- From the menu, I opened "Settings" → "Compiler..." For this step, I diverged a bit from what was shown in the video. With "Global compiler settings" highlighted in the sidebar, I set "Selected compiler" to "GNU GCC Compiler for ARM." Because I have so many different ARM-based platforms, I decided to create a specific one for NuttX and for ARM Cortex M4F. So I used the Copy button to make a copy of the GNU GCC Compiler for ARM profile and named my copy "NuttX GCC ARM Cortex M4F." I then went to the "Toolchain executables" tab and configured the compiler as follows:
- For "Compiler's installation directory" I set: $HOME/NuttX/buildroot/build_arm_hf/staging_dir (once again I actually entered the full "hardcoded" path without the $HOME variable)
- C compiler: arm-nuttx-eabi-gcc
- C++ compiler: arm-nuttx-eabi-g++
- Linker for dynamic libs: arm-nuttx-eabi-g++
- Linker for static libs: arm-nuttx-eabi-gcc-ar
- Debugger: GDB/CDB debugger : OpenOCD
- Resource compiler: (left blank)
- Make program: make
- I created a new empty project by going to "File" → "New" → "Project..." and selecting "Empty project" in the dialog that appeared. In the project wizard, I gave the project the title "nuttx" and placed it in the $HOME/NuttX directory, which is the parent directory of my nuttx repository. I think it was significant that the project was named nuttx with the same spelling and lowercase letters as the binary file produced by NuttX's makefile. As the above-mentioned NuttX Channel video shows, I removed the values from "Output dir" and "Objects output dir" for the Debug configuration. I renamed the Debug configuration to "all" (in the text field next to "Create 'Debug' configuration." I removed the Release configuration by removing the checkmark from "Create 'Release' configuration." I exited this dialog by clicking "Finish."
- In the Projects view, which by default runs down the left side of the Code::Blocks window, I right-clicked the "nuttx" project and opened Properties from the context menu. This opened the "Project/targets options" dialog. In the "Project settings" tab, I placed a checkmark at "This is a custom Makefile." I then went to the Debugger tab, as shown in the video. Under "Select target" I selected "all" and in the "Remote Connection" sub-tab (located within the "Debugger" tab) I set the IP address to 127.0.0.1 (the loopback address) and port 3333. (Remember earlier, when OpenOCD said it was listening on port 3333 for gdb connections? That's why.) Then, in the Additional GDB commands sub-tab, I entered slightly different commands than shown in the video for "After connection," namely:
- On the first line: "monitor reset init"
- On the second line: "load nuttx"
- On the third line, here is where we diverge from the video, I entered "b nx_start" instead of what the video shows. (The video shows "b os_start".) This command puts a breakpoint at the nx_start() function and causes the board to run to that breakpoint. It didn't work for me with os_start because, as I understood from scouring various places, the function was renamed sometime between when the video was made and now.
- The video shows nuttx being configured on the command line using the tools/configure.sh script and make menuconfig. I didn't need to do this because my nuttx was already configured. Caveat: I think I did do make menuconfig to turn on debugging information and to suppress optimization. You always want to suppress optimization when single-step debugging; otherwise the debugger seems to jump all over the place for no rhyme or reason, because actually the compiler reorders instructions for best performance and/or smallest code when you optimize.
- The video also shows editing the linker script (in the video's case under configs/stm32f103-minimum/scripts/ld.script, but I'm using a TI TM4C129ENCPDT). If I understand correctly, the purpose of this edit was to lie to the linker about the processor's flash storage capacity. Otherwise the video maker reported that the linker was failing, presumably because debugging information made the code too big. I didn't do this and my code did link successfully without it. Of course, depending on your MCU and its size, your mileage may vary.
- Back in Code::Blocks, the video shows right-clicking the nuttx project in the Projects view, selecting "Add files recursively," choosing the nuttx directory, using Select All to select all the files and directories therein, and adding them to the project. This worked for me, but after doing it, the IDE started going haywire, locking up, crashing, windows not sizing correctly... I don't know why. So after several attempts, I decided to skip this step and not add any files to the IDE project. They'll still build correctly (because building is done by the makefile) and single-stepping still worked correctly, though I'll talk more about that in a moment.
- At this point, I built the project by going to "Build" → "Build" in the menu. NuttX built. The Code::Blocks "Build log" tab showed the same kind of output I had come to expect from building NuttX on the command line previously.
- Back on the command line, I started OpenOCD. This time, I used a script that comes with NuttX:
$ $TOPDIR/configs/tm4c1294-launchpad/tools/oocd.sh $HOME/NuttX/nuttx
- Back in Code::Blocks, I went to "Debug" → "Start / Continue." This opened some kind of blank Xterm window, FLASH-programmed the nuttx executable to the board, and started the debugger, placing the cursor at nx_start().
The above worked, but I had a couple of problems.
First of all, single-stepping was rather slow. Specifically, single-stepping through C came with a frustrating and very noticeable delay between each step. Single-stepping through assembly was reasonably quick.
Secondly, I like how other IDEs show an easy-to-interpret gauge that tells me how much of Flash and RAM I'm using as a percentage of my MCU's Flash and RAM capacity. I couldn't figure out how to do this with Code::Blocks.
So, even though everything technically worked, I decided to try TI's Code Composer Studio (CCS). That's a job for next time.
I do like Code::Blocks and have worked with it (and still work with it) pretty extensively, so if you know of a way to speed up single-step debugging or what to do about the IDE going haywire and crashing when I added all the NuttX files to the project, please drop me a line!
July 22, 2019: Using TI's CCSv9
Previously, I had set up Code::Blocks IDE to work on NuttX and my programs for it, but I ran into an issue where single-stepping was slow and there was no memory usage gauge. So I decided to try TI's Code Composer Studio (CCS). Recently they released CCS version 9 (which I'll call CCSv9).
I started by installing CCS in my Linux machine. I went to ti.com and searched for "CCS" in the website's Search bar. Then, I selected the first search result, "Code Composer Studio (CCS) Integrated Development Environment (IDE) CCSTUDIO (ACTIVE)." From here, there was a download link. Clicking on that link took me to another page, where I could download actual files as well as read the Linux Installation Instructions. At the time of this writing, the latest version of CCS is version 9.1.0.00010. According to TI, they test CCS on Ubuntu LTS distributions and one CentOS distribution. All other installation instructions are provided for reference (and are sometimes contributed by community members). Despite this notice, I found that CCS installed perfectly on my Debian "Stretch" machine. Note: As far as I know, Ubuntu is based on Debian, so I think they're close cousins. I didn't have any of the potential issues mentioned on that page. Back at the download page, I downloaded the latest available Linux off-line installer, which came out to some 850 MB. I untarred this and ran the installer. I followed the screens in the graphical installers and everything went smoothly.
I opened CCS and began to setup a project to build, load, and run NuttX as follows:
In the command line, I created a directory at $HOME/NuttX/NuttxCCS to hold the TI Code Composer Studio 9 (CCSv9) project, adjacent to the nuttx and apps directories.
In CCSv9, I created a new CCS project by going to "Project" → "New CCS Project." In the dialog that appeared:
- I named the project "NuttxCCS" and placed it in the NuttxCCS directory I created a moment ago.
- I chose the MCU part number, in my case TM4C129ENCPDT.
- I chose the GNU ARM compiler (Linaro). This is now the compiler that comes embedded in and installed with CCS, not the buildroot ARM compiler I built previously.
- I told it not to create a main program.
In the "Project Explorer" (by default this view appears along the left side of the CCS window), I right-clicked the NuttxCCS project and opened Properties (located all the way at the bottom of the context menu). In the Project Properties dialog that appeared (while Debug build configuration is selected), I made the following changes. Note that I've experienced CCS "forgetting" some changes when I make too many to a project, so I recommend changing a few settings, applying and closing the dialog, and then reopening it to make more changes.
Note: The following is a bit messy because I wanted to document it all as quickly as possible, before I forget the steps. At some point I plan to come back, clean this up, and improve the instructions.
Project properties dialog:
- Show advanced settings (link at bottom)
- CCS Build:
- No checkmark on "Use default build command"
- No checkmark on "Generate Makefiles automatically"
- Set "Build location" → "Build directory" to "${PROJECT_LOC}/../nuttx"
- No checkmark on "Enable parallel build"
- No checkmark on "Build on resource save (Auto build)
- Checkmark on Build (Incremental build) and "all" in text field.
- Checkmark on Clean and "clean" in text field.
- GNU Compiler, GNU Linker, GNU Objcopy Utility: These settings have no effect on the build because it is controlled by the NuttX makefile. However, to avoid displaying misleading information, you can remove any include paths from CCS Build → GNU Compiler → Directories and any predefined preprocessor symbols from CCS Build → GNU Compiler → Preprocessor.
- C/C++ Build:
- Builder type: External builder
- Build command: make -k
- No checkmark on "Generate Makefiles automatically"
- Set "Build location" → "Build directory" to "${PROJECT_LOC}/../nuttx"
- C/C++ Build → Environment: Prepend PATH with: "${ccs_install_root}/tools/compiler/gcc-arm-none-eabi-7-2017-q4-major/bin:" using that last colon as the delimiter between that and the rest of the path.
- Settings: Binary Parsers: Check mark on Elf Parser only.
- Settings: Error Parsers: Check marks on GNU gmake Error Parser 7.0, GNU Assembler Error Parser, GNU Linker Error Parser, and GNU gcc/g++ Error Parser.
- Debug:
- Device: Stellaris In-Circuit Debug Interface_0/CORTEX_M4_0
- Auto Run and Launch Options:
Auto Run Options:- Run to symbol: nx_start
- Check mark on "On a program load or restart"
- Check mark on "On a reset"
- Run/Debug Settings:
- Launch configurations: Select the launch configuration and Edit.
- Program tab:
- Device: Stellaris In-Circuit Debug Interface_0/CORTEX_M4_0
- Project: NuttxCCS (or the project name)
- Program: Path to the nuttx binary (e.g., $HOME/NuttX/nuttx/nuttx)
- Loading options: Check mark on "Load program"
- Source tab:
- Add source lookup path, being the nuttx directory (e.g., $HOME/NuttX/nuttx)
- Put that directory at the top of the list with the Up button.
In command line, go to nuttx $TOPDIR and:
$ make clean $ make menuconfig
In menu config:
- Build Setup:
- Build Host Platform: Linux
- Debug Options: Generate Debug Symbols
- Optimization Level: Suppress Optimization
- System Type:
- Toolchain Selection: Generic GNU EABI toolchain under Linux (or other POSIX environment)
In CCS, Project → Clean (and perform build). If everything is configured correctly above, the project will build.
Debug: If all is configured correctly above, the project will load and run.
To get the Memory Allocation view to work, the linker needs to generate a "map" file usable by CCS. The NuttX build system produces a file called System.map but CCS cannot parse it. Therefore it is necessary to add a custom linker option. According to patacongo, "Make.defs is a part of your board and you are free to modify it as you like." The Make.defs actually used during the build process is in $TOPDIR, but it gets there by being copied when $TOPDIR/tools/configure.sh is run to select a board and configuration. So it is best to make the edit in our board's config directory (in our case that's $TOPDIR/configs/tm4c1294-launchpad/Make.defs), and then copy that over the one in $TOPDIR. Edit Make.defs and add the following at or near the bottom of the file:
LDFLAGS += -Map=$(TOPDIR)/nuttx.map
According to Chester Gillon in a post on TI's e2e forum, the CCS Memory Allocation view is hard-coded to parse a .map file located at ${BuildDirectory}/${ProjName}.map. In our case, that would be $HOME/NuttX/NuttxCCS/Debug/NuttxCCS.map. This appears to be true as of this writing with CCS Version: 9.1.0.00010. Since we do not know of a user-accessible setting to change it, we work around this by creating a symbolic link:
$ cd $HOME/NuttX/NuttxCCS/Debug $ ln -s ../../nuttx/nuttx.map NuttxCCS.map
Alternately, if you don't want to create the symbolic link, you can open any (properly formatted) .map file in the Memory Allocation view: Go to that view's menu (small down-pointing triangle) and select "Open TI link-info or GNU linker-map file..." and choose the nuttx.map file, at $TOPDIR/nuttx.map (or any other .map file you wish to examine).
With CCS, I got both of the things that I found lacking in yesterday's Code::Blocks setup, namely that single-step debugging through C code was sped up considerably and I got a working Memory Allocation view that shows Flash and RAM usage as a percentage of total available on the microcontroller. Once again, I do like Code::Blocks so if you know how to speed up single-step debugging there, please let me know!
July 30, 2019: More on Using TI's CCSv9 with NuttX
Increasing Scroll Back Buffer for the CDT Build Console
CCS is based on Eclipse and uses a part of Eclipse called CDT (C Development Tools). When building, the build output (all that text from make that scrolls up the screen) is displayed in a view called Console, which shows the CDT Build Console.
I noticed that with the default settings, the NuttX build generated too much output for the CDT Build Console, so if I wanted to look near the beginning of the build output for something that might cause an error, I couldn't because it had been lost. To fix this:
- In the menu, open Window → Preferences.
- In the dialog that appears, make sure that advanced settings are displayed. If there is a link at the bottom of the dialog labeled "Show advanced settings" click it. This will show additional settings in the left sidebar of the dialog box.
- In the sidebar, find and expand "C/C++" → "Build" → "Console"
- Find the item "Limit console output (number of lines)" and set it to something larger. Mine was initially set to 500. I increased it to 20000. This setting seemed to work for me.
- Apply and close the dialog.
Since we are using CCS slightly differently than TI expected, it seems necessary to show advanced settings in multiple places. So far I've done that in Project Properties (described last time) and in the Preferences dialog as I just explained above. Initially, I hadn't noticed that some preferences were hidden, so when I tried to find and enlarge the console scrollback I ended up doing it for the Run/Debug console, which is something else, and I saw no improvement. Showing advanced settings and updating the setting for the C/C++ Build Console made all the difference.
Showing source files in the Project Explorer
The other improvement I made is for the project itself.
Normally, if there is a build error, it should be possible to double-click the error either in the CDT Build Console or the Problems view and CCS should open the offending source file and place the cursor on the offending line. This wasn't happening. I thought that was a bit strange because source-level debugging worked (when I built with debug information and optimizations suppressed) but it didn't work for build errors. Nor was I able to use the indexer to navigate (e.g., by right-clicking an identifier and choosing "Open Declaration").
I fixed this by adding the "nuttx" and "apps" folders to the project as Linked Folders. The way to do this is not entirely intuitive because you might be tempted to right-click the project in the Project Explorer and choose "Add Files." But apparently that's not the right way.
Instead:
- Right-click the project in the Project Explorer and choose "New" → "Folder."
- Make sure the project is selected in the list (in my case it's called NuttxCCS), not "RemoteSystemsTempFiles."
- Click "Advanced" (notice a theme for today?)
- Select the radio button for "Link to alternate location (Linked Folder)"
- In my case, I placed the NuttxCCS directory containing the CCS project adjacent to the nuttx and apps directories. Therefore the path to nuttx is "../nuttx" relative to the project. So in the text field below "Link to alternate location" I entered:
${PROJECT_LOC}/../nuttx
as the path. - Make sure "Choose file system" is set to "default"
- Click Finish to add the linked folder.
- It might ask a bunch of times (once for each .cfg file it finds) if you want to enable XDCtools. Select "No" each time and be careful because the order of the No and Yes buttons are reversed! (At least on my system!)
- Wait for it to build its index, or whatever it's doing.
- Repeat the above process to add the apps directory, using
${PROJECT_LOC}/../apps
as the path.
Now, if all went well, build errors can be double-clicked to jump straight to the offending file and line.
That's all for today! See you soon.
August 1, 2019: Even more on Using TI's CCSv9 with NuttX
Stop lengthy "Searching for Binaries"
As mentioned before, CCS is based on Eclipse.
Each time I built the project, I noticed a lengthy Eclipse task called "Searching for Binaries" running for quite some time. I wanted to stop this from bogging down my system. After a quick search, I found the answer to this one here: According to Alex Mueller:
Eclipse searches for the binaries to fill the virtual folder "Binaries" in your project (see Project Explorer). These binaries are also used when you create a Launch Configuration.
If you are using an external Makefile Eclipse does not which binaries were created by the build step. Therefore, after every build it searches the complete project for changes.
Mueller writes that you can limit the search scope. That's exactly what I want, to limit the search scope to the one file I know matters, nuttx. So I followed Mueller's instructions to go to "Project Properties" → "C/C++ General" → "Paths and Symbols" → the "Output location" tab. There is a tree view titled "Output folders on build path" containing search locations. There was only one item in the list: "NuttxCCS/nuttx" with an arrow indicating the item can be expanded. Expanding this item reveals a filter, which was initially empty. I highlighted it, clicked "Edit Filter..." and added multiple items: Everything in the nuttx directory except the nuttx binary itself.
Having made this change, I built the project and there was no lengthy "Searching for Binaries"—in fact the search was pretty much instantaneous! When it comes to computers, I like speed!
Stay tuned for more!
September 3, 2019: Seeing how make invokes the compiler
It happened a few times that I needed to see exactly how make was invoking the compiler.
Normally, only something like this is printed to the console:
CC: name_of_file.c
But I need to see how the compiler was actually invoked, as in what command line arguments it received.
Googling around, I found all sorts of advice, such as passing --debug=j to make, etc., but it didn't work in this case.
After some experimentation and more searching, I figured out that what I wanted could be achieved by passing a V=1 argument to make:
$ make V=1
Now it prints all kinds of details, like this:
CC: name_of_file.c arm-none-eabi-gcc -c -fno-builtin -funwind-tables -Wall -Wstrict-prototypes -Wshadow -Wundef -g -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -I. -isystem /home/builder/NuttX/nuttx/include -D__KERNEL__ -ffunction-sections -fdata-sections -pipe -fdebug-prefix-map=..= -I/home/builder/NuttX/nuttx/sched -I/home/builder/NuttX/nuttx/arch/arm/src/chip -I/home/builder/NuttX/nuttx/arch/arm/src/common -I/home/builder/NuttX/nuttx/arch/arm/src/armv7-m name_of_file.c -o name_of_file.o
December 10, 2019: NuttX to become an Apache Software Foundation (ASF) Project
This isn't so much a technical update as a bit of news. Until the present time, NuttX has been a project run almost exclusively by one person, Gregory Nutt. With support for myriad processor architecture and microcontroller variants, the codebase has grown so large that Mr. Nutt decided it would be best to continue its development as an Apache.org project.
The way Apache.org works is that projects that want to become part of ASF must first become a "podling" in the ASF Incubator. During "incubation" the project undergoes a transition period until all its processes are operating according to the "Apache Way" at which time the project can graduate to become an Apache "top-level project."
At the time of this writing, only the very first parts of this process have taken place, namely the proposal was made, a vote took place (which passed unanimously), and the project is now beginning its first step as an ASF podling.
Stay tuned while this story develops!
Update (October 26, 2022): The Apache NuttX (Incubating) community is apparently beginning the process of graduating the Apache Incubator and becoming an Apache Software Foundation Top Level Project (TLP). See NuttX community discussing graduation from the Incubator below.March 30, 2020: Updated various links on this page
Since NuttX joined the Apache Software Foundation by becoming an Apache.org Incubator Podling, the NuttX website and documentation have moved from their former web addresses to Apache.org servers. Also, some 3rd party NuttX sites, such as the former nuttx2019.org, have been moved to new locations, such as nuttx.events.
The ongoing changes will ultimately be good for the future of NuttX, but they resulted in various broken links in the sections above. So I went ahead and tracked down all their new locations and updated the links.
If you do find any more broken links, please let me know and I'll go hunting for their new locations.
Thanks for reading and come back soon!
August 15-16, 2020: The NuttX Online Workshop (N.O.W.)
This section last updated August 20th, 2020.
A NuttX 2020 event was planned to take place in Tokyo. However, because of the pandemic, the event was held online instead. The NuttX Online Workshop (N.O.W.) was held online August 15-16, 2020. The video footage and presentations can be seen on YouTube by following the links below:
Note: While the primary place to communicate with the NuttX developers and users is at the NuttX mailing lists, some questions and answers can be found in the forums that were set up for the event, also listed below. Links to other articles about some of these projects are included below as well.
- Day 1 (full video, from the beginning):
- NuttX at Fitbit - Andrei Voinescu
Video (0:09:08), Q&A Forum - Implementing a USRSOCK-Based WiFi Driver on NuttX - Masayuki Ishikawa
Video (1:06:08), Q&A Forum - A Linux-Compatible Compounded RTOS Based on NuttX, Linux and Jailhouse - Chung-Fan Yang
Video (2:04:50), Q&A Forum - A Bit of SmartFS Talk - Iulian Matesica
Video (3:06:50), Q&A Forum - NuttX on the BeagleBone Black - Petro Karashchenko
Video (4:07:20), Q&A Forum - SocketCAN on NuttX - Peter van der Perk
Video (5:04:25), Q&A Forum - A Journey from Fork to Mainline - Alin Jerpelea
Video (6:04:59), Q&A Forum - Bringing NuttX to the FGPA with the QuickLogic EOS 3 - Brennan Ashton
Video (7:04:30), Q&A Forum - NuttX In A Flat Memory-Constrained Environment - Andrei Voinescu
Video (8:04:26), Q&A Forum
- NuttX at Fitbit - Andrei Voinescu
- Day 2 (full video, from the beginning):
- Prize Announcement, First Draw - Alan C. Assis et al.
Video (0:12:20) - Porting the Rust Standard Library to NuttX/Cortex-M4F and Prototyping a Simple Web Server - Yoshinori Sugino
Video (0:28:35), Q&A Forum - Swimming to Antarctica with NuttX - Christian Catchpole
Video (0:52:40), Q&A Forum - Javascript Robot on NuttX - Philippe Coval
Video (1:49:55), Q&A Forum - BicycleCompanion: an Open-Source Low-Power Bicycle Computer Based on NuttX - Matias Nitsche
Video (2:21:00), Q&A Forum
This project is featured at Hackaday. (See also this Hackaday article by Brian McEvoy. - Tickless Round Robin - Vlad Urziceanu
Video (4:11:40), Q&A Forum - Battery Management in NuttX with NXP RDDRONE-BMS772 - Jari van Ewijk, Cis van Mierlo
Video (4:45:40), Q&A Forum - NuttX in Professional Sports - Ivan Ucherzhiev
Video (5:24:00), Q&A Forum - Scaling Up Tasks, Signals, and Scheduling for Fitness Devices - Cosmin Petrisor
Video (6:07:30), Q&A Forum - NuttX for ESP32: Current Status and Next Developments - Alan Carvalho de Assis
Video (6:48:15), Q&A Forum - Motorcycle Sports Lap Timer Using NuttX - Ben (Disruptive Solutions)
Video (7:10:00) - Community Discussion
Video (7:27:10) - Final Prize Draw
Video (7:38:16)
- Prize Announcement, First Draw - Alan C. Assis et al.
March 31, 2021: An Update...
Many things have happened since my last significant update here, but I hope to get back into regularly documenting my adventures here.
Until now, I've described in (excruciating?!) detail how I've gotten NuttX to build and run on the TI TM4C129x microcontroller but at the outset I mentioned that my reason to dive headlong into NuttX is that I work with many different microcontroller architectures and the programming is very different when jumping from one family to another.
Oh, all the various microcontroller vendors support programming in C, but that's basically where the similarities end. From there, you have three options: you could write bare-metal firmware and operate the chip's basic peripherals by stuffing values into registers; or you could write bare-metal firmware and use a library of hardware abstraction function provided by the chip vendor to encapsulate some of the details of the peripherals; or you could go the RTOS route, and some chip vendors have one or more favorite RTOSes that you could choose from.
The biggest problem with all of those approaches is that, again, they're not portable. Even if you use a hardware abstraction library such as TI's TivaWare for the TM4C129x or STmicro's HAL for the STM32 families, your software is still stuck on that vendor's chips, and sometimes, on a particular model of chip. When your customer needs next-generation electronics with added new features that require a different microcontroller, you often end up having to rework much of the code to fit the new chip, starting back at square one for the most low-level details. At least that has been my experience.
So when I discovered NuttX, its long list of supported microcontroller architectures, its goal of sticking as much as possible to POSIX or POSIX-like standards, and its vibrant developer community, I found a viable and smarter way to write quality firmware with mobility between different microcontroller families.
I have several updates to this Adventure series in the works, which I hope to post soon, and in which I hop over to the STM32 family for the latest project I'm working on. Stay tuned for topics including:
- NuttX on STM32
- Debugging NuttX With GDB's Text User Interface (TUI)
- Using STmicro's STM32CubeIDE with NuttX
August 21-22, 2021: The NuttX International Workshop
This section last updated February 22nd, 2022.
The 2021 NuttX event was held online like its counterpart of the prior year. A recording of the entire two-day event and all its presentations can be seen on YouTube by following the links below.
Note: The primary place to communicate with the NuttX developer and user community is at its mailing lists.
- Day 1 (full video, from the beginning):
- Introducing Xiaomi VelaOS powered by NuttX - Yaoyao Gu, Xiaomi
Video (00:19:40) - NuttX Support Status for ESP32 - Ricardo Tafas, Espressif Systems
Video (01:15:13) - Demo: using NuttX to monitor electrical energy generated by mini solar panels - Pedro Bertoleti
Video (01:49:47) - Task Trace for NuttX - Yuichi Nakamura, Sony
Video (02:20:05) - Rapid Control Prototyping with pysimCoder & NuttX - Roberto Bucher
Video (03:12:20) - NuttX integration with pysimCoder - Michal Lenc
Video (04:10:50) - Demo: Edge Impulse on Sony's Spresense - Louis Moreau, Edge Impulse
Video (04:41:30) - Firmware updates on Fitbit devices - Silviu Grigore
Video (05:10:00) - Demo: Meadow + NuttX - Bryan Costanich, Wilderness Labs
Video (05:57:43) - SpO2 - Hardening complex health metrics computations on NuttX - Irina Presa, Fitbit
Video (06:09:50) - NuttX puts you in complete control of a smart battery with unique features - Cis van Mierlo, Jari van Ewijk, NXP
Video (07:18:32) - Signalling Task Group on Realtime - Sara Monteiro, Espressif Systems
Video (08:12:30) - Software Architecture for Industrial IoT Gateway Applications - Flavio de Castro Alves Filho, PHI Innovations
Video (09:12:00) - Realtime Trace for Embedded Development - Dave Marples
Video (10:10:30)
- Introducing Xiaomi VelaOS powered by NuttX - Yaoyao Gu, Xiaomi
- Day 2 (full video, from the beginning):
- Transition and Future of SPresense SDK - Takayoshi Koizumi
Video (00:18:33) - NuttX porting for Raspberry Pi Pico - Yuichi Nakamura, Sony
Video (00:59:25) - Current status of the NuttX SMP kernel - Masayuki Ishikawa, Sony
Video (02:02:55) - NuttX Status Report - Alin Jerpelea
Video (03:01:17) - Bringing NuttX to NXP S32K3 Family - Peter van der Perk, Jari van Ewijk, NXP
Video (04:01:25) - NuttX, an RTOS in my demo toolbox - Phil Coval
Video (05:04:00) - microROS for ESP32 under NuttX - Felipe Neves
Video (05:53:10) - MultiWii/Msp with Electron/React GUI - Ben & Edwin
Video (07:07:16) - Running .NET/C# on Microcontrollers with NuttX - Matheus Castello
Video (08:00:30) - MCUboot bootloader on NuttXChannel - Gustavo Nihei, Espressif Systems
Video (09:04:20)
- Transition and Future of SPresense SDK - Takayoshi Koizumi
May 15, 2022: Porting Low-Level Code From TivaWare to NuttX
The following tables show the correspondence between TivaWare identifiers and their NuttX Tiva counterparts, to assist developers in porting low-level code written for TivaWare to NuttX.
This section is a work in progress. I will try to add additional tables as I need them.
Section Contents
Memory Map
TivaWare | NuttX | Value | Description |
---|---|---|---|
WATCHDOG0_BASE | TIVA_WDOG0_BASE | 0x40000000 | Watchdog0 |
WATCHDOG1_BASE | TIVA_WDOG1_BASE | 0x40001000 | Watchdog1 |
GPIO_PORTA_BASE | TIVA_GPIOA_BASE | 0x40004000 | GPIO Port A |
GPIO_PORTB_BASE | TIVA_GPIOB_BASE | 0x40005000 | GPIO Port B |
GPIO_PORTC_BASE | TIVA_GPIOC_BASE | 0x40006000 | GPIO Port C |
GPIO_PORTD_BASE | TIVA_GPIOD_BASE | 0x40007000 | GPIO Port D |
SSI0_BASE | TIVA_SSI0_BASE | 0x40008000 | SSI0 |
SSI1_BASE | TIVA_SSI1_BASE | 0x40009000 | SSI1 |
SSI2_BASE | TIVA_SSI2_BASE | 0x4000a000 | SSI2 |
SSI3_BASE | TIVA_SSI3_BASE | 0x4000b000 | SSI3 |
UART0_BASE | TIVA_UART0_BASE | 0x4000c000 | UART0 |
UART1_BASE | TIVA_UART1_BASE | 0x4000d000 | UART1 |
UART2_BASE | TIVA_UART2_BASE | 0x4000e000 | UART2 |
UART3_BASE | TIVA_UART3_BASE | 0x4000f000 | UART3 |
UART4_BASE | TIVA_UART4_BASE | 0x40010000 | UART4 |
UART5_BASE | TIVA_UART5_BASE | 0x40011000 | UART5 |
UART6_BASE | TIVA_UART6_BASE | 0x40012000 | UART6 |
UART7_BASE | TIVA_UART7_BASE | 0x40013000 | UART7 |
I2C0_BASE | TIVA_I2C0_BASE | 0x40020000 | I2C0 |
I2C1_BASE | TIVA_I2C1_BASE | 0x40021000 | I2C1 |
I2C2_BASE | TIVA_I2C2_BASE | 0x40022000 | I2C2 |
I2C3_BASE | TIVA_I2C3_BASE | 0x40023000 | I2C3 |
GPIO_PORTE_BASE | TIVA_GPIOE_BASE | 0x40024000 | GPIO Port E |
GPIO_PORTF_BASE | TIVA_GPIOF_BASE | 0x40025000 | GPIO Port F |
GPIO_PORTG_BASE | TIVA_GPIOG_BASE | 0x40026000 | GPIO Port G |
GPIO_PORTH_BASE | TIVA_GPIOH_BASE | 0x40027000 | GPIO Port H |
PWM0_BASE | TIVA_PWM0_BASE | 0x40028000 | Pulse Width Modulator (PWM) |
PWM1_BASE | TIVA_PWM1_BASE | 0x40029000 | Pulse Width Modulator (PWM) |
QEI0_BASE | TIVA_QEI0_BASE | 0x4002c000 | QEI0 |
QEI1_BASE | TIVA_QEI1_BASE | 0x4002d000 | QEI1 |
TIMER0_BASE | TIVA_TIMER0_BASE | 0x40030000 | Timer0 |
TIMER1_BASE | TIVA_TIMER1_BASE | 0x40031000 | Timer1 |
TIMER2_BASE | TIVA_TIMER2_BASE | 0x40032000 | Timer2 |
TIMER3_BASE | TIVA_TIMER3_BASE | 0x40033000 | Timer3 |
TIMER4_BASE | TIVA_TIMER4_BASE | 0x40034000 | Timer4 |
TIMER5_BASE | TIVA_TIMER5_BASE | 0x40035000 | Timer5 |
WTIMER0_BASE | TIVA_WTIMER0_BASE | 0x40036000 | Wide Timer0 |
WTIMER1_BASE | TIVA_WTIMER1_BASE | 0x40037000 | Wide Timer1 |
ADC0_BASE | TIVA_ADC0_BASE | 0x40038000 | ADC0 |
ADC1_BASE | TIVA_ADC1_BASE | 0x40039000 | ADC1 |
COMP_BASE | TIVA_CMP_BASE | 0x4003c000 | Analog comparators |
GPIO_PORTJ_BASE | TIVA_GPIOJ_BASE | 0x4003d000 | GPIO Port J |
CAN0_BASE | TIVA_CAN0_BASE | 0x40040000 | CAN0 |
CAN1_BASE | TIVA_CAN1_BASE | 0x40041000 | CAN1 |
WTIMER2_BASE | TIVA_WTIMER2_BASE | 0x4004c000 | Wide Timer2 |
WTIMER3_BASE | TIVA_WTIMER3_BASE | 0x4004d000 | Wide Timer3 |
WTIMER4_BASE | TIVA_WTIMER4_BASE | 0x4004e000 | Wide Timer4 |
WTIMER5_BASE | TIVA_WTIMER5_BASE | 0x4004f000 | Wide Timer5 |
USB0_BASE | TIVA_USB_BASE | 0x40050000 | USB 0 Controller |
GPIO_PORTA_AHB_BASE | TIVA_GPIOAAHB_BASE | 0x40058000 | GPIO Port A (high speed) |
GPIO_PORTB_AHB_BASE | TIVA_GPIOBAHB_BASE | 0x40059000 | GPIO Port B (high speed) |
GPIO_PORTC_AHB_BASE | TIVA_GPIOCAHB_BASE | 0x4005a000 | GPIO Port C (high speed) |
GPIO_PORTD_AHB_BASE | TIVA_GPIODAHB_BASE | 0x4005b000 | GPIO Port D (high speed) |
GPIO_PORTE_AHB_BASE | TIVA_GPIOEAHB_BASE | 0x4005c000 | GPIO Port E (high speed) |
GPIO_PORTF_AHB_BASE | TIVA_GPIOFAHB_BASE | 0x4005d000 | GPIO Port F (high speed) |
GPIO_PORTG_AHB_BASE | TIVA_GPIOGAHB_BASE | 0x4005e000 | GPIO Port G (high speed) |
GPIO_PORTH_AHB_BASE | TIVA_GPIOHAHB_BASE | 0x4005f000 | GPIO Port H (high speed) |
GPIO_PORTJ_AHB_BASE | TIVA_GPIOJAHB_BASE | 0x40060000 | GPIO Port J (high speed) |
GPIO_PORTK_BASE | TIVA_GPIOKAHB_BASE | 0x40061000 | GPIO Port K |
GPIO_PORTL_BASE | TIVA_GPIOLAHB_BASE | 0x40062000 | GPIO Port L |
GPIO_PORTM_BASE | TIVA_GPIOMAHB_BASE | 0x40063000 | GPIO Port M |
GPIO_PORTN_BASE | TIVA_GPIONAHB_BASE | 0x40064000 | GPIO Port N |
GPIO_PORTP_BASE | TIVA_GPIOPAHB_BASE | 0x40065000 | GPIO Port P |
GPIO_PORTQ_BASE | TIVA_GPIOQAHB_BASE | 0x40066000 | GPIO Port Q |
GPIO_PORTR_BASE | TIVA_GPIORAHB_BASE | 0x40067000 | General-Purpose Input/Outputs (GPIOs) |
GPIO_PORTS_BASE | TIVA_GPIOSAHB_BASE | 0x40068000 | General-Purpose Input/Outputs (GPIOs) |
GPIO_PORTT_BASE | TIVA_GPIOTAHB_BASE | 0x40069000 | General-Purpose Input/Outputs (GPIOs) |
EEPROM_BASE | TIVA_EEPROM_BASE | 0x400af000 | EEPROM memory |
ONEWIRE0_BASE | TIVA_1WIRE_BASE | 0x400b6000 | 1-Wire Master Module |
I2C8_BASE | TIVA_I2C8_BASE | 0x400b8000 | I2C8 |
I2C9_BASE | TIVA_I2C9_BASE | 0x400b9000 | I2C9 |
I2C4_BASE | TIVA_I2C4_BASE | 0x400c0000 | I2C4 |
I2C5_BASE | TIVA_I2C5_BASE | 0x400c1000 | I2C5 |
I2C6_BASE | TIVA_I2C6_BASE | 0x400c2000 | I2C6 |
I2C7_BASE | TIVA_I2C7_BASE | 0x400c3000 | I2C7 |
EPI0_BASE | TIVA_EPI0_BASE | 0x400d0000 | EPI0 |
TIMER6_BASE | TIVA_TIMER6_BASE | 0x400e0000 | General-Purpose Timers |
TIMER7_BASE | TIVA_TIMER7_BASE | 0x400e1000 | General-Purpose Timers |
EMAC0_BASE | TIVA_ETHCON_BASE | 0x400ec000 | Ethernet Controller |
SYSEXC_BASE | TIVA_SYSEXC_BASE | 0x400f9000 | System Exception Module |
HIB_BASE | TIVA_HIBERNATE_BASE | 0x400fc000 | Hibernation Module |
FLASH_CTRL_BASE | TIVA_FLASHCON_BASE | 0x400fd000 | FLASH Controller |
SYSCTL_BASE | TIVA_SYSCON_BASE | 0x400fe000 | System Control |
UDMA_BASE | TIVA_UDMA_BASE | 0x400ff000 | uDMA Controller |
CCM0_BASE | TIVA_CCM_BASE | 0x44030000 | Cyclical Redundancy Check (CRC) |
SHAMD5_BASE | TIVA_SHAMD5_BASE | 0x44034000 | SHA/MD5 Accelerator |
AES_BASE | TIVA_AES_BASE | 0x44036000 | Advance Encryption Hardware-Accelerator (AES) |
DES_BASE | TIVA_DES_BASE | 0x44038000 | Data Encryption Standard Accelerator (DES) |
LCD0_BASE | TIVA_LCD_BASE | 0x44050000 | LCD Controller |
??? | TIVA_EPHY_BASE | 0x44054000 | |
ITM_BASE | ??? | 0xe0000000 | Instrumentation Trace Macrocell |
DWT_BASE | ??? | 0xe0001000 | Data Watchpoint and Trace |
FPB_BASE | ??? | 0xe0002000 | FLASH Patch and Breakpoint |
NVIC_BASE | ??? | 0xe000e000 | Nested Vectored Interrupt Ctrl |
TPIU_BASE | ??? | 0xe0040000 | Trace Port Interface Unit |
GPIO
TivaWare | NuttX Memory Map | NuttX tiva_configgpio() |
---|---|---|
GPIO_PORTA_BASE | TIVA_GPIOA_BASE | GPIO_PORTA |
GPIO_PORTB_BASE | TIVA_GPIOB_BASE | GPIO_PORTB |
GPIO_PORTC_BASE | TIVA_GPIOC_BASE | GPIO_PORTC |
GPIO_PORTD_BASE | TIVA_GPIOD_BASE | GPIO_PORTD |
GPIO_PORTE_BASE | TIVA_GPIOE_BASE | GPIO_PORTE |
GPIO_PORTF_BASE | TIVA_GPIOF_BASE | GPIO_PORTF |
GPIO_PORTG_BASE | TIVA_GPIOG_BASE | GPIO_PORTG |
GPIO_PORTH_BASE | TIVA_GPIOH_BASE | GPIO_PORTH |
GPIO_PORTJ_BASE | TIVA_GPIOJ_BASE | GPIO_PORTJ |
GPIO_PORTK_BASE | TIVA_GPIOK_BASE | GPIO_PORTK |
GPIO_PORTL_BASE | TIVA_GPIOL_BASE | GPIO_PORTL |
GPIO_PORTM_BASE | TIVA_GPIOM_BASE | GPIO_PORTM |
GPIO_PORTN_BASE | TIVA_GPION_BASE | GPIO_PORTN |
GPIO_PORTP_BASE | TIVA_GPIOP_BASE | GPIO_PORTP |
GPIO_PORTQ_BASE | TIVA_GPIOQ_BASE | GPIO_PORTQ |
GPIO_PORTR_BASE | TIVA_GPIOR_BASE | GPIO_PORTR |
GPIO_PORTS_BASE | TIVA_GPIOS_BASE | GPIO_PORTS |
GPIO_PORTT_BASE | TIVA_GPIOT_BASE | GPIO_PORTT |
TivaWare | NuttX |
---|---|
GPIO_PIN_0 | (1 << (GPIO_PIN_0 >> GPIO_PIN_SHIFT)) |
GPIO_PIN_1 | (1 << (GPIO_PIN_1 >> GPIO_PIN_SHIFT)) |
GPIO_PIN_2 | (1 << (GPIO_PIN_2 >> GPIO_PIN_SHIFT)) |
GPIO_PIN_3 | (1 << (GPIO_PIN_3 >> GPIO_PIN_SHIFT)) |
GPIO_PIN_4 | (1 << (GPIO_PIN_4 >> GPIO_PIN_SHIFT)) |
GPIO_PIN_5 | (1 << (GPIO_PIN_5 >> GPIO_PIN_SHIFT)) |
GPIO_PIN_6 | (1 << (GPIO_PIN_6 >> GPIO_PIN_SHIFT)) |
GPIO_PIN_7 | (1 << (GPIO_PIN_7 >> GPIO_PIN_SHIFT)) |
TivaWare | NuttX | Description |
---|---|---|
GPIO_O_DATA | TIVA_GPIO_DATA_OFFSET | GPIO Data |
GPIO_O_DIR | TIVA_GPIO_DIR_OFFSET | GPIO Direction |
GPIO_O_IS | TIVA_GPIO_IS_OFFSET | GPIO Interrupt Sense |
GPIO_O_IBE | TIVA_GPIO_IBE_OFFSET | GPIO Interrupt Both Edges |
GPIO_O_IEV | TIVA_GPIO_IEV_OFFSET | GPIO Interrupt Event |
GPIO_O_IM | TIVA_GPIO_IM_OFFSET | GPIO Interrupt Mask |
GPIO_O_RIS | TIVA_GPIO_RIS_OFFSET | GPIO Raw Interrupt Status |
GPIO_O_MIS | TIVA_GPIO_MIS_OFFSET | GPIO Masked Interrupt Status |
GPIO_O_ICR | TIVA_GPIO_ICR_OFFSET | GPIO Interrupt Clear |
GPIO_O_AFSEL | TIVA_GPIO_AFSEL_OFFSET | GPIO Alternate Function |
GPIO_O_DR2R | TIVA_GPIO_DR2R_OFFSET | Select GPIO 2-mA Drive Select |
GPIO_O_DR4R | TIVA_GPIO_DR4R_OFFSET | GPIO 4-mA Drive Select |
GPIO_O_DR8R | TIVA_GPIO_DR8R_OFFSET | GPIO 8-mA Drive Select |
GPIO_O_ODR | TIVA_GPIO_ODR_OFFSET | GPIO Open Drain Select |
GPIO_O_PUR | TIVA_GPIO_PUR_OFFSET | GPIO Pull-Up Select |
GPIO_O_PDR | TIVA_GPIO_PDR_OFFSET | GPIO Pull-Down Select |
GPIO_O_SLR | TIVA_GPIO_SLR_OFFSET | GPIO Slew Rate Control Select |
GPIO_O_DEN | TIVA_GPIO_DEN_OFFSET | GPIO Digital Enable |
GPIO_O_LOCK | TIVA_GPIO_LOCK_OFFSET | GPIO Lock |
GPIO_O_CR | TIVA_GPIO_CR_OFFSET | GPIO Commit |
GPIO_O_AMSEL | TIVA_GPIO_AMSEL_OFFSET | GPIO Analog Mode Select |
GPIO_O_PCTL | TIVA_GPIO_PCTL_OFFSET | GPIO Port Control |
GPIO_O_ADCCTL | TIVA_GPIO_ADCCTL_OFFSET | GPIO ADC Control |
GPIO_O_DMACTL | TIVA_GPIO_DMACTL_OFFSET | GPIO DMA Control |
GPIO_O_SI | TIVA_GPIO_SI_OFFSET | GPIO Select Interrupt |
GPIO_O_DR12R | TIVA_GPIO_DR12R_OFFSET | GPIO 12-mA Drive Select |
GPIO_O_WAKEPEN | TIVA_GPIO_WAKEPEN_OFFSET | GPIO Wake Pin Enable |
GPIO_O_WAKELVL | TIVA_GPIO_WAKELVL_OFFSET | GPIO Wake Level |
GPIO_O_WAKESTAT | TIVA_GPIO_WAKESTAT_OFFSET | GPIO Wake Status |
GPIO_O_PP | TIVA_GPIO_PP_OFFSET | GPIO Peripheral Property |
GPIO_O_PC | TIVA_GPIO_PC_OFFSET | GPIO Peripheral Configuration |
??? | TIVA_GPIO_PERIPHID4_OFFSET | GPIO Peripheral Identification 4 |
??? | TIVA_GPIO_PERIPHID5_OFFSET | GPIO Peripheral Identification 5 |
??? | TIVA_GPIO_PERIPHID6_OFFSET | GPIO Peripheral Identification 6 |
??? | TIVA_GPIO_PERIPHID7_OFFSET | GPIO Peripheral Identification 7 |
??? | TIVA_GPIO_PERIPHID0_OFFSET | GPIO Peripheral Identification 0 |
??? | TIVA_GPIO_PERIPHID1_OFFSET | GPIO Peripheral Identification 1 |
??? | TIVA_GPIO_PERIPHID2_OFFSET | GPIO Peripheral Identification 2 |
??? | TIVA_GPIO_PERIPHID3_OFFSET | GPIO Peripheral Identification 3 |
??? | TIVA_GPIO_PCELLID0_OFFSET | GPIO PrimeCell Identification 0 |
??? | TIVA_GPIO_PCELLID1_OFFSET | GPIO PrimeCell Identification 1 |
??? | TIVA_GPIO_PCELLID2_OFFSET | GPIO PrimeCell Identification 2 |
??? | TIVA_GPIO_PCELLID3_OFFSET | GPIO PrimeCell Identification 3 |
TivaWare | NuttX | Description |
---|---|---|
GPIO_PIN_TYPE_STD | GPIO_PADTYPE_STD | Push-pull |
GPIO_PIN_TYPE_STD_WPU | GPIO_PADTYPE_STDWPU | Push-pull with weak pull-up |
GPIO_PIN_TYPE_STD_WPD | GPIO_PADTYPE_STDWPD | Push-pull with weak pull-down |
GPIO_PIN_TYPE_OD | GPIO_PADTYPE_OD | Open-drain |
??? | GPIO_PADTYPE_ODWPU | Open-drain with weak pull-up |
??? | GPIO_PADTYPE_ODWPD | Open-drain with weak pull-down |
GPIO_PIN_TYPE_ANALOG | GPIO_PADTYPE_ANALOG | Analog comparator |
GPIO_PIN_TYPE_WAKE_HIGH | ??? | Hibernate wake, high |
GPIO_PIN_TYPE_WAKE_LOW | ??? | Hibernate wake, low |
TivaWare | NuttX | Description |
---|---|---|
GPIO_FALLING_EDGE | GPIO_INT_FALLINGEDGE | Interrupt on falling edge |
GPIO_RISING_EDGE | GPIO_INT_RISINGEDGE | Interrupt on rising edge |
GPIO_BOTH_EDGES | GPIO_INT_BOTHEDGES | Interrupt on both edges |
GPIO_LOW_LEVEL | GPIO_INT_LOWLEVEL | Interrupt on low level |
GPIO_HIGH_LEVEL | GPIO_INT_HIGHLEVEL | Interrupt on high level |
GPIO_DISCRETE_INT | ??? | Interrupt for individual pins |
TivaWare | NuttX |
---|---|
GPIODirModeSet(GPIO_DIR_MODE_IN) | tiva_configgpio(GPIO_FUNC_INPUT | other settings) |
GPIOPadConfigSet(GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD) | tiva_configgpio(GPIO_STRENGTH_2MA | GPIO_PADTYPE_STD | other settings) See: tiva_gpiopadstrength(), tiva_gpiopadtype() |
GPIOIntEnable() | tiva_gpioirqenable() See: arch/arm/src/tiva/common/lmxx_tm4c_gpioirq.c |
GPIOIntDisable() | tiva_gpioirqdisable() See: arch/arm/src/tiva/common/lmxx_tm4c_gpioirq.c |
GPIOIntClear() | tiva_gpioirqclear() See: arch/arm/src/tiva/common/lmxx_tm4c_gpioirq.c |
Interrupts
TivaWare | NuttX | IntNum | Description |
---|---|---|---|
INT_GPIOA | TIVA_IRQ_GPIOA | 16 | GPIO Port A |
INT_GPIOB | TIVA_IRQ_GPIOB | 17 | GPIO Port B |
INT_GPIOC | TIVA_IRQ_GPIOC | 18 | GPIO Port C |
INT_GPIOD | TIVA_IRQ_GPIOD | 19 | GPIO Port D |
INT_GPIOE | TIVA_IRQ_GPIOE | 20 | GPIO Port E |
INT_UART0 | TIVA_IRQ_UART0 | 21 | UART0 |
INT_UART1 | TIVA_IRQ_UART1 | 22 | UART1 |
INT_SSI0 | TIVA_IRQ_SSI0 | 23 | SSI0 |
INT_I2C0 | TIVA_IRQ_I2C0 | 24 | I2C0 |
INT_PWM0_FAULT | TIVA_IRQ_PWM0_FAULT | 25 | PWM Fault |
INT_PWM0_0 | TIVA_IRQ_PWM0_GEN0 | 26 | PWM Generator 0 |
INT_PWM0_1 | TIVA_IRQ_PWM0_GEN1 | 27 | PWM Generator 1 |
INT_PWM0_2 | TIVA_IRQ_PWM0_GEN2 | 28 | PWM Generator 2 |
INT_QEI0 | TIVA_IRQ_QEI0 | 29 | QEI0 |
INT_ADC0SS0 | TIVA_IRQ_ADC0 | 30 | ADC0 Sequence 0 |
INT_ADC0SS1 | TIVA_IRQ_ADC1 | 31 | ADC0 Sequence 1 |
INT_ADC0SS2 | TIVA_IRQ_ADC2 | 32 | ADC0 Sequence 2 |
INT_ADC0SS3 | TIVA_IRQ_ADC3 | 33 | ADC0 Sequence 3 |
INT_WATCHDOG | TIVA_IRQ_WDOG | 34 | Watchdog Timers 0 and 1 |
INT_TIMER0A | TIVA_IRQ_TIMER0A | 35 | 16/32-Bit Timer 0A |
INT_TIMER0B | TIVA_IRQ_TIMER0B | 36 | 16/32-Bit Timer 0B |
INT_TIMER1A | TIVA_IRQ_TIMER1A | 37 | 16/32-Bit Timer 1A |
INT_TIMER1B | TIVA_IRQ_TIMER1B | 38 | 16/32-Bit Timer 1B |
INT_TIMER2A | TIVA_IRQ_TIMER2A | 39 | 16/32-Bit Timer 2A |
INT_TIMER2B | TIVA_IRQ_TIMER2B | 40 | 16/32-Bit Timer 2B |
INT_COMP0 | TIVA_IRQ_COMPARE0 | 41 | Analog Comparator 0 |
INT_COMP1 | TIVA_IRQ_COMPARE1 | 42 | Analog Comparator 1 |
INT_COMP2 | TIVA_IRQ_COMPARE2 | 43 | Analog Comparator 2 |
INT_SYSCTL | TIVA_IRQ_SYSCON | 44 | System Control |
INT_FLASH | TIVA_IRQ_FLASHCON | 45 | Flash Memory Control |
INT_GPIOF | TIVA_IRQ_GPIOF | 46 | GPIO Port F |
INT_GPIOG | TIVA_IRQ_GPIOG | 47 | GPIO Port G |
INT_GPIOH | TIVA_IRQ_GPIOH | 48 | GPIO Port H |
INT_UART2 | TIVA_IRQ_UART2 | 49 | UART2 |
INT_SSI1 | TIVA_IRQ_SSI1 | 50 | SSI1 |
INT_TIMER3A | TIVA_IRQ_TIMER3A | 51 | 16/32-Bit Timer 3A |
INT_TIMER3B | TIVA_IRQ_TIMER3B | 52 | 16/32-Bit Timer 3B |
INT_I2C1 | TIVA_IRQ_I2C1 | 53 | I2C1 |
INT_CAN0 | TIVA_IRQ_CAN0 | 54 | CAN 0 |
INT_CAN1 | TIVA_IRQ_CAN1 | 55 | CAN1 |
INT_EMAC0 | TIVA_IRQ_ETHCON | 56 | Ethernet MAC |
INT_HIBERNATE | TIVA_IRQ_HIBERNATE | 57 | HIB |
INT_USB0 | TIVA_IRQ_USB | 58 | USB MAC |
INT_PWM0_3 | TIVA_IRQ_PWM0_GEN3 | 59 | PWM Generator 3 |
INT_UDMA | TIVA_IRQ_UDMASOFT | 60 | uDMA 0 Software |
INT_UDMAERR | TIVA_IRQ_UDMAERROR | 61 | uDMA 0 Error |
INT_ADC1SS0 | TIVA_IRQ_ADC1_0 | 62 | ADC1 Sequence 0 |
INT_ADC1SS1 | TIVA_IRQ_ADC1_1 | 63 | ADC1 Sequence 1 |
INT_ADC1SS2 | TIVA_IRQ_ADC1_2 | 64 | ADC1 Sequence 2 |
INT_ADC1SS3 | TIVA_IRQ_ADC1_3 | 65 | ADC1 Sequence 3 |
INT_EPI0 | TIVA_IRQ_EPI0 | 66 | EPI 0 |
INT_GPIOJ | TIVA_IRQ_GPIOJ | 67 | GPIO Port J |
INT_GPIOK | TIVA_IRQ_GPIOK | 68 | GPIO Port K |
INT_GPIOL | TIVA_IRQ_GPIOL | 69 | GPIO Port L |
INT_SSI2 | TIVA_IRQ_SSI2 | 70 | SSI 2 |
INT_SSI3 | TIVA_IRQ_SSI3 | 71 | SSI 3 |
INT_UART3 | TIVA_IRQ_UART3 | 72 | UART 3 |
INT_UART4 | TIVA_IRQ_UART4 | 73 | UART 4 |
INT_UART5 | TIVA_IRQ_UART5 | 74 | UART 5 |
INT_UART6 | TIVA_IRQ_UART6 | 75 | UART 6 |
INT_UART7 | TIVA_IRQ_UART7 | 76 | UART 7 |
INT_I2C2 | TIVA_IRQ_I2C2 | 77 | I2C 2 |
INT_I2C3 | TIVA_IRQ_I2C3 | 78 | I2C 3 |
INT_TIMER4A | TIVA_IRQ_TIMER4A | 79 | Timer 4A |
INT_TIMER4B | TIVA_IRQ_TIMER4B | 80 | Timer 4B |
INT_TIMER5A | TIVA_IRQ_TIMER5A | 81 | Timer 5A |
INT_TIMER5B | TIVA_IRQ_TIMER5B | 82 | Timer 5B |
INT_SYSEXC | TIVA_IRQ_FLOAT | 83 | Floating-Point Exception (imprecise) |
??? | TIVA_RESERVED_84 | ||
??? | TIVA_RESERVED_85 | ||
INT_I2C4 | TIVA_IRQ_I2C4 | 86 | I2C 4 |
INT_I2C5 | TIVA_IRQ_I2C5 | 87 | I2C 5 |
INT_GPIOM | TIVA_IRQ_GPIOM | 88 | GPIO Port M |
INT_GPION | TIVA_IRQ_GPION | 89 | GPIO Port N |
??? | TIVA_RESERVED_90 | ||
INT_TAMPER0 | TIVA_IRQ_TAMPER | 91 | Tamper |
INT_GPIOP0 | TIVA_IRQ_GPIOP | 92 | GPIO Port P (Summary or P0) |
INT_GPIOP1 | TIVA_IRQ_GPIOP1 | 93 | GPIO Port P1 |
INT_GPIOP2 | TIVA_IRQ_GPIOP2 | 94 | GPIO Port P2 |
INT_GPIOP3 | TIVA_IRQ_GPIOP3 | 95 | GPIO Port P3 |
INT_GPIOP4 | TIVA_IRQ_GPIOP4 | 96 | GPIO Port P4 |
INT_GPIOP5 | TIVA_IRQ_GPIOP5 | 97 | GPIO Port P5 |
INT_GPIOP6 | TIVA_IRQ_GPIOP6 | 98 | GPIO Port P6 |
INT_GPIOP7 | TIVA_IRQ_GPIOP7 | 99 | GPIO Port P7 |
INT_GPIOQ0 | TIVA_IRQ_GPIOQ | 100 | GPIO Port Q (Summary or Q0) |
INT_GPIOQ1 | TIVA_IRQ_GPIOQ1 | 101 | GPIO Port Q1 |
INT_GPIOQ2 | TIVA_IRQ_GPIOQ2 | 102 | GPIO Port Q2 |
INT_GPIOQ3 | TIVA_IRQ_GPIOQ3 | 103 | GPIO Port Q3 |
INT_GPIOQ4 | TIVA_IRQ_GPIOQ4 | 104 | GPIO Port Q4 |
INT_GPIOQ5 | TIVA_IRQ_GPIOQ5 | 105 | GPIO Port Q5 |
INT_GPIOQ6 | TIVA_IRQ_GPIOQ6 | 106 | GPIO Port Q6 |
INT_GPIOQ7 | TIVA_IRQ_GPIOQ7 | 107 | GPIO Port Q7 |
??? | TIVA_RESERVED_108 | ||
??? | TIVA_RESERVED_109 | ||
INT_SHA0 | TIVA_RESERVED_110 | 110 | SHA/MD5 |
INT_AES0 | TIVA_RESERVED_111 | 111 | AES |
INT_DES0 | TIVA_RESERVED_112 | 112 | DES |
??? | TIVA_RESERVED_113 | ||
INT_TIMER6A | TIVA_IRQ_TIMER6A | 114 | 16/32-Bit Timer 6A |
INT_TIMER6B | TIVA_IRQ_TIMER6B | 115 | 16/32-Bit Timer 6B |
INT_TIMER7A | TIVA_IRQ_TIMER7A | 116 | 16/32-Bit Timer 7A |
INT_TIMER7B | TIVA_IRQ_TIMER7B | 117 | 16/32-Bit Timer 7B |
INT_I2C6 | TIVA_IRQ_I2C6 | 118 | I2C 6 |
INT_I2C7 | TIVA_IRQ_I2C7 | 119 | I2C 7 |
??? | TIVA_RESERVED_120 | ||
??? | TIVA_RESERVED_121 | ||
??? | TIVA_RESERVED_122 | ||
??? | TIVA_RESERVED_123 | ||
??? | TIVA_RESERVED_124 | ||
INT_I2C8 | TIVA_IRQ_I2C8 | 125 | I2C 8 |
INT_I2C9 | TIVA_IRQ_I2C9 | 126 | I2C 9 |
??? | TIVA_RESERVED_127 | ||
??? | TIVA_RESERVED_128 | ||
??? | TIVA_RESERVED_129 |
QEI
QEI Register Offsets
TivaWare | NuttX | Description |
---|---|---|
QEI_O_CTL | TIVA_QEI_CTL_OFFSET | QEI Control |
QEI_O_STAT | TIVA_QEI_STAT_OFFSET | QEI Status |
QEI_O_POS | TIVA_QEI_POS_OFFSET | QEI Position |
QEI_O_MAXPOS | TIVA_QEI_MAXPOS_OFFSET | QEI Maximum Position |
QEI_O_LOAD | TIVA_QEI_LOAD_OFFSET | QEI Timer Load |
QEI_O_TIME | TIVA_QEI_TIME_OFFSET | QEI Timer |
QEI_O_COUNT | TIVA_QEI_COUNT_OFFSET | QEI Velocity Counter |
QEI_O_SPEED | TIVA_QEI_SPEED_OFFSET | QEI Velocity |
QEI_O_INTEN | TIVA_QEI_INTEN_OFFSET | QEI Interrupt Enable |
QEI_O_RIS | TIVA_QEI_RIS_OFFSET | QEI Raw Interrupt Status |
QEI_O_ISC | TIVA_QEI_ISC_OFFSET | QEI Interrupt Status and Clear |
UART
UART register offsets
TivaWare | NuttX | Description |
---|---|---|
UART_O_DR | TIVA_UART_DR_OFFSET | UART Data |
UART_O_RSR | TIVA_UART_RSR_OFFSET | UART Receive Status |
UART_O_ECR | TIVA_UART_ECR_OFFSET | UART Error Clear |
UART_O_FR | TIVA_UART_FR_OFFSET | UART Flag |
UART_O_ILPR | TIVA_UART_ILPR_OFFSET | UART IrDA Low-Power Register |
UART_O_IBRD | TIVA_UART_IBRD_OFFSET | UART Integer Baud-Rate Divisor |
UART_O_FBRD | TIVA_UART_FBRD_OFFSET | UART Fractional Baud-Rate Divisor |
UART_O_LCRH | TIVA_UART_LCRH_OFFSET | UART Line Control |
UART_O_CTL | TIVA_UART_CTL_OFFSET | UART Control |
UART_O_IFLS | TIVA_UART_IFLS_OFFSET | UART Interrupt FIFO Level Select |
UART_O_IM | TIVA_UART_IM_OFFSET | UART Interrupt Mask |
UART_O_RIS | TIVA_UART_RIS_OFFSET | UART Raw Interrupt Status |
UART_O_MIS | TIVA_UART_MIS_OFFSET | UART Masked Interrupt Status |
UART_O_ICR | TIVA_UART_ICR_OFFSET | UART Interrupt Clear |
UART_O_DMACTL | TIVA_UART_DMACTL_OFFSET | UART DMA Control |
UART_O_9BITADDR | TIVA_UART_9BITADDR_OFFSET | UART 9-Bit Self Address |
UART_O_9BITAMASK | TIVA_UART_9BITAMASK_OFFSET | UART 9-Bit Self Address Mask |
UART_O_PP | TIVA_UART_PP_OFFSET | UART Peripheral Properties |
UART_O_CC | TIVA_UART_CC_OFFSET | UART Clock Configuration |
??? | TIVA_UART_PERIPHID4_OFFSET | UART Peripheral Identification 4 |
??? | TIVA_UART_PERIPHID5_OFFSET | UART Peripheral Identification 5 |
??? | TIVA_UART_PERIPHID6_OFFSET | UART Peripheral Identification 6 |
??? | TIVA_UART_PERIPHID7_OFFSET | UART Peripheral Identification 7 |
??? | TIVA_UART_PERIPHID0_OFFSET | UART Peripheral Identification 0 |
??? | TIVA_UART_PERIPHID1_OFFSET | UART Peripheral Identification 1 |
??? | TIVA_UART_PERIPHID2_OFFSET | UART Peripheral Identification 2 |
??? | TIVA_UART_PERIPHID3_OFFSET | UART Peripheral Identification 3 |
??? | TIVA_UART_PCELLID0_OFFSET | UART PrimeCell Identification 0 |
??? | TIVA_UART_PCELLID1_OFFSET | UART PrimeCell Identification 1 |
??? | TIVA_UART_PCELLID2_OFFSET | UART PrimeCell Identification 2 |
??? | TIVA_UART_PCELLID3_OFFSET | UART PrimeCell Identification 3 |
UART Interrupt Mask (IM) Register
These values can be passed to UARTIntEnable(), UARTIntDisable(), and UARTIntClear() as the ui32IntFlags parameter, and are returned from UARTIntStatus():
See arch/arm/src/tiva/hardware/tm4c/tm4c_uart.h.
TivaWare | NuttX | Bit | TM4C123 | TM4C129 | Description |
---|---|---|---|---|---|
UART_INT_DMATX | UART_IM_DMATXIM | 17 | Yes | Transmit DMA Interrupt Mask | |
UART_INT_DMARX | UART_IM_DMARXIM | 16 | Yes | Receive DMA Interrupt Mask | |
UART_INT_9BIT | UART_IM_9BITIM | 12 | Yes | Yes | 9-Bit Mode Interrupt Mask |
??? | UART_IM_EOTIM | 11 | Yes | End of Transmission Interrupt Mask | |
UART_INT_OE | UART_IM_OEIM | 10 | Yes | Yes | UART Overrun Error Interrupt Mask |
UART_INT_BE | UART_IM_BEIM | 9 | Yes | Yes | UART Break Error Interrupt Mask |
UART_INT_PE | UART_IM_PEIM | 8 | Yes | Yes | UART Parity Error Interrupt Mask |
UART_INT_FE | UART_IM_FEIM | 7 | Yes | Yes | UART Framing Error Interrupt Mask |
UART_INT_RT | UART_IM_RTIM | 6 | Yes | Yes | UART Receive Time-Out Interrupt Mask |
UART_INT_TX | UART_IM_TXIM | 5 | Yes | Yes | UART Transmit Interrupt Mask |
UART_INT_RX | UART_IM_RXIM | 4 | Yes | Yes | UART Receive Interrupt Mask |
UART_INT_DSR | UART_IM_DSRIM | 3 | Yes | UART Data Set Ready Modem Interrupt Mask | |
UART_INT_DCD | UART_IM_DCDIM | 2 | Yes | UART Data Carrier Detect Modem Interrupt Mask | |
UART_INT_CTS | UART_IM_CTSIM | 1 | Yes | Yes | UART Clear to Send Modem Interrupt Mask |
UART_INT_RI | UART_IM_RIIM | 0 | Yes | Yes | UART Ring Indicator Modem Interrupt Mask |
UART Interrupt FIFO Level Select (IFLS)
Values that can be passed to UARTFIFOLevelSet() as the ui32TxLevel parameter and returned by UARTFIFOLevelGet() in the pui32TxLevel:
TivaWare | NuttX | Description |
---|---|---|
UART_FIFO_TX1_8 | UART_IFLS_TXIFLSEL_18th | Transmit interrupt at 1/8 Full |
UART_FIFO_TX2_8 | UART_IFLS_TXIFLSEL_14th | Transmit interrupt at 1/4 Full |
UART_FIFO_TX4_8 | UART_IFLS_TXIFLSEL_half | Transmit interrupt at 1/2 Full |
UART_FIFO_TX6_8 | UART_IFLS_TXIFLSEL_34th | Transmit interrupt at 3/4 Full |
UART_FIFO_TX7_8 | UART_IFLS_TXIFLSEL_78th | Transmit interrupt at 7/8 Full |
Values that can be passed to UARTFIFOLevelSet() as the ui32RxLevel parameter and returned by UARTFIFOLevelGet() in the pui32RxLevel:
TivaWare | NuttX | Description |
---|---|---|
UART_FIFO_RX1_8 | UART_IFLS_RXIFLSEL_18th | Receive interrupt at 1/8 Full |
UART_FIFO_RX2_8 | UART_IFLS_RXIFLSEL_14th | Receive interrupt at 1/4 Full |
UART_FIFO_RX4_8 | UART_IFLS_RXIFLSEL_half | Receive interrupt at 1/2 Full |
UART_FIFO_RX6_8 | UART_IFLS_RXIFLSEL_34th | Receive interrupt at 3/4 Full |
UART_FIFO_RX7_8 | UART_IFLS_RXIFLSEL_78th | Receive interrupt at 7/8 Full |
UART DMA Control (DMACTL) Register
Values that can be passed to UARTDMAEnable() and UARTDMADisable():
TivaWare | NuttX | Description |
---|---|---|
UART_DMA_RX | UART_DMACTL_RXDMAE | Receive DMA Enable |
UART_DMA_TX | UART_DMACTL_TXDMAE | Transmit DMA Enable |
UART_DMA_ERR_RXSTOP | UART_DMACTL_DMAERR | Stop DMA receive if UART error |
September 24-25, 2022: The NuttX International Workshop
This section last updated September 25th, 2022.
As in the previous two years, the 2022 NuttX International Workshop event was held online. A recording of the entire two-day event and all its presentations can be seen on YouTube by following the links below.
Note: The primary place to communicate with the NuttX developer and user community is at its mailing lists.
October 26, 2022: NuttX community discussing graduation from the Incubator
Back in December 2019, I wrote that NuttX, which was until then driven almost exclusively by one person, Gregory Nutt, became accepted into the Apache Incubator at the Apache Software Foundation (ASF).
This move was motivated by a desire to shift from a Benevolent Dictator For Life (BDFL) model to a community-driven model.
The ASF has hundreds of different software projects driven by equally many different communities. Some of these are termed Top-Level Projects (TLP) while others are subprojects of a TLP.
The way projects become part of the ASF is that they first must be accepted as a "podling" within the Apache Incubator. During the "incubation" process, the project organizes (or re-organizes), builds and expands its community, migrates its source code licenses to the Apache 2.0 License, and learns "The Apache Way" which is how project governance works at the ASF. When the community feels it is ready, it votes to graduate, then has the Incubator vote to recommend its graduation to the ASF board of directors, and if these votes pass, a resolution is brought before the board for an approval vote and formation of the Top Level Project.
All of the above is related to governance and may seem unrelated to the technical aspects of using NuttX as your embedded RTOS, but there is a significant benefit to graduating and becoming a Top-Level Project as opposed to staying in the Incubator, namely more frequent releases. Back in NuttX's BDFL days, Gregory Nutt released a new version of NuttX every other month like clockwork. While in the Incubator, the frequency of releases slowed down from six releases per year to about three, due in part to the requirement for podlings to undergo two rounds of voting for each release: first the podling must vote successfully, and then the Incubator's mentors must vote to approve the release. In some cases, it takes weeks for enough Incubator mentors, who are volunteers, to vote on a release, so the releases end up delayed.
Though the two rounds of voting and the reduced frequency of releases may be seen as disadvantages, I think it is significant to note that the number of improvements, new microcontroller architectures, new board support, and bug fixes, have skyrocketed in the three years since NuttX joined the Apache.org Incubator. I think this is due in large part to the fact that the work previously done by an overworked BDFL is now shared among more than a dozen skilled developers who have been involved with NuttX for many years. I'd say that's a definite advantage.
The recent news (only a few days old at this writing) is that after roughly three years in the Incubator, the following mailing list posts appeared on the NuttX developer's mailing list:
Round one of voting at the NuttX podling level:
Seems there are exciting times ahead for Apache NuttX! Stay tuned while this story develops!
November 17, 2022: Happy Graduation, Apache NuttX Top-Level-Project!
I've written several times about the journey of NuttX from one-man-project to BDFL-driven community to merit-driven community at the Apache Incubator.
Today, NuttX has graduated the Apache Incubator and is officially Apache NuttX, a Top-Level-Project of the Apache Software Foundation!
The high12noon blog is pleased to say "Congratulations!" to the Apache NuttX community, who work tirelessly to bring this fantastic RTOS to the world.
Round two of voting at the Apache Incubator level:
Graduation announcement:
November 25, 2022: NuttX runs on the PINE64 PinePhone!
LEE Lup Yuen, an IoT educator, CTO, consultant, blogger, and NuttX developer, has written a series of articles about grokking the PINE64 PinePhone (PinePhone official site, PinePhone on Wikipedia). This is a 64-bit ARM Cortex-A53-based smartphone that normally runs Linux. And Lup Yuen has gotten NuttX to boot and run on it! The step-by-step process is documented in a series on articles on Lup Yuen's personal blog.
Today's exciting news is that PinePhone support has landed in NuttX! PR-7692, which was merged just a few short hours ago, upstreams the culmination of Lup Yuen's work thus far on the NuttX port to the PinePhone. These are exciting times indeed for NuttX on some seriously powerful hardware.
If you'd like to run NuttX on a PinePhone, see the documentation at Documentation/platforms/arm/a64/boards/pinephone/index.rst in the NuttX tree. In particular, Lup Yuen points out that a serial debug cable is needed.
Lup Yuen's educator background really shows as the blog articles are well-written with clear explanations, photographs, and beautiful illustrations. If you'd like to follow along on Lup Yuen's journey to bring NuttX to the PinePhone, the articles on Lup Yuen's blog, in chronological order through today, are:
- Apache NuttX RTOS on Arm Cortex-A53: How it might run on PinePhone
- PinePhone boots Apache NuttX RTOS
- NuttX RTOS for PinePhone: Fixing the Interrupts
- NuttX RTOS for PinePhone: UART Driver
- NuttX RTOS for PinePhone: Blinking the LEDs
- Simpler, safer LVGL Touchscreen Apps with Zig and NuttX (part of Lup Yuen's Understanding PinePhone's Display (MIPI DSI)
- NuttX RTOS for PinePhone: Display Driver in Zig
- Rendering PinePhone's Display (DE and TCON0)
- NuttX RTOS for PinePhone: Render Graphics in Zig
Hopefully many more helpful articles will follow on Lup Yuen's blog, so I recommend to set a bookmark and keep an eye on it!
References:
- PinePhone official site
- PinePhone (Wikipedia)
- NuttX pull request 7692
- Documentation/platforms/arm/a64/boards/pinephone/index.rst
January 16, 2023: NuttX 12.0 released!
This section last updated January 20th, 2023. (Added link to release announcement.)
The title says it all: Apache NuttX 12.0 has just been released!
There are a couple of firsts in this release:
- It's the first release since the NuttX developer community graduated the Apache Incubator to become a Top-Level-Project.
- It's also the first release to include support for running on PinePhone 64-bit hardware.
I've written about the new PinePhone support previously. Development of that support seems to be ongoing and improving with a continuing stream of PinePhone-related PRs at the NuttX GitHub.
The PinePhone is only one out of about 250 boards (I don't know the exact count) that currently are supported in the official NuttX tree. There is always the possibility to port NuttX to new boards and either upstream that support (propose it for inclusion in the official NuttX sources) or maintain it as an in-house "out-of-tree" board.
Upstreaming makes sense for commonly available off-the-shelf boards and hackable products. Upstreaming the support benefits the community as a whole because it allows others to use existing support as a starting point for their own projects. It also benefits the developer who upstreamed the support because they'll get improvements and bug fixes proposed by others "for free."
Maintaining a port as an in-house "out-of-tree" board makes sense in other contexts, such as for proprietary commercial products that use NuttX as the RTOS running in their boards.
NuttX is under the Apache 2.0 license, which makes both of the above scenarios possible.
References:
September 28-29, 2023: The NuttX International Workshop in Campinas, Brazil
This section last updated October 6th, 2023.
For the first time in three years, the 2023 NuttX International Workshop event was a physical event held at The School of Electrical and Computer Engineering (FEEC/Unicamp) in Campinas, Brazil. In addition to the physical event, it was made possible to attend virtually, and the proceedings have been placed online for later viewing. The recordings of the entire two-day event and all its presentations can be seen on YouTube by following the links below.
Note: The primary place to communicate with the NuttX developer and user community is at its mailing lists.
NuttX International Workshop Day 1
Day 1 - September 28, 2023
- 01:07:13 - PinePhone Touchscreen on NuttX: handling MIPI DSI, Display Engine and I2C Touch Input - Lup Yuen Lee
- 01:46:14 - Q&A
- 02:00:00 - LVGL in Webassembly: Buildi9ng NuttX Touchscreen Apps with Zig and testing them in the Web Browser - Lup Yuen Lee
- 02:27:45 - Q&A
- 02:34:10 - Quiz
- 02:52:10 - Coffee break
- 03:13:10 - NuttX VirtIO Framework and Future Works - Wang Bowen, Vela OS Team, Xiaomi
- 03:35:37 - NuttX network Subsystem Enhancement Overview - Zhe Weng, Vela Team, Xiaomi
- 03:53:45 - Q&A
- 04:02:10 - Discussion with Gregory Nutt
- 04:15:00 - Lunch break
- 05:22:34 - Wildfire Air Toxics Data Collection via UAV Equipped with Spresence - Prabhash Ragbir
- 05:41:35 - Q&A
- 05:50:48 - Wiegand Protocol, The world access control - Halysson Carvalho, Wilderness Lab
- 06:09:03 - Demo
- 06:11:44 - Q&A
- 06:19:13 - Real-time Road Classification Using NuttX and Tensorflow - Filipe do Ó Cavalcanti
- 06:55:15 - Q&A
- 07:10:13 - Using NuttX to develop an ultra low power datalogger with STM32L4 family - Oliver Augusto Miranda
- 07:27:12 - Q&A
- 07:32:20 - Using VS Code to develop NuttX based projects - Matheus Castello
- 08:17:30 - Q&A
- 08:20:40 - Coffee break
- 08:33:44 - IMU Fusion on NuttX Visualizing 3D Movements - Filipe do Ó Cavalcanti
- 08:45:40 - Demo
- 08:53:30 - Q&A
- 08:55:00 - Closing
Day 2 - September 29, 2023
- 00:03:23 - NuttX Status report - Alin Jerpelea
- 00:17:55 - Board draw - Alan C. Assis
- 00:27:23 - Porting Linux apps to NuttX - Alin Jerpelea
- 00:41:58 - Break
- 01:01:03 - Debugging and Profiling NuttX and PX4 - Niklas Hauser
- 01:30:35 - Q&A
- 02:12:40 - Apache MuttX RTOS for PINE64 PinePhone - Lup Yuen Lee
- 02:44:40 - Q&A
- 03:06:50 - Lunch Break
- 04:17:20 - Running NuttX with VirtIO on QEMU - Masayuki Ishikawa
- 05:05:10 - Q&A
- 05:14:20 - Sony Hands-on session - Camila Souza, Alin Jerpelea
- 08:01:05 - Closing
- 08:06:30 - Meeting picture
December 5, 2024: A Worldwide Distributed Embedded Build Farm? (Part 1)
How does one test a system as vast and complex as NuttX?
Currently, NuttX has two tiers, or at least what I'll call tiers, of testing.
These are:
- First tier: Compilation smoke test.
- Second tier: ostest, found in the nuttx-apps repository (GitHub).
Today, we'll discuss the first tier, which is the compilation smoke test. In part 2 (coming soon), we'll cover the ostest.
First Tier: Compilation Smoke Test
Simply stated, NuttX is compiled to see whether the build succeeds or is broken.
What can we possibly learn from that? After all, as anyone who has written code should know, code can compile just fine but not work correctly. While that's true, it is still important to perform this test. Here's why:
NuttX is a very complex codebase with an equally complex set of build requirements.
- It needs to build on the various host operating systems, including Linux, the BSDs, Macintosh, and Windows, used by developers.
- It needs to build with any number of different C cross-compiler toolchains.
- Possibly more importantly, it supports numerous target processor architectures ranging from 8-bit to 64-bit.
- It supports an even more numerous amount of systems on chip (SoC) or microcontroller (MCU) models. For example, armv7m is one variant of ARM processors. This one variant appears in hundreds of different SoCs and MCUs from different manufacturers. There are other variants of ARM as well. Furthermore, NuttX is not only an ARM-based RTOS. NuttX also supports RISC-V and MIPS and many more, each with their own variants.
- SoCs and MCUs do not exist in a vacuum. They must be installed on a board in order to function as part of a system. We've already said that the number of different SoCs or MCUs is much larger than the number of processor architectures. Well, these are absolutely eclipsed by the number of boards out there!
- Even when we've considered all the host operating systems and toolchains and target architectures and SoCs and boards, there is also a need for flexibility within NuttX itself to tune it to the particular system. What OS components are needed? How should they work? Which drivers are included? Which libraries and applications are needed?
To handle all of the above, a NuttX build is configured with myriad tuning knobs called Kconfig options. These control which files are compiled, how they are compiled, and sometimes exert fine grained control over details within the files. Given that there are countless combinations of Kconfig settings, it is combinatorially impossible to test every possible build of NuttX.
Yet, when editing code, it is very easy for a developer to make a build-breaking mistake that will not manifest on that developer's machine, because the particular Kconfig options in use will mask the mistake. However, if this code makes it into a Pull Request (PR) and is merged into the NuttX mainline, the build may suddenly start breaking for many other developers whose Kconfig settings do not mask the mistake.
If that were to happen frequently, with different people accidentally breaking different parts of the build unbeknownst to themselves, the community as a whole would start losing a lot of time, and gaining a lot of frustration, to broken builds that were working fine a moment ago, and now aren't.
How can we test every build if we just established that it is combinatorially impossible to do so? The answer is that while we cannot test every single possible build, we can at least compile all of the stock board configurations that NuttX comes with. If all of those build successfully, it gives us adequate confidence that the changes shouldn't break the build for most people, most of the time.
But there's a logistical problem. There are nearly 1,600 board configurations at this writing, and the number is always growing. Compiling nearly 1,600 builds on your own development machine, just to see if you've broken anything, will take much too long. It could be a significant number of hours!
The NuttX project tried to solve this by using GitHub Actions, which is GitHub's Continuous Integration (CI) system. This system has the computing power to perform these builds much faster than most developer machines. But there's a catch. It costs real money to use GitHub Actions, and with 1,600 builds happening for every PR and for every force-push in every PR, the costs were piling up fast.
Lup Yuen LEE, an educator and NuttX developer, explores this issue in several recent blog articles (external links):
- Continuous Integration for Apache NuttX RTOS in lupyuen.github.io
- Your very own Build Farm for Apache NuttX RTOS in lupyuen.github.io
- Optimising the Continuous Integration for Apache NuttX RTOS (GitHub Actions) in lupyuen.github.io
- Continuous Integration Dashboard for Apache NuttX RTOS (Prometheus and Grafana) in lupyuen.github.io
Based on those articles, it sounds like a temporary workaround has been put into place to reduce cost, but the work hasn't ended. The NuttX developers are apparently trying to come up with a way for volunteers around the world to somehow hook into a distributed system and participate in build testing without using an unreasonable amount of computing power from any individual volunteer.
This reminds me of earlier efforts at distributed computing, such as SETI@home (Wikipedia) or the Great Internet Mersenne Prime Search (Wikipedia). It should be interesting to keep an eye on this.
Do you have an idea how the NuttX developers can build a worldwide distributed build farm? I'm sure they'd like to hear about it at the NuttX developer mailing list! And, if it works for NuttX, it possibly could work for many other projects faced with similar challenges.
Check back soon for the second tier of testing, ostest.
NuttX Articles On Other Blogs
This section lists articles on other blogs that are related to NuttX and that I found interesting, helpful, or unique in some way.
This section last updated January 25th, 2022.
- Auto Flash and Test NuttX on RISC-V BL602 describes how one NuttX user gets daily updates from the upstream project, builds, flashes, and tests the changes on real hardware, automatically.
References and External Resources
This section last updated January 16, 2023.
- NuttX official site
- NuttX on GitHub
- The NuttX official site documentation.
- NuttX channel video #001 - Setting the Development Environment for NuttX
- NuttX channel video #002 - Compiling the NuttX Source Code
- NuttX channel video #003 - Flashing NuttX in the STM32F103 Minimum Board
- Getting Started with NuttX -- LM3S6965-EK (Ubuntu Linux) -- the LM3S is the grand daddy of the TM4C12x, so there is some relevant information there.
- The Buildroot user manual
- The OpenOCD user manual
- The NuttX Google Group forum — Note: Since the NuttX move to Apache.org, the NuttX Google Group forum is deprecated. Some people still use it and various NuttX developers seem to continue monitoring it and responding to questions, but most of the community now favors using the Apache.org-based email list instead. See the following item:
- Community page of the Apache NuttX website — lists the project's mailing lists (and other community resources) and how to join them.
- Christian's Blog: Getting Started with the TI Stellaris LaunchPad on Linux (December 11, 2012)
- Install and configure NuttX ARM build environment in Linux
- Building NuttX in Eclipse (Ubuntu)
- TI e2e Forums: "CCS/TMS320F28335: Building with external makefile does not export the active configurations" gave me a clue as to how to set up a CCSv9 project with a custom makefile.
- TI e2e Forums: "CCS/LAUNCHXL-CC1350: Memory Allocation View of Non TI App" gave me a clue as to how to get the Memory Allocation view working, which shows Flash and RAM usage as a percentage of Flash and RAM size.
- Solution to Eclipse: Searching For Binaries
- NuttX 2019 International Workshop at Gouda, South Holland
- Blog of Alan C. Assis, a NuttX developer
- Blog of LEE Lup Yuen, a NuttX developer
NuttX journey to Apache Top-Level-Project:
- Joining the Apache Incubator (December 2019):
- Graduating the Apache Incubator (November 2022):
- Round one of voting at the NuttX podling level:
- Round two of voting at the Apache Incubator level:
- Announcements:
As always, stay tuned for more Adventures with NuttX!
Send feedback to: the name of this blog at mail dot com.