Compiling Adafruit_LittleFS - semaphore type missing

Seeing as Particle don’t want to expose littleFS to users and I need a fail safe file system for SPI Flash -
I am trying to build the Adafruit_LittleFS for a SPIFlash. I get the following errors which are related to FreeRTOS missing semaphore definitions. Could someone point me towards a missing include?

In file included from /Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.cpp:27:0:
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h:88:5: error: ‘SemaphoreHandle_t’ does not name a type
SemaphoreHandle_t _mutex;
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h:91:5: error: ‘StaticSemaphore_t’ does not name a type
StaticSemaphore_t _MutexStorageSpace;
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h: In member function ‘void Adafruit_LittleFS::_lockFS()’:
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h:81:45: error: ‘_mutex’ was not declared in this scope
void _lockFS (void) { xSemaphoreTake(_mutex, portMAX_DELAY); }
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h:81:54: error: ‘portMAX_DELAY’ was not declared in this scope
void _lockFS (void) { xSemaphoreTake(_mutex, portMAX_DELAY); }
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h:81:67: error: ‘xSemaphoreTake’ was not declared in this scope
void _lockFS (void) { xSemaphoreTake(_mutex, portMAX_DELAY); }
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h: In member function ‘void Adafruit_LittleFS::_unlockFS()’:
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h:82:45: error: ‘_mutex’ was not declared in this scope
void _unlockFS(void) { xSemaphoreGive(_mutex); }
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.h:82:51: error: ‘xSemaphoreGive’ was not declared in this scope
void _unlockFS(void) { xSemaphoreGive(_mutex); }
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.cpp: In constructor ‘Adafruit_LittleFS::Adafruit_LittleFS(lfs_config*)’:
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.cpp:44:15: error: ‘varclr’ was not declared in this scope
varclr(&_lfs);
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.cpp:47:3: error: ‘_mutex’ was not declared in this scope
_mutex = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.cpp:47:47: error: ‘class Adafruit_LittleFS’ has no member named ‘_MutexStorageSpace’
_mutex = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
^
/Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/Adafruit_LittleFS.cpp:47:65: error: ‘xSemaphoreCreateMutexStatic’ was not declared in this scope
_mutex = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);

Hi @armor

I had replied to your support tickets. Let us check on your query above and reply to you.

Just retried building this on Photon OS 2.0.0-rc.4, I get these errors still:

/Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/nofp/libg_nano.a(lib_a-writer.o): in function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
/Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/nofp/libg_nano.a(lib_a-closer.o): in function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
/Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/nofp/libg_nano.a(lib_a-lseekr.o): in function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
/Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/nofp/libg_nano.a(lib_a-readr.o): in function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
/Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/nofp/libg_nano.a(lib_a-fstatr.o): in function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld: /Users/wjsteen/.particle/toolchains/gcc-arm/9.2.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/nofp/libg_nano.a(lib_a-isattyr.o): in function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
collect2: error: ld returned 1 exit status

Looking on stackoverflow looks like NewlibC-Nano is missing in linking? Can I include this using workbench?

Any pointers appreciated.

@particle7888, @armor, it would be good to share the “reply” to @armor’s questions so that all members can benefit. I’m certain others would be interested in a working LittleFS library for Gen2 devices.

The linking failure for _write, _close, _lseek, _isatty, etc. are almost always caused by a call to printf, scanf or other output to standard output, standard input, or standard error in the code that you are porting.

The original errors for semaphore, etc. are most likely because the original library directly used the FreeRTOS semaphore implementation. You’d need to change those to use the threading API wrappers in Device OS as you can’t directly call the FreeRTOS implementation from user firmware.

Sorry about that - will keep it on the community thread from now on.

1 Like

I am using the arm standard littleFS which is just 4 files:

lfs_util.c
lfs_util.h
lfs.c
lfs.h

Then in the application, 4 functions plus this struct need to be defined

const struct lfs_config cfg = {
    .context = NULL,            //could this be used to pass the spiFlash object?
    // block device operations
    .read  = _block_device_read,
    .prog  = _block_device_prog,
    .erase = _block_device_erase,
    .sync  = _block_device_sync,

    // block device configuration
    .read_size = 256,
    .prog_size = 256,
    .block_size = 4096,
    .block_count = 4096,
    .lookahead = 256,

    //optional buffers
    .read_buffer = lfs_read_buf,
    .prog_buffer = lfs_prog_buf,
    .lookahead_buffer = lfs_lookahead_buf,
    .file_buffer = lfs_file_buf
};

Given your clue about output, input I added #include <stdio.h> in lfs.h - no difference and then tried #include <stream.h> and the error is now

In file included from ./inc/Particle.h:5,
                 from /Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/lfs.h:10,
                 from /Users/wjsteen/Documents/Intelligent_Furniture_Project/VSC_Projects/littleFS-test//src/lfs.c:7:
./inc/application.h:33:10: fatal error: chrono: No such file or directory
   33 | #include <chrono>
      |          ^~~~~~~~
compilation terminated.

I thought this could be solved by #include <stdlib.h> but it doesn’t make any difference. Any ideas - feels like this is close.

Hi @peekay123, to clarify when I said I “replied” to armor, I meant I had taken his support ticket. We are in the midst of checking and coming up with more comprehensive solutions for him.

1 Like

I ported the LittleFS file system as a library for Gen 2 devices. It seems to work but there may still be bugs. Tested with Winbond, ISSI, and Macronix SPI NOR flash chips. It even works with the MX25L25645G 256 Mbit (32 Mbyte) flash chip, which I could not get to work reliably with SPIFFS.

5 Likes

I have compiled the example for a Winbond W25Q256JV flash memory that I had already got working using SpiFlashRK library (with adjustments for the erase timeouts, etc.), the LittleFS application hangs on the fs.mount() in setup() - what does this suggest? The flash had been formatted and written to using the SpiFlash test examples.

[Update] I rebuilt it and included some more Log statements and it started to work… Is there a timing issue for the mount? Test output looks correct - so I guess it is working (Photon 1.5.2).

0000010638 [app] INFO: Starting test1
0000010639 [app] INFO:  Dir .
0000010639 [app] INFO:  Dir ..
0000010639 [app] INFO:  Dir usr
0000010640 [app] INFO:    Dir .
0000010640 [app] INFO:    Dir ..
0000010640 [app] INFO:  Dir FileSystemTest
0000010641 [app] INFO:    Dir .
0000010641 [app] INFO:    Dir ..
0000010642 [app] INFO:    File test1.txt
0000010643 [app] INFO: /FileSystemTest exists and is a directory
0000010643 [app] INFO: createDirIfNecessary=1
0000010733 [app] INFO: Completed test1

If the flash is not formatted (for LittleFS) and the sectors are not already erased it could take a while to erase all of the sectors in a large file system. Might be up to 8 minutes for a 32 Mbyte flash chip. The checks are quick so mounts are normally fast but if the file system is not valid and not erased, that’s what takes a long time.

I ran the large file test for three days on the Macronix 256 Mbit flash chip and it worked perfectly, reading and writing large files constantly.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.