I’ve been struggling with this all week now. I am trying to get littlefs to create a directory in /lfs but it fails with error -22. I was able to get it to work once, but now… nothing.

This is my code snippet:

...
        char dname[MAX_PATH_LEN];

	// create data directory if it doesn't exist
	printk("Creating data directory...\n");
	
        // STORE_FORWARD_DIR defined as "sfdata"
	snprintf(dname, sizeof(dname), "%s/%s", mp->mnt_point, STORE_FORWARD_DIR);

	int rc = fs_mkdir(dname);
	if (rc && rc != -EEXIST) {
		printk("  mkdir(%s) error -> rc=%d\n", dname, rc);
		return rc;
	} 
	printk("  mkdir(%s) SUCCESS -> rc=%d\n", dname, rc);
...

I’ve tried numerous variations of this but no luck. The one time I was able to create it the file system worked perfectly but then I decided to attempt a reset the file system by erasing the flash area. However this seemed to corrupt the flash device and I was not longer able to do anything with it. I assumed I wrecked the flash and ordered more boards assuming that was my problem.

On a brand new board, this still does not work and I am at a loss. Naturally there are other implementations I could choose that do not require a subdirectory, but I am more concerned that I am doing something fundamentally wrong and I don’t want to deploy devices with a critical fault so I really need to get something so basic working properly.

