NuttX apps compilation issue

If you decide you create your own NuttX application based on apps/examples/hello you could eventually face this issue:

CC: my_app_main.c
:0:6: error: expected identifier or '(' before numeric constant
:0:6: error: expected identifier or '(' before numeric constant
my_app_main.c:51:5: note: in expansion of macro 'main'
int main(int argc, FAR char *argv[])
^
make[3]: *** [/home/alan/apps/Application.mk:189: my_app_main.home.alan.apps.examples.my_app.o] Error 1

This error happens because your PROGNAME defined inside the Kconfig differs from your application name:

config EXAMPLES_MYAPPNAME_PROGNAME
string "Program name"
default "myapp"

If your PROGNAME is myapp then you need to have apps/examples/myapp/myapp_main.c otherwise it will not work. So don’t my_app for your app directory neither my_app_main.c for your main file, it needs to be myapp_main.c

Linking external libraries on NuttX

Some time ago I needed to link with ARM DSP library on NuttX to use FFT feature and I decided to document who I did it and some tricks to reduce the final binary size.

In fact to include a library all you need to do is add it to your board Make.defs. See a simple patch file to stm32f4discovery:

index 59aa60bf6b..5e6845c81c 100644
--- a/boards/arm/stm32/stm32f4discovery/scripts/Make.defs
+++ b/boards/arm/stm32/stm32f4discovery/scripts/Make.defs
@@ -63,6 +63,8 @@ CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
AFLAGS = $(CFLAGS) -D__ASSEMBLY__

+EXTRA_LIBS = "$(TOPDIR)/3rparty/libarmdsp.a"
+
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048

It means you need to create a “3rdpary” directory at root of nuttx/ and put your library there.

But after the compilation you will notice that your nuttx.bin binary will become very big. It happens because the linker will include all the functions in the library.

You can instruct it to include only the needed functions using this parameter with LDFLAGS:

LDFLAGS += --gc-sections

Now your binary will become way smaller

Testing PSRAM support for NuttX on ESP-WROVER-KIT

rst:0x1 (POWERON_RESET),boot:0x1e (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7160
load:0x40078000,len:13376
ho 0 tail 12 room 4
load:0x40080400,len:4084
entry 0x40080680
I (30) boot: ESP-IDF v4.2-dev-1883-gb8f5d2e46 2nd stage bootloader
I (30) boot: compile time 17:37:10
I (30) boot: chip revision: 1
I (35) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (42) boot.esp32: SPI Speed : 40MHz
I (46) boot.esp32: SPI Mode : DIO
I (51) boot.esp32: SPI Flash Size : 2MB
I (55) boot: Enabling RNG early entropy source…
I (61) boot: Partition Table:
I (64) boot: ## Label Usage Type ST Offset Length
I (72) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (79) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (87) boot: 2 factory factory app 00 00 00010000 00100000
I (94) boot: End of partition table
I (98) boot_comm: chip revision: 1, min. application chip revision: 0
I (105) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x02eb8 ( 11960) map
I (120) esp_image: segment 1: paddr=0x00012ee0 vaddr=0x3ffbae40 size=0x0006c ( 108) load
I (123) esp_image: segment 2: paddr=0x00012f54 vaddr=0x40080000 size=0x00400 ( 1024) load
I (133) esp_image: segment 3: paddr=0x0001335c vaddr=0x40080400 size=0x01c64 ( 7268) load
I (145) esp_image: segment 4: paddr=0x00014fc8 vaddr=0x00000000 size=0x0b050 ( 45136)
I (169) esp_image: segment 5: paddr=0x00020020 vaddr=0x400d0020 size=0x1a43c (107580) map
I (217) boot: Loaded app from partition at offset 0x10000
I (218) boot: Disabling RNG early entropy source…
NuttShell (NSH) NuttX-9.1.0
nsh> free
total used free largest
Umem: 4477264 15872 4461392 4194288
nsh> ?
help usage: help [-v] []
. cd exec ifconfig mkrd put test usleep
[ cp exit ifdown mh pwd telnetd wget
? cmp false ifup mount rm time xd
arp dirname free kill mv rmdir true
basename dd get ls mw set uname
break df help mb nslookup sleep umount
cat echo hexdump mkdir ps source unset
Builtin Apps:
sh ramtest ping nsh
nsh> ramtest -w 0x3F800000 4194304
RAMTest: Marching ones: 3f800000 4194304
RAMTest: Marching zeroes: 3f800000 4194304
RAMTest: Pattern test: 3f800000 4194304 55555555 aaaaaaaa
RAMTest: Pattern test: 3f800000 4194304 66666666 99999999
RAMTest: Pattern test: 3f800000 4194304 33333333 cccccccc
RAMTest: Address-in-address test: 3f800000 4194304
nsh>

Xiaomi Mi True Wireless Earbuds review

I’m using the Mi Earbuds for two days and these are my impressions so far:

  • Pros:
  • It is comfortable because it fits perfectly in the ears! At first I thought I was going to feel like the Frankenstein with his bolts in his neck, but it was my prejudice;
  • The battery duration is fine, of course it should be nice if it could run for days instead of a single day;
  • It is very light weight compared to others Wireless headsets.
  • Cons:
  • It often drops off your ears mainline when you are speaking or eating;
  • It starts to cut the connection when you are more than 5 meter far from your smartphone (in my case I’m using a high-end Xiaomi smartphone);
  • There is not a button to move to the next music, hopefully I found a solution for it:

So, I’m happy with this product, but I think Xiaomi could make improvements for the next models to fix these points.

NuttX failing with dirlinks error

This is common error on NuttX, but unfortunately the build system is not clear to explain to the user about it.

$ git clone https://github.com/apache/incubator-nuttx
$ cd incubator-nuttx
$ ./tools/configure.sh esp32-core:nsh
...
This program built for x86_64-pc-linux-gnu
Report bugs to bug-make@gnu.org
make: *** [tools/Makefile.unix:319: dirlinks] Error 2
ERROR: failed to refresh

This problem happens because you missed to clone the apps/ repository:

$ cd ..
$ git clone https://github.com/apache/incubator-nuttx-apps apps

Now you can configure it correctly:

$ cd incubator-nuttx
$ ./tools/configure.sh esp32-core:nsh
...
#
# configuration written to .config
#

Testing IOTJS on NuttX

$ git clone https://github.com/spiriou/incubator-nuttx-apps apps
$ git clone https://github.com/apache/incubator-nuttx
$ cd apps
$ git checkout -b iotjs origin/iotjs
Branch 'iotjs' set up to track remote branch 'iotjs' from 'origin'.
Switched to a new branch 'iotjs'
$ cd ../incubator-nuttx
Config:
CONFIG_ARCH_FPU is not set
CONFIG_NSH_ARGCAT is not set
CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_NSH_CMDPARMS is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="stm32f4discovery"
CONFIG_ARCH_BOARD_STM32F4_DISCOVERY=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="stm32"
CONFIG_ARCH_CHIP_STM32=y
CONFIG_ARCH_CHIP_STM32F407VG=y
CONFIG_ARCH_SETJMP_H=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_FS_FAT=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INTELHEX_BINARY=y
CONFIG_IOTJS=y
CONFIG_LIBUV=y
CONFIG_LIBUV_FS=y
CONFIG_LIBUV_TCP=y
CONFIG_LIBUV_TIMER=y
CONFIG_LIBUV_WQ=y
CONFIG_MAX_TASKS=16
CONFIG_MM_REGIONS=2
CONFIG_NET=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NET_SOCKOPTS=y
CONFIG_NET_TCP=y
CONFIG_NET_TCPBACKLOG=y
CONFIG_NET_TCP_KEEPALIVE=y
CONFIG_NFILE_DESCRIPTORS=8
CONFIG_NFILE_STREAMS=8
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_PWR=y
CONFIG_STM32_SPI1=y
CONFIG_STM32_USART2=y
CONFIG_SYSTEM_NSH=y
CONFIG_USART2_RXBUFSIZE=128
CONFIG_USART2_SERIAL_CONSOLE=y
CONFIG_USART2_TXBUFSIZE=128
CONFIG_USER_ENTRYPOINT="nsh_main"
$ make

$ sudo openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000"

Create the RAMDISK:
nsh> mkrd 64
nsh> mkfatfs /dev/ram0
nsh> mount -t vfat /dev/ram0 /mnt

Create the sample file:
nsh> echo "var fs = require('fs');" > /mnt/index.js
nsh> echo "console.log('Hello World');" >> /mnt/index.js

Confirm it is correct:
nsh> cat /mnt/index.js
var fs = require('fs');
console.log('Hello World');

Is iotjs here?
nsh> ?
help usage: help [-v] []
. cd exec ifdown mkrd pwd time
[ cp exit ifup mh rm true
? cmp false kill mount rmdir uname
arp dirname free ls mv set umount
basename dd help mb mw sleep unset
break df hexdump mkdir nslookup source usleep
cat echo ifconfig mkfatfs ps test xd
Builtin Apps:
iotjs sh hello nsh


All right, run it:
nsh> iotjs /mnt/index.js
Hello World
nsh>

How to use RAMDISK as filesystem on NuttX

NuttX is evolving all the time and although I created a video tutorial at NuttX Channel explaining how to create a RAMDISK, that information is already outdated.

Let’s do it again using the current NuttX version (9.1)

First select the needed options at menuconfig:

Device Drivers  --->
    [*] RAM disk wrapper (mkrd)

Board Selection  --->
    [*] Enable boardctl() interface
    [*] Enable application space creation of RAM disks

File Systems --->
    [*] FAT file system

Compile it and run these commands when NuttX’s nsh show up on serial console:

NuttShell (NSH) NuttX-9.1.0
nsh> ?
help usage: help [-v] []
. cd echo hexdump mkrd pwd test usleep
[ cp exec kill mh rm time xd
? cmp exit ls mount rmdir true
basename dirname false mb mv set uname
break dd free mkdir mw sleep umount
cat df help mkfatfs ps source unset
Builtin Apps:
sh nsh

nsh> mkrd 64
nsh> ls /dev
/dev:
console
null
ram0 <---
ttyS0

nsh> mkfatfs /dev/ram0

nsh> mount -t vfat /dev/ram0 /mnt

nsh> echo "This is a file in RAMDISK" > /mnt/file.txt
nsh> cat /mnt/file.txt
This is a file in RAMDISK
nsh>