Read-Only FS in MCU Flash

The ROM file system

The ROM file system (ROMFS) is a small, read-only file system built for eLua. It is integrated with the C library, so you can use standard POSIX calls (fopen/fread/fwrite...) to access it. It is also accessible directly from Lua via the io module. The files in the file system are part of the eLua binary image, thus they can't be modified after the image is built. For the same reason, you can't add/delete files after the image is built. ROMFS doesn't support sub-directories.

ROMFS is integrated with the build system for maximum flexibility on various platforms. As a result, you can select the ROMFS contents for each board on which eLua runs. Moreover, you can specify what applications (instead of individual files) go to the file system, as a real application might need more than a single Lua program to run (for example a HTTP page with all its dependencies).

Using ROMFS

To use ROMFS, you have to copy the required files to the romfs/ directory, before building eLua. Keep in mind that the maximum file name of a ROMFS file is 14 characters, including the dot between the file name and its extension. Make sure that the file names from romfs/ follow this rule. Then edit the main build script (SConstruct) to add a new application or to modify an existing one. All the applications that can be included in ROMFS are defined in the romfs array in SConstruct. Each application in the romfs array lists its files, as shown below (note that ltthpd, tvbgone and pong applications require more than one file in order to run):

romfs = { 
    'bisect' : [ 'bisect.lua' ],
    'hangman' : [ 'hangman.lua' ],
    'lhttpd' : [ 'index.pht', 'lhttpd.lua', 'test.lua' ],
    'pong' : [ 'pong.lua', 'LM3S.lua' ],
    'led' : [ 'led.lua' ],
    'piano' : [ 'piano.lua' ],
    'pwmled' : [ 'pwmled.lua' ],
    'tvbgone' : [ 'tvbgone.lua', 'codes.bin' ],
    'hello' : [ 'hello.lua' ],
    'info' : [ 'info.lua' ],
    'morse' : [ 'morse.lua' ],
    'dualpwm' : [ 'dualpwm.lua' ],
    'adcscope' : [ 'adcscope.lua' ],
    'life' : [ 'life.lua' ]
}

After this, you need to decide the application-to-board mapping. This is defined in another array in SConsctruct, named file_list. The definition of this array is shown below, the format is self-explanatory:

file_list = { 
    'SAM7-EX256' : [ 'bisect', 'hangman' , 'led', 'piano', 'hello', 'info', 'morse' ],
    'EK-LM3S8962' : [ 'bisect', 'hangman', 'lhttpd', 'pong', 'led', 'piano', 'pwmled', 'tvbgone', 'hello', 'info', 'morse', 'adcscope' ],
    'EK-LM3S6965' : [ 'bisect', 'hangman', 'lhttpd', 'pong', 'led', 'piano', 'pwmled', 'tvbgone', 'hello', 'info', 'morse', 'adcscope' ],
    'STR9-COMSTICK' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
    'PC' : [ 'bisect', 'hello', 'info', 'life' ],
    'LPC-H2888' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
    'MOD711' : [ 'bisect', 'hangman', 'led', 'hello', 'info', 'dualpwm' ],
    'STM3210E-EVAL' : [ 'bisect', 'hello', 'info' ],
    'ATEVK1100' : [ 'bisect', 'hangman', 'led', 'hello', 'info' ],
    'ET-STM32' : [ 'hello', 'hangman', 'info', 'bisect' ],
    'EAGLE-100' : [ 'bisect', 'hangman', 'lhttpd', 'led', 'hello', 'info' ]              
}

What's left to do is build eLua. As part of the build process, mkfs.py will be called, which will read the contents of the romfs/ directory and output a C header file that contains a binary description of the file system. To use ROMFS from C code, whevener you want to access a file, prefix its name with /rom/. For example, if you want to open the a.txt file in ROMFS, you should call fopen like this:

f = fopen( "/rom/a.txt", "rb" )

If you want to execute one file from the ROM file system with Lua, simply do this from the shell:

eLua# lua /rom/bisect.lua

Or directly from Lua:

> dofile "/rom/bisect.lua"

ROMFS modes

Starting with version 0.7, the ROMFS can be added to the eLua binary image in 3 different ways:

  • verbatim: this is the default option. All the files are copied to the ROMFS directly, without any processing.
  • compress: compress the Lua source code by using LuaSrcDiet (included in eLua), a program that can decrease the size of a Lua source file by applying different transformations. Every Lua source file (extension .lua) from ROMFS is fed through LuaSrcDiet and the result is written in the eLua binary image. This option can yield pretty good compression, the only downside being that the compressed Lua source files aren't generally easily readable. However, this isn't really a problem in most practical cases.
  • compile: precompile the Lua source code to bytecode. Every Lua source file (extension .lua) from ROMFS is fed through the Lua cross compiler (see here for details on cross compilation and its benefits) and the result is written in the eLua binary image. This option might decrease or increase the physical size of the ROMFS image, but its real benefits are increased speed (because eLua doesn't need to compile the Lua code to bytecode first) and decreased RAM consumption (the Lua parser might get quite memory-hungry at times, which in turn might lead to stack overflows and very hard to find bugs).

See here for instructions on how to specify the ROMFS compilation mode.