nxflatxip NXFLAT Executed In Place from XIPFS
Writes an NXFLAT module into a XIPFS volume at run time, the way a download would, and runs two instances of it concurrently. The module’s text is executed directly out of flash and shared between the instances; each instance gets its own data.
The same module in a ROMFS image would execute in place just as well. What it could not do is arrive after the firmware was built, which is the point of the exercise.
Usage:
nxflatxip [bench | defrag]
With no argument it stages the module, reports the extent it landed in and the flash address the file system will map it at, then runs both instances:
nsh> nxflatxip
=== NXFLAT module executed in place from xipfs ===
staged 268 bytes to /mnt/xipfs/xipmod
extent: block 6 x1, size 268, flash addr 0x10106000
running two concurrent instances...
[while running] pin count on the shared text = 2
instance seed 1: text 0x10106070, stack 0x20006860, sum 2080 -- data private and intact
instance seed 2: text 0x10106070, stack 0x200074b0, sum 4160 -- data private and intact
[after exit] pin count on the shared text = 2 (released when this task exits)
The two instances report the same text address, inside the flash window and equal to where the file lies on the media, and different stack addresses. While they run the extent carries one pin per instance, which is what stops the defragmenter relocating code that is executing.
The pins outlive the instances: binfmt maps the text in the context of
whoever called exec(), so the mappings belong to the demo’s address space
and are released when it exits. Run xipfs -n afterwards to see the count
back at zero.
Subcommands
benchTimes a bulk read out of the mapped flash before and after a write. On a target whose driver has to tear down and restore execute-in-place around each erase, the difference is the cost of whichever restore path it used. Needs a large file to read; the command says how to create one.
defragFills the volume, deletes every other file until an allocation genuinely cannot be satisfied, compacts, retries the same allocation, then verifies every relocated file byte for byte and again after a remount. Prints a block map at each step.
Building the module
The module is built from module/xipmod.c at build time, exactly the way
nxflat NXFLAT Binary builds its test programs, so it needs the same two
host tools from the NuttX toolchain, mknxflat and ldnxflat, and the
board’s Make.defs must name them.
The module has no static data and no string constants, and reports through a
callback into the firmware rather than formatting its own output. The comment
at the top of module/xipmod.c records why: the ldnxflat in
circulation miscomputes both of those cases. The callback also exercises the
other direction of the interface, firmware code entered with the module’s
data base still live in its PIC register.
Configuration
CONFIG_EXAMPLES_NXFLATXIPEnable the example. Requires
CONFIG_FS_XIPFS,CONFIG_NXFLATandCONFIG_LIBC_EXECFUNCS.CONFIG_EXAMPLES_NXFLATXIP_MOUNTPTThe XIPFS volume to use.
CONFIG_EXAMPLES_NXFLATXIP_MTDThe MTD device backing that volume, used only by the
defragsubcommand, which remounts to show that what it did survives.