fs_write freezes app for 100+ ms

Hi,
    On nRF52840, on example https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/subsys/mgmt/mcumgr/smp_svr bluetooth stack configurations

    I am calling fs_write( less than 512bytes) and I have the main thread frozen for ~130ms.

    I tried calling fs_write from a different thread and I have now the main thread frozen for ~90ms:

static void saveFlashThread(void* p1, void* p2, void* p3)
{
    while(true)
    {
        k_msleep(10);

        if(flag)
        {
            flag = false;

            debugPinHighLow();
            fs_open(&file, path, FS_O_WRITE); 
            fs_write(&file, array, size);
            fs_close(&file);
            debugPinHighLow();
        }
    }
}

K_THREAD_DEFINE(saveFlashThreadId, 1024, saveFlashThread, NULL, NULL, NULL, 7, 0, 0);



static void mainThread()
{
...
    flag=true;
...

    while(true)
    {
        k_msleep(5);
        debugPinToggle();
        
        ...
    }
}


   Please kindly advise, you know of an asynchronous flash write function? Or is other way to write the thread so that fs_write() will not cause freeze in other threads?

   





  The curious thing is that only part of fs_write call is blocking: may you know if the low level function code is public? If yes, where can be found for board nRF52840?

ssize_t fs_write(struct fs_file_t *zfp, const void *ptr, size_t size)
{
...
    rc = zfp->mp->fs->write(zfp, ptr, size);



fs_file_system_t  /* File operations */
{
...
    ssize_t (*write)(struct fs_file_t *filp, const void *src, size_t nbytes);


Kind Regards,
Iulian

MSc.MEd. Software Engineer and Trainer
"But God demonstrates His own love for us in this: While we were still sinners, Christ died for us." (Romans 5:8)

Parents Reply Children
  • Hi Sigurd,
       Thank you: let me look into the link you sent

       I use the zephyr/fs/littlefs one:

     .dts file
    &flash {
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
            ...
    	
    		storage_partition: partition@XXXX {
    			label = "storage";
    			reg = <0xXXXX 0xXXXX>;
    		};
    	};
    };
    
    
    
     main.c file
    
    #ifdef CONFIG_MCUMGR_CMD_FS_MGMT
    FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage);
    static struct fs_mount_t littlefs_mnt = {
        .type        = FS_LITTLEFS,
        .fs_data     = &storage,
        .storage_dev = (void*)FIXED_PARTITION_ID(storage_partition),
        .mnt_point   = "/lfs"
    };
    #endif
    
    static struct fs_file_t file;
    
    void main(void)
    {
        /* Register the built-in mcumgr command handlers. */
    #ifdef CONFIG_MCUMGR_CMD_FS_MGMT
        fs_mgmt_register_group();
    
        int rc = fs_mount(&littlefs_mnt);
        if(rc < 0)
        {
            LOG_ERR("Error mounting littlefs [%d]", rc);
        }
    #endif
    
        fs_file_t_init(&file);
        fs_open(&file, path, FS_O_CREATE);
        fs_close(&file);
        
        ...
    }

      I use the nrf52840dk_nrf52840.overlay


    Kind Regards,
     Iulian




  • Hi Sigurd,
      Did not manage to reach far as had to jump on another task and when get back have to decide if to continue this path or look for alternative.

      The question is, on nrf52840, is possible to save 500 bytes to flash in a separate thread without freezing other threads at all (or no more than 2 milliseconds)?

    Kind Regards,
    Iulian

  • IulianI said:

      The question is, on nrf52840, is possible to save 500 bytes to flash in a separate thread without freezing other threads at all (or no more than 2 milliseconds)?

    I looked more into it, and I see that the CPU pauses when writing to flash.

    So if you have timing requirements, you could write less data at a time when writing to flash.
    Here you can see how much time it takes to write a 32 bit word to flash:

    Now how the data is written depends on how your file system does the writing: Does it write all with one command or with multiple?
    So maybe you have to just reduce the size you write at once.
    Or if you give the fs write thread low priority, and the file system writes in multiple blocks, the scheduler will fix the rest?

    An alternative could always be to use the NVMC drivers to do this manually in a low-prio thread to make sure you do not spend too much time.

  • Hi Sigurd,
      41us x my ~500 bytes = ~5ms: so then the rest ~100ms freeze might be caused just by erase?
      Is the lowest erase amount one page 85ms as per datasheet? So even with advised low priority threads, if the CPU pauses, my whole app will be frozen at least 85ms inevitably?

      If you have at hand a tiny example with ~500bytes erase + write (even in multiple calls if needed) for nRF52840 using bluetooth stack, please kindly advise the smallest app freeze possible in milliseconds you get on your side (kindly share that example too)

    Kind Regards,
    Iulian

Related