Skip to content

Commit de82822

Browse files
fdcavalcantif-hollow
authored andcommitted
blog: add nuttx article for external static libraries
Adds and article with instructions on how to use an externally built static library. Signed-off-by: Filipe Cavalcanti <[email protected]>
1 parent fc8fb4c commit de82822

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed
254 KB
Loading
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
title: "Integrating External Libraries into NuttX Applications"
3+
date: 2025-11-19
4+
tags: ["NuttX", "Apache", "ESP32", "ESP32-C6", "RISC-V", "cross-compilation", "static-library"]
5+
showAuthor: false
6+
authors:
7+
- "filipe-cavalcanti"
8+
summary: "This guide demonstrates how to integrate external libraries into NuttX applications using static libraries and cross-compilation. Learn how to build a library on x86, integrate it into the NuttX simulation environment, and cross-compile for RISC-V targets like the ESP32-C6, all without moving your codebase into the NuttX directory structure."
9+
---
10+
11+
## Introduction
12+
13+
When moving your application to NuttX, you often need to add your existing software stack to the NuttX image. This software may run on a different RTOS or even on an x86 environment, but sometimes it must run on multiple target devices. This article shows how to build NuttX with your custom application without moving your entire stack to the NuttX directory. You use a static library and cross-compilation to achieve this.
14+
15+
This article is divided into three parts. The first part introduces and builds the sample library on x86. Then, a second part decribes how to add the library to the NuttX simulation environment and finally, the last part cross-compiles to RISC-V and runs the example on the ESP32-C6.
16+
17+
## Using an example library
18+
19+
As an example, we will use an example application library that converts a hexadecimal color string to RGB with the following structure:
20+
21+
```
22+
hex-converter/
23+
├── src/
24+
│ ├── hex_to_rgb.h
25+
│ └── hex_to_rgb.c
26+
├── main.c
27+
├── test.c
28+
├── Makefile
29+
└── README.md
30+
```
31+
32+
The reference project is available in [this repository](https://github.com/fdcavalcanti/hex-converter).
33+
34+
The `hex-converter` library exposes one single function called `hex_to_rgb`. The user provides a pointer to a string representing the hex color and a pointer
35+
to an array where the R, G, and B values are copied. It is a simple application but very useful as an example.
36+
37+
Clone the repository and build it according to the steps in the README file to produce the static library. To confirm that everything works, run the provided `main` example program. This program accepts a hexadecimal color string as input.
38+
39+
```bash
40+
$ ./main "#1A2B3C"
41+
Input: #1A2B3C
42+
RGB: (26, 43, 60)
43+
```
44+
45+
At this point, the directory should contain a static library called `libhex_to_rgb.a` that will be added to the NuttX build system.
46+
47+
## Testing on NuttX Simulation
48+
49+
As an user, you might want to use this library in an application. The first solution might be to copy the entire hex-converter repository to the NuttX application directory and
50+
add it entirely to the build system. That works but is complicated, not user-friendly, and causes a Makefile mess.
51+
52+
The simplest way to test this library on NuttX is to modify the ready-to-use Hello World example in the NuttX Apps repository, which could in fact be any application.
53+
54+
With your NuttX environment ready, follow these steps:
55+
56+
1. Copy `libhex_to_rgb.a` from the hex-converter repository to `apps/examples/hello` (the Hello World example directory).
57+
2. In `apps/hello/Make.defs`, add the hex library, library path, and include path.
58+
59+
The Make.defs file should look like this:
60+
```
61+
ifneq ($(CONFIG_EXAMPLES_HELLO),)
62+
CONFIGURED_APPS += $(APPDIR)/examples/hello
63+
64+
EXTRA_LIBS += -lhex_to_rgb
65+
EXTRA_LIBPATHS += -L$(APPDIR)/examples/hello
66+
CFLAGS += ${INCDIR_PREFIX}/home/user/hex-converter/src
67+
68+
endif
69+
```
70+
71+
To use the library, we edit the `hello_main.c` file to look like this:
72+
73+
```c
74+
/****************************************************************************
75+
* Included Files
76+
****************************************************************************/
77+
78+
#include <nuttx/config.h>
79+
#include <stdio.h>
80+
#include <stdlib.h>
81+
82+
#include "hex_to_rgb.h"
83+
84+
/****************************************************************************
85+
* Public Functions
86+
****************************************************************************/
87+
88+
/****************************************************************************
89+
* hello_main
90+
****************************************************************************/
91+
92+
int main(int argc, FAR char *argv[])
93+
{
94+
int rgb[3];
95+
int result;
96+
97+
if (argc != 2) {
98+
return EXIT_FAILURE;
99+
}
100+
101+
printf("Input: %s\n", argv[1]);
102+
103+
result = hex_to_rgb(argv[1], rgb);
104+
105+
if (result == HEX_TO_RGB_SUCCESS) {
106+
printf("RGB: (%d, %d, %d)\n", rgb[0], rgb[1], rgb[2]);
107+
}
108+
else {
109+
printf("Error: %d\n", result);
110+
}
111+
112+
return result;
113+
}
114+
```
115+
116+
After all changes are done, build the NuttX simulation:
117+
118+
1. `./tools/configure.sh sim:nsh`
119+
2. `make`
120+
3. Execute: `./nuttx`
121+
122+
Call the `hello` program. This executes the HEX to RGB conversion:
123+
```
124+
user@desktop:~/nxsupport/nuttx$ ./nuttx
125+
NuttShell (NSH) NuttX-12.8.0
126+
nsh> hello "#1a2b3c"
127+
Input: #1a2b3c
128+
RGB: (26, 43, 60)
129+
nsh>
130+
```
131+
132+
Success! We can compile our library externally, link it to a NuttX application, and use it.
133+
134+
## Using the library on ESP32C6
135+
136+
Now that simulation works, we must look into a real use case that requires the same code to work on hardware.
137+
For this, we must compile the library to be supported on our RISC-V target.
138+
139+
### Cross-compilation
140+
141+
In the hex-converter Makefile, the CC instruction changes to `riscv-none-elf-gcc` instead of `gcc` when you set the TARGET variable.
142+
143+
Clear the environment to delete the x86 build and rebuild for RISC-V:
144+
1. `make clean`
145+
2. `make TARGET=riscv32`
146+
147+
The same `libhex_to_rgb.a` library is ready, but now it can be used on RISC-V devices. This can be verified easily:
148+
149+
```
150+
$ file main
151+
main: ELF 32-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, not stripped
152+
```
153+
154+
### Test on target
155+
156+
Clean the NuttX environment with `make distclean` and configure it for the `nsh` example of ESP32-C6.
157+
158+
Copy the new `libhex_to_rgb.a` to the `hello` example directory. Then configure and build the project:
159+
160+
1. `make distclean`
161+
2. `./tools/configure.sh esp32c6-devkitc:nsh`
162+
3. On `menuconfig`, enable Hello World example (Application Configuration → Examples > "Hello World" Example)
163+
4. `make`
164+
165+
Flash the board and try the `hello` example using the serial console:
166+
167+
```
168+
[...]
169+
SHA-256 comparison failed:
170+
Calculated: d07603736784dd3c56754d4d27366ffd0c2a32aebaddea7e6c0a153ad774ba15
171+
Expected: 00000000009d0000000000000000000000000000000000000000000000000000
172+
Attempting to boot anyway...
173+
entry 0x40805496
174+
pmu_param(dbg): blk_version is less than 3, act dbias not burnt in efuse
175+
*** Booting NuttX ***
176+
[...]
177+
NuttShell (NSH) NuttX-12.8.0
178+
nsh> hello "#1a2b3c"
179+
Input: #1a2b3c
180+
RGB: (26, 43, 60)
181+
nsh>
182+
```
183+
184+
With a simple change of compiler and no changes to the NuttX build system, we were able to have the same example
185+
running on an ESP32-C6.
186+
187+
## Conclusion
188+
189+
This article demonstrates how to integrate external libraries into NuttX applications using static libraries and cross-compilation. The process involves three main steps: building the library on x86, integrating it into the NuttX simulation environment, and cross-compiling for the target hardware.
190+
191+
The static library approach offers several advantages. You can develop and test your code on an x86 machine without flashing the target device. The same library works across different architectures with minimal changes, requiring only a recompilation step. This workflow saves development time and simplifies the porting process.
192+
193+
By following these steps, you can add existing software stacks to NuttX without moving your entire codebase into the NuttX directory structure. This approach maintains separation between your application code and the RTOS, making maintenance and updates easier.
194+
195+
## Related Resources
196+
197+
- [NuttX ESP32 Documentation](https://nuttx.apache.org/docs/latest/platforms/risc-v/esp32c6/index.html)
198+
- [Getting Started with NuttX and ESP32](https://developer.espressif.com/blog/nuttx-getting-started/)

0 commit comments

Comments
 (0)