Has anyone tried this yet?

  • jaredwolff replied to this.
  • imoon So I’ve been playing with this and thus far my observations are:

    1. I can write to multiple files and recover their contents:
    /lfs mount: 0
    /lfs: bsize = 16 ; frsize = 4096 ; blocks = 8192 ; bfree = 8190
    
    /lfs/test0 stat: 0
    fn 'test0' siz 22
    /lfs/test0 {"test":0,"entry",:0}: 22
    /lfs/test0 seek start: 0
    /lfs/test0 close: 0
    /lfs/test1 stat: 0
    fn 'test1' siz 22
    /lfs/test1 {"test":1,"entry",:1}: 22
    /lfs/test1 seek start: 0
    /lfs/test1 close: 0
    /lfs/test2 stat: 0
    fn 'test2' siz 22
    /lfs/test2 {"test":2,"entry",:2}: 22
    /lfs/test2 seek start: 0
    /lfs/test2 close: 0
    /lfs/test3 stat: 0
    fn 'test3' siz 22
    /lfs/test3 {"test":3,"entry",:3}: 22
    /lfs/test3 seek start: 0
    /lfs/test3 close: 0
    /lfs/test4 stat: 0
    fn 'test4' siz 22
    /lfs/test4 {"test":4,"entry",:4}: 22
    /lfs/test4 seek start: 0
    /lfs/test4 close: 0
    /lfs/test5 stat: 0
    fn 'test5' siz 22
    /lfs/test5 {"test":5,"entry",:5}: 22
    /lfs/test5 seek start: 0
    /lfs/test5 close: 0
    /lfs/test6 stat: 0
    fn 'test6' siz 22
    /lfs/test6 {"test":6,"entry",:6}: 22
    /lfs/test6 seek start: 0
    /lfs/test6 close: 0
    /lfs/test7 stat: 0
    fn 'test7' siz 22
    /lfs/test7 {"test":7,"entry",:7}: 22
    /lfs/test7 seek start: 0
    /lfs/test7 close: 0
    /lfs/test8 stat: 0
    fn 'test8' siz 22
    /lfs/test8 {"test":8,"entry",:8}: 22
    /lfs/test8 seek start: 0
    /lfs/test8 close: 0
    /lfs/test9 stat: 0
    fn 'test9' siz 22
    /lfs/test9 {"test":9,"entry",:9}: 22
    /lfs/test9 seek start: 0
    /lfs/test9 close: 0
    1. One thing I did notice was that it failed erasing the volume with a -19 error. (ENODEV from errno.h)
    2020-11-22T18:31:09.666Z DEBUG modem << Erasing flash area ... -19
    2020-11-22T18:31:09.689Z DEBUG modem << [00:00:00.013,397] [0m<inf> littlefs: LittleFS version 2.2, disk version 2.0[0m
    2020-11-22T18:31:09.691Z DEBUG modem << [00:00:00.021,636] [0m<inf> littlefs: FS at W25Q32JV:0x0 is 8192 0x1000-byte blocks with 512 cycle[0m
    2020-11-22T18:31:09.693Z DEBUG modem << [00:00:00.030,914] [0m<inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32[0m
    2020-11-22T18:31:09.722Z DEBUG modem << [00:00:00.054,199] [0m<inf> littlefs: /lfs mounted[0m

    So looking into it, it appears that the CONFIG_PM_EXTERNAL_FLASH_SIZE should be 0×400000. I had the value in bits which screwed everything up. Now full flash erases ok with no errors. I just pushed the example repository.

    2020-11-22T18:41:04.783Z DEBUG modem << *** Booting Zephyr OS build v2.3.0-rc1-ncs3  ***
    2020-11-22T18:41:04.785Z DEBUG modem << Area 0 at 0x0 on W25Q32JV for 33554432 bytes
    2020-11-22T18:41:05.236Z DEBUG modem << Erasing flash area ... 0

    Sorry for the delay on this @imoon

    Some other great resources when fiddling with the flash. (Hopefully you don’t have to after this.)

    imoon ugg sorry about this. I had some similar issues start up. You can erase your external flash as much as you want. As long as you reinitialize it it should come back.

    Have you taken a look at the LittleFS example in Zephyr? I’ve also adopted it here. You can use the CONFIG_APP_WIPE_STORAGE to wipe everything out.

    If you can work with an isolated example first before integration. It saves some headaches. 🙂

      jaredwolff Thanks for the reply. I have tried CONFIG_APP_WIPE_STORAGE but it does not seem to work. After I execute flash_area_erase() the device still has all files and structure as it did before the erase and does not solve the problem I’m having. Also, is there a specific initialization or format process for littlefs?

      Perhaps I’m not initializing it properly…

      But that doesn’t make sense because I can create/write/open files all I want - onlymkdir fails.

      Here’s what I get when I just create files in /lfs:

      [00:00:00.217,071] .[0m<inf> littlefs: LittleFS version 2.2, disk version 2.0.[0m
      [00:00:00.218,017] .[0m<inf> littlefs: FS at W25Q32JV:0x0 is 8192 0x1000-byte blocks with 512 cycle.[0m
      [00:00:00.218,048] .[0m<inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32.[0m
      [00:00:00.232,360] .[0m<inf> littlefs: /lfs mounted.[0m
      [00:00:00.232,391] .[0m<inf> filesystem: Area 0 at 0x0 on W25Q32JV for 33554432 bytes.[0m
      [00:00:00.242,279] .[0m<inf> filesystem: /lfs: bsize = 16 ; frsize = 4096 ; blocks = 8192 ; bfree = 8190.[0m
      [00:00:00.247,589] .[0m<inf> filesystem: /lfs opendir: 0.[0m
      [00:00:00.256,835] .[0m<inf> filesystem:   F 47 19700101_000001.json.[0m
      [00:00:00.262,939] .[0m<inf> filesystem:     {distance_mm:1450,batt_mv:4166,batt_pptt:1000~.[0m
      [00:00:00.263,031] .[0m<inf> filesystem: End of files.[0m

        imoon So I’ve been playing with this and thus far my observations are:

        1. I can write to multiple files and recover their contents:
        /lfs mount: 0
        /lfs: bsize = 16 ; frsize = 4096 ; blocks = 8192 ; bfree = 8190
        
        /lfs/test0 stat: 0
        fn 'test0' siz 22
        /lfs/test0 {"test":0,"entry",:0}: 22
        /lfs/test0 seek start: 0
        /lfs/test0 close: 0
        /lfs/test1 stat: 0
        fn 'test1' siz 22
        /lfs/test1 {"test":1,"entry",:1}: 22
        /lfs/test1 seek start: 0
        /lfs/test1 close: 0
        /lfs/test2 stat: 0
        fn 'test2' siz 22
        /lfs/test2 {"test":2,"entry",:2}: 22
        /lfs/test2 seek start: 0
        /lfs/test2 close: 0
        /lfs/test3 stat: 0
        fn 'test3' siz 22
        /lfs/test3 {"test":3,"entry",:3}: 22
        /lfs/test3 seek start: 0
        /lfs/test3 close: 0
        /lfs/test4 stat: 0
        fn 'test4' siz 22
        /lfs/test4 {"test":4,"entry",:4}: 22
        /lfs/test4 seek start: 0
        /lfs/test4 close: 0
        /lfs/test5 stat: 0
        fn 'test5' siz 22
        /lfs/test5 {"test":5,"entry",:5}: 22
        /lfs/test5 seek start: 0
        /lfs/test5 close: 0
        /lfs/test6 stat: 0
        fn 'test6' siz 22
        /lfs/test6 {"test":6,"entry",:6}: 22
        /lfs/test6 seek start: 0
        /lfs/test6 close: 0
        /lfs/test7 stat: 0
        fn 'test7' siz 22
        /lfs/test7 {"test":7,"entry",:7}: 22
        /lfs/test7 seek start: 0
        /lfs/test7 close: 0
        /lfs/test8 stat: 0
        fn 'test8' siz 22
        /lfs/test8 {"test":8,"entry",:8}: 22
        /lfs/test8 seek start: 0
        /lfs/test8 close: 0
        /lfs/test9 stat: 0
        fn 'test9' siz 22
        /lfs/test9 {"test":9,"entry",:9}: 22
        /lfs/test9 seek start: 0
        /lfs/test9 close: 0
        1. One thing I did notice was that it failed erasing the volume with a -19 error. (ENODEV from errno.h)
        2020-11-22T18:31:09.666Z DEBUG modem << Erasing flash area ... -19
        2020-11-22T18:31:09.689Z DEBUG modem << [00:00:00.013,397] [0m<inf> littlefs: LittleFS version 2.2, disk version 2.0[0m
        2020-11-22T18:31:09.691Z DEBUG modem << [00:00:00.021,636] [0m<inf> littlefs: FS at W25Q32JV:0x0 is 8192 0x1000-byte blocks with 512 cycle[0m
        2020-11-22T18:31:09.693Z DEBUG modem << [00:00:00.030,914] [0m<inf> littlefs: sizes: rd 16 ; pr 16 ; ca 64 ; la 32[0m
        2020-11-22T18:31:09.722Z DEBUG modem << [00:00:00.054,199] [0m<inf> littlefs: /lfs mounted[0m

        So looking into it, it appears that the CONFIG_PM_EXTERNAL_FLASH_SIZE should be 0×400000. I had the value in bits which screwed everything up. Now full flash erases ok with no errors. I just pushed the example repository.

        2020-11-22T18:41:04.783Z DEBUG modem << *** Booting Zephyr OS build v2.3.0-rc1-ncs3  ***
        2020-11-22T18:41:04.785Z DEBUG modem << Area 0 at 0x0 on W25Q32JV for 33554432 bytes
        2020-11-22T18:41:05.236Z DEBUG modem << Erasing flash area ... 0

        Sorry for the delay on this @imoon

        Some other great resources when fiddling with the flash. (Hopefully you don’t have to after this.)

        jaredwolff

        Yes, I have this working now. Thank you!

        The flash erase is working properly now! Once I was able to do that I can now create directories without issue. To be honest, I don’t know what the root cause was but I suspect at some point, when I was playing around with having some file stuff in a thread, it got pre-empted and corrupted the filesystem somehow. I have no proof, but I had other issues using a thread for MQTT which failed randomly regardless of thread priority. Once I moved file and network handling back into main, my problems went away.

        This was really painful and I don’t fully understand it, but at least I now have a fully working app with LTE-M (on Rogers in Canada), MQTT, store-forward, PCF85063A RTC datetime set from NTP, deep sleep with PCF85063A timer wake-up, external 5V boost converter, and a TeraBee distance sensor on UART. Good times!

        Thanks for your help… I really love this board, you’ve done a great job with it.

        Cheers

        Thank you for sharing this all @imoon. It keeps me going for sure.

        I’m also thrilled everything that you wanted to get working is working. That’s a whole bunch of work right there for sure. 😁

        Please let me know if there’s anything else I can do to make your life easier with the nRF9160 Feather.

        Thanks again!

        Terms and Conditions | Privacy Policy