Mbed components (SD, FAT) without RTOS

I’m trying to add SDBlockDevice and FATFileSystem to a target that doesn’t support RTOS and on mbed 5.15.

My mbed_app.json looks like:

{
    "requires": ["bare-metal", "sd", "filesystem", "fat_chan"],
    "target_overrides": {
        "*": {
            "target.features_add": ["STORAGE"],
            "target.components_add": ["SD"],
            "platform.stdio-baud-rate": 115200
        }
    }
}

but the build crashes with:

...: fatal error: SDBlockDevice.h: No such file or directory

The same mbed_app.json on mbed cli does not run into this error (though other unrelated errors prevent it from building - I think they were linker errors).

I could copy the components/storage/blockdevice/COMPONENT_SD, storage/blockdevice, and storage/filesystem folders into a library, and with the addition of stubbing out rtos::ThisThread::sleep_for, it compiles and runs fine. But that seems like an ugly solution which unnecessarily duplicates code.

So:

  • Is my mbed_app.json wrong? Or is there another way to add these mbed components without requiring the RTOS?
  • Or is there a way to write a library.json that references the code in the mbed framework that PIO pulls?
  • Or something else?

Full platformio.ini and minimal test code?

Here’s the platformio.ini (it’s pretty minimal except for the long list of filesystem configs):

[env:test]
platform = nxplpc
board = lpc1549
framework = mbed

build_flags = 
  -D MBED_CONF_FAT_CHAN_FFS_DBG=0
  -D MBED_CONF_FAT_CHAN_FF_CODE_PAGE=437
  -D MBED_CONF_FAT_CHAN_FF_FS_EXFAT=0
  -D MBED_CONF_FAT_CHAN_FF_FS_HEAPBUF=0
  -D MBED_CONF_FAT_CHAN_FF_FS_LOCK=0
  -D MBED_CONF_FAT_CHAN_FF_FS_MINIMIZE=0
  -D MBED_CONF_FAT_CHAN_FF_FS_NOFSINFO=0
  -D MBED_CONF_FAT_CHAN_FF_FS_NORTC=0
  -D MBED_CONF_FAT_CHAN_FF_FS_READONLY=0
  -D MBED_CONF_FAT_CHAN_FF_FS_REENTRANT=0
  -D MBED_CONF_FAT_CHAN_FF_FS_RPATH=1
  -D MBED_CONF_FAT_CHAN_FF_FS_TIMEOUT=1000
  -D MBED_CONF_FAT_CHAN_FF_FS_TINY=1
  -D MBED_CONF_FAT_CHAN_FF_LFN_BUF=255
  -D MBED_CONF_FAT_CHAN_FF_LFN_UNICODE=0
  -D MBED_CONF_FAT_CHAN_FF_MAX_LFN=255
  -D MBED_CONF_FAT_CHAN_FF_MAX_SS=4096
  -D MBED_CONF_FAT_CHAN_FF_MIN_SS=512
  -D MBED_CONF_FAT_CHAN_FF_MULTI_PARTITION=0
  -D MBED_CONF_FAT_CHAN_FF_NORTC_MDAY=1
  -D MBED_CONF_FAT_CHAN_FF_NORTC_MON=1
  -D MBED_CONF_FAT_CHAN_FF_NORTC_YEAR=2017
  -D MBED_CONF_FAT_CHAN_FF_SFN_BUF=12
  -D MBED_CONF_FAT_CHAN_FF_STRF_ENCODE=3
  -D MBED_CONF_FAT_CHAN_FF_STR_VOLUME_ID=0
  -D MBED_CONF_FAT_CHAN_FF_SYNC_T=HANDLE
  -D MBED_CONF_FAT_CHAN_FF_USE_CHMOD=0
  -D MBED_CONF_FAT_CHAN_FF_USE_EXPAND=0
  -D MBED_CONF_FAT_CHAN_FF_USE_FASTSEEK=0
  -D MBED_CONF_FAT_CHAN_FF_USE_FIND=0
  -D MBED_CONF_FAT_CHAN_FF_USE_FORWARD=0
  -D MBED_CONF_FAT_CHAN_FF_USE_LABEL=0
  -D MBED_CONF_FAT_CHAN_FF_USE_LFN=3
  -D MBED_CONF_FAT_CHAN_FF_USE_MKFS=1
  -D MBED_CONF_FAT_CHAN_FF_USE_STRFUNC=0
  -D MBED_CONF_FAT_CHAN_FF_USE_TRIM=1
  -D MBED_CONF_FAT_CHAN_FF_VOLUMES=4
  -D 'MBED_CONF_FAT_CHAN_FF_VOLUME_STRS="RAM","NAND","CF","SD","SD2","USB","USB2","USB3"'
  -D MBED_CONF_FAT_CHAN_FLUSH_ON_NEW_CLUSTER=0
  -D MBED_CONF_FAT_CHAN_FLUSH_ON_NEW_SECTOR=1

Here’s the minimal main.cpp:

#include <mbed.h>
#include <SDBlockDevice.h>
#include <FATFileSystem.h>

SDBlockDevice Sd(P1_1, P0_10, P0_18, P0_7, 15000000);
FATFileSystem Fat("fs");

int main() {
  // demo code, no error / return code handling
  Sd.init();
  Fat.mount(&Sd);

  FileSystemLike& fs = Fat;
  mbed::FileHandle* file;
  fs.open(&file, "test", O_WRONLY | O_CREAT | O_TRUNC);
}

Note that this compiles if the includes are changed to:

#include <components/storage/blockdevice/COMPONENT_SD/SDBlockDevice.h>
#include <features/storage/filesystem/fat/FATFileSystem.h>

since presumably the base mbed directory is on the include path, but does not link with errors like undefined reference to 'SDBlockDevice::SDBlockDevice(PinName, PinName, PinName, PinName, unsigned long long, bool)', presumably because those components and features are not being compiled.