using SMP service with file system (lfs)

hello Nordic

i am using nrf52832 and nrf52840, working with ncs v2.3.0

currently i am using the SMP service for DFU but i also want to use the service's property to work directly with file system.

1. i saw a mention about security but if i have a secure connection (by second stage pairing), i am guessing the risk is not there right ?

2. in the following link and other places i looked i saw only read and wright commands, no delete option so my question is, what if i want to update/rewrite a file or, delete a file from file system, with the SMP service/ mcumgr, how can it be achieved ?

https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/device_mgmt/smp_groups/smp_group_8.html

https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/samples/subsys/mgmt/mcumgr/smp_svr/README.html

3. is there a minimal block/frame size to read/write to lfs, no only in limitation but in what size of frames is the data written to lfs and is it configurable ? 

 hope to read from you soon

best regards

Ziv

  • hi Hung

    It's because the system need to find where the file is located

    is it not saved on some map for file name and address or ptr in a small area in flash, seems very wastful other wise (also considering that up until ncs v2.5.0 fs upload/download using smp requires to open and close the file on each fs_mgmt event

    As file system it's normal that it has to do more reading than a simple one single read if you want to get the data out. 

    some overhead is reasonable but i am talking about a serious over head and the reading of all the file happen also at the write operation, after the file was already opened which does not make any sense, first because it is upload and not download and second cause it will get only few bytes to write in each fs_mgmt_upload event so how come it reads all the file again (after opening) ??

    (i added some prints in ncs "fs_mgmt_write" and  as can be seen in the code here , and added part of the rtt log as a file)

    /cfs-file/__key/communityserver-discussions-components-files/4/4456.canary_5F00_upload.txt

    static int fs_mgmt_write(const char *path, size_t offset,
    			 const void *data, size_t len)
    {
    	struct fs_file_t file;
    	int rc;
    	size_t file_size = 0;
    	LOG_INF("in fs_mgmt_write");
    	if (offset == 0) {
    		rc = fs_mgmt_filelen(path, &file_size);
    	}
    	LOG_INF("in fs_mgmt_write call fs_file_t_init");
    	fs_file_t_init(&file);
    	LOG_INF("in fs_mgmt_write call fs_open");
    	rc = fs_open(&file, path, FS_O_CREATE | FS_O_WRITE);
    	if (rc != 0) {
    		return MGMT_ERR_EUNKNOWN;
    	}
    
    	if (offset == 0 && file_size > 0) {
    		/* Offset is 0 and existing file exists with data, attempt to truncate the file
    		 * size to 0
    		 */
    		rc = fs_truncate(&file, 0);
    
    		if (rc == -ENOTSUP) {
    			/* Truncation not supported by filesystem, therefore close file, delete
    			 * it then re-open it
    			 */
    			fs_close(&file);
    
    			rc = fs_unlink(path);
    			if (rc < 0 && rc != -ENOENT) {
    				return rc;
    			}
    			LOG_INF("in fs_mgmt_write second call fs_open");
    			rc = fs_open(&file, path, FS_O_CREATE | FS_O_WRITE);
    		}
    
    		if (rc < 0) {
    			/* Failed to truncate file */
    			return MGMT_ERR_EUNKNOWN;
    		}
    	} else if (offset > 0) {
    		LOG_INF("in fs_mgmt_write call fs_seek");
    		rc = fs_seek(&file, offset, FS_SEEK_SET);
    		if (rc != 0) {
    			goto done;
    		}
    	}
    	LOG_INF("in fs_mgmt_write call fs_write");
    
    	rc = fs_write(&file, data, len);
    	if (rc < 0) {
    		goto done;
    	}

    * File operations */
    int fs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags)
    {
    	struct fs_mount_t *mp;
    	int rc = -EINVAL;
    
    	if ((file_name == NULL) ||
    			(strlen(file_name) <= 1) || (file_name[0] != '/')) {
    		LOG_ERR("invalid file name!!");
    		return -EINVAL;
    	}
    
    	if (zfp->mp != NULL) {
    		return -EBUSY;
    	}
    	LOG_INF("in fs_open call fs_get_mnt_point");
    
    	rc = fs_get_mnt_point(&mp, file_name, NULL);
    	if (rc < 0) {
    		LOG_ERR("mount point not found!!");
    		return rc;
    	}
    
    	if (((mp->flags & FS_MOUNT_FLAG_READ_ONLY) != 0) &&
    	    (flags & FS_O_CREATE || flags & FS_O_WRITE)) {
    		return -EROFS;
    	}
    
    	CHECKIF(mp->fs->open == NULL) {
    		return -ENOTSUP;
    	}
    	LOG_INF("in fs_open call mp->fs->open");
    	zfp->mp = mp;
    	rc = mp->fs->open(zfp, file_name, flags);
    	if (rc < 0) {
    		LOG_ERR("file open error (%d)", rc);
    		zfp->mp = NULL;
    		return rc;
    	}
    
    	/* Copy flags to zfp for use with other fs_ API calls */
    	zfp->flags = flags;
    
    	return rc;
    }

    best regards

    Ziv

  • Hi Ziv, 
    I don't have the insight on how exactly the file system in Zephyr works. But keeping a map file that need to be updated whenever you have a new file may wear the flash area that the map file is located. 

    Please be aware that we don't make the file system in Zephyr. I would suggest to check on Zephyr support channel as well. 
    Please continue in the ticket with Andreas. 

  • hi Hung

    OK, figured out the issue with the throughput and closed the mentioned thread. 

    one last question, hope you can help, one i finish the transfer of the file to my file system i need the received device to read it so it has to be in formed some how, i did not see a place for give some handler or a way to register for file upload done event or something like that. 

    any idea how i can get notified with in the device on the upload finish ?

    hope to read from you soon

    best regards

    Ziv 

  • Hi Ziv, 
    I dont have much experience with the SMP protocol, but have you looked at the specification ? 

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/device_mgmt/smp_groups/smp_group_8.html#mcumgr-smp-group-8

    When you upload a chunk you will receive a file upload response that tell at which offset it has received the file chunk. 

  • hi Hung

    it seems there is no event for upload done on the receiving side with the ncs

    (i wonder how to suggest to add one to zephyr)

    When you upload a chunk you will receive a file upload response that tell at which offset it has received the file chunk

    not sure i understand, this part of code is in the ncs and i don't think its a good practice to add my code there.

    maybe you know if there is an option to register for an event of fs_close() for specific file in lfs ?

    if not, maybe i can create an event and publish it with zbus ?

    what do you think ?

    hope to read from you soon

    best regards

    Ziv

Related