Normally NuttX supports internal (Built-In) applications embedded on its firmware. When you run: “nsh> hello” or your application, NuttX look for the application inside the internal flash of the microcontroller and run it.
But NuttX also supports running external applications. These external applications are ELF files. The ELF format is the default executable format used on Linux and almost all Unix OS.
Normally the OS needs to create a Global Symbol Table (AKA: symtab) where the ELF look at to translate the used functions of the ELF binary to memory addresses where these functions exist in the OS.
The “drawback” of this symtab is because it will waste a lot of space inside the flash (firmware) of the OS.
Fortunately NuttX also supports an alternative solution where this symtab is not needed. The ELF binary is created with the fixed memory position of each function address position. The drawback of this solution is the ELF binary is not relocatable, in other words: if you compile a new firmware for your board the existent external ELF binary could to fail because these functions positions are located at a different position now.
You can find the instructions for both options here:
http://www.nuttx.org/doku.php?id=wiki:nshhowtos:elf-addon
I tested the “no-symtab” option loading an external “hello” from a USB Flash Drive:
NuttShell (NSH) nsh> ls /dev /dev: console null sda ttyS0 nsh> ? help usage: help [-v] [] [ dirname help mh set unset ? dd hexdump mount sh usleep basename df kill mv sleep xd break echo ls mw test cat exec mb ps time cd exit mkdir pwd true cp false mkfatfs rm uname cmp free mkrd rmdir umount Builtin Apps: hello nsh> hello Hello, World!! nsh> mount -t vfat /dev/sda /bin nsh> hello Hello world from external binary! nsh>
As you can see initially the internal “hello” program was executed, but after I mounted the USB Flash Drive to /bin the external “hello” takes precedence over the internal.
These are the options I need to get it working:
CONFIG_STM32_OTGFS=y CONFIG_STM32_CCMEXCLUDE=y CONFIG_SCHED_WORKQUEUE=y CONFIG_SCHED_HPWORK=y CONFIG_USBHOST=y CONFIG_USBHOST_ISOC_DISABLE=y CONFIG_USBHOST_MSC=y CONFIG_FS_FAT=y CONFIG_BINFMT_EXEPATH=y CONFIG_PATH_INITIAL="/bin" CONFIG_ELF=y CONFIG_LIBC_ARCH_ELF=y CONFIG_LIBC_EXECFUNCS=y # CONFIG_EXECFUNCS_HAVE_SYMTAB is not set CONFIG_EXAMPLES_HELLO=y CONFIG_NSH_FILE_APPS=y CONFIG_NSH_ARCHINIT=y
Alan nice blog entry.
Very useful, I could execute the ELF from SD Card.
Thanks to the link of nuttx add-on, and your blog.
Greetings!
And now a question.
It can be execute, a ELF outside from the route established on
->Binary Loader->Initial PATH Value (/bin) of .config?
Like for example:
nsh> cd /sd/tmp
nsh> ls
/sd/tmp:
hello
nsh> ./hello
like linux?
Hi transistor retorcido, yes there is an option to run it from other place:
nsh> ?
help usage: help [-v] []
[ dirname help mh set unset
? dd hexdump mount sh usleep
basename df kill mv sleep xd
break echo ls mw test
cat exec mb ps time
cd exit mkdir pwd true
cp false mkfatfs rm uname
cmp free mkrd rmdir umount
Builtin Apps:
hello
nsh> hello
Hello, World!!
nsh> echo $PATH
/bin
nsh> unset PATH
nsh> set PATH /mnt
nsh> echo $PATH
/mnt
nsh> hello
Hello from external world!
nsh>
Does Nuttx support running multiple external apps? Can an app execute another app?
Yes, it supports many external applications and an app can execute other using exec() functions family