IO-Link data storage in the example project is based on the available FLASH memory connected via OSPI. More generally, any non-volatile random-access-memory (NVRAM) may be used by modifying the NVRAM driver.
On top of the hardware access functions, the open source file system LittleFS (https://github.com/littlefs-project/littlefs) is used in the example project and the NVRAM driver has to provide functions as expected by LittleFS.
The driver's interface is defined in
KBDrv/nvram_driver.h
and must remain untouched in order for the example to work, namely
extern struct lfs_config* NVR_DRV_init(const unsigned int instanceID, const unsigned int baseAdr); extern int NVR_DRV_fini(void);
However, the implentation in
KBDrv/nvram_driver.c
may be modified according the the underlying hardware. Functions with a type signature expected by LittleFS must be implemented to
from/to non-volatile memory. Please refer to the online LittleFS documentation and the example's nvram_driver.c
for a more detailed description. There the functions are called
static int NVR_DRV_s_read(const struct lfs_config *pCfg, lfs_block_t block, lfs_off_t off, void *pBuffer, lfs_size_t size); static int NVR_DRV_s_prog(const struct lfs_config *pCfg, lfs_block_t block, lfs_off_t off, const void *pBuffer, lfs_size_t size); static int NVR_DRV_s_erase(const struct lfs_config *pCfg, lfs_block_t block);
Finally these functions must be assigned to the corresponding members in a static LittleFS struct lfs_config
and returned by NVR_DRV_init()
like so:
static struct lfs_config lfscfg; extern struct lfs_config* NVR_DRV_init(const unsigned int instanceID, const unsigned int baseAdr) { // littleFS configuration // block device operations lfscfg.read = NVR_DRV_s_read; lfscfg.prog = NVR_DRV_s_prog; lfscfg.erase = NVR_DRV_s_erase; ... return &lfscfg; }
In the IO-Link master stack timing is an important issue. Writing to NVRAM can be slow, depending on the details of the hardware. In order to mitigate the issue, the IO-Link master example starts a separate task defined in iolm_work_task.c
which asynchroneously executes pending write requests in order to avoid blocking the program flow by slow memory access.
If users wants to use the filesystem for their own purposes it is recommended to use
IOLM_queueWriteNvram() IOLM_queueClearNvram()
declared in iolm_work_task.h
rather than
NVR_write() NVR_erase()
declared in nvram.h
.
Reading from NVRAM is assumed to be fast enough so that NVR_read() may be called directly.