168 lines
4.4 KiB
C
168 lines
4.4 KiB
C
//
|
|
// Created by cfif on 29.05.2024.
|
|
//
|
|
#include "LittleFsInterface.h"
|
|
#include "InternalFlashPage.h"
|
|
|
|
#define FLASH_BASE ((uint32_t)0x04000000)
|
|
#define FLASH_START_SECTOR ((uint32_t)0x10000 / FLASH_PAGE_D_SIZE)
|
|
#define FLASH_STOP_SECTOR ((uint32_t)0x1F000 / FLASH_PAGE_D_SIZE)
|
|
|
|
// Read a region in a block. Negative error codes are propagated
|
|
// to the user.
|
|
int readFlash(const struct lfs_config *c, lfs_block_t block,
|
|
lfs_off_t off, void *buffer, lfs_size_t size) {
|
|
|
|
uint32_t sectorAdr = (FLASH_START_SECTOR + block) * FLASH_PAGE_D_SIZE + off + FLASH_BASE;
|
|
|
|
for (uint32_t i = 0; i < size; ++i) {
|
|
((uint8_t *) buffer)[i] = *(uint8_t *) sectorAdr;
|
|
++sectorAdr;
|
|
}
|
|
|
|
return LFS_ERR_OK;
|
|
}
|
|
|
|
|
|
// Program a region in a block. The block must have previously
|
|
// been erased. Negative error codes are propagated to the user.
|
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
|
int progFlash(const struct lfs_config *c, lfs_block_t block,
|
|
lfs_off_t off, const void *buffer, lfs_size_t size) {
|
|
|
|
uint32_t sectorAdr = (FLASH_START_SECTOR + block) * FLASH_PAGE_D_SIZE + off + FLASH_BASE;
|
|
|
|
if (D_bInternalFlashPage_WriteFromRam(sectorAdr, (void *)buffer, size) == false) {
|
|
return LFS_ERR_IO;
|
|
}
|
|
/*
|
|
flash_unlock();
|
|
|
|
for (uint32_t i = 0; i < size; ++i) {
|
|
if (FLASH_OPERATE_DONE != flash_byte_program(sectorAdr + i, ((uint8_t *) buffer)[i])) {
|
|
flash_lock();
|
|
return LFS_ERR_IO;
|
|
}
|
|
}
|
|
|
|
flash_lock();
|
|
*/
|
|
|
|
return LFS_ERR_OK;
|
|
}
|
|
|
|
|
|
// Erase a block. A block must be erased before being programmed.
|
|
// The state of an erased block is undefined. Negative error codes
|
|
// are propagated to the user.
|
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
|
int eraseFlash(const struct lfs_config *c, lfs_block_t block) {
|
|
|
|
uint32_t sectorAdr = (FLASH_START_SECTOR + block) * FLASH_PAGE_D_SIZE + FLASH_BASE;
|
|
|
|
if (D_bInternalFlashPage_Clear(sectorAdr, NULL, NULL) == false) {
|
|
return LFS_ERR_IO;
|
|
}
|
|
|
|
/*
|
|
flash_unlock();
|
|
|
|
if (FLASH_OPERATE_DONE != flash_sector_erase(sectorAdr)) {
|
|
flash_lock();
|
|
return LFS_ERR_IO;
|
|
}
|
|
|
|
flash_lock();
|
|
*/
|
|
|
|
return LFS_ERR_OK;
|
|
}
|
|
|
|
// Sync the state of the underlying block device. Negative error codes
|
|
// are propagated to the user.
|
|
int syncFlash(const struct lfs_config *c) {
|
|
|
|
return LFS_ERR_OK;
|
|
}
|
|
|
|
|
|
osMutexId_t accessDumperLittleFS;
|
|
|
|
// Lock the underlying block device. Negative error codes
|
|
// are propagated to the user.
|
|
int lockFlash(const struct lfs_config *c) {
|
|
|
|
if (osMutexAcquire(accessDumperLittleFS, 5000) == osOK)
|
|
return LFS_ERR_OK;
|
|
|
|
return LFS_ERR_IO;
|
|
}
|
|
|
|
// Unlock the underlying block device. Negative error codes
|
|
// are propagated to the user.
|
|
int unlockFlash(const struct lfs_config *c) {
|
|
|
|
if (osMutexRelease(accessDumperLittleFS) == osOK)
|
|
return LFS_ERR_OK;
|
|
|
|
return LFS_ERR_IO;
|
|
}
|
|
|
|
#define LFS_CACHE_SIZE (2048)
|
|
#define LFS_LOOK_HEAD_SIZE (256)
|
|
|
|
#ifdef LFS_NO_MALLOC
|
|
uint8_t readBuffer[LFS_CACHE_SIZE];
|
|
uint8_t writeBuffer[LFS_CACHE_SIZE];
|
|
uint8_t lookBuffer[LFS_LOOK_HEAD_SIZE];
|
|
uint8_t g_file_buffer[LFS_CACHE_SIZE];
|
|
#endif
|
|
|
|
int lfs_init_Over(lfs_t *lfs, const struct lfs_config *cfg);
|
|
|
|
|
|
int LittleFileFsInit(tLittleFileFs *env, osMutexId_t accessDumper) {
|
|
|
|
accessDumperLittleFS = accessDumper;
|
|
|
|
env->cfg.read = readFlash;
|
|
env->cfg.prog = progFlash;
|
|
env->cfg.erase = eraseFlash;
|
|
env->cfg.sync = syncFlash;
|
|
env->cfg.lock = lockFlash;
|
|
env->cfg.unlock = unlockFlash;
|
|
|
|
// block device configuration
|
|
env->cfg.read_size = LFS_CACHE_SIZE;
|
|
env->cfg.prog_size = LFS_CACHE_SIZE;
|
|
env->cfg.block_size = FLASH_PAGE_D_SIZE;
|
|
env->cfg.block_count = FLASH_STOP_SECTOR - FLASH_START_SECTOR;
|
|
env->cfg.cache_size = LFS_CACHE_SIZE;
|
|
env->cfg.lookahead_size = LFS_LOOK_HEAD_SIZE;
|
|
env->cfg.block_cycles = 100;
|
|
|
|
#ifdef LFS_NO_MALLOC
|
|
env->cfg.read_buffer = readBuffer;
|
|
env->cfg.prog_buffer = writeBuffer;
|
|
env->cfg.lookahead_buffer = lookBuffer;
|
|
|
|
env->g_file_cfg.buffer = g_file_buffer;
|
|
#endif
|
|
int err;
|
|
|
|
err = lfs_init_Over(&env->lfs, &env->cfg);
|
|
|
|
// err = lfs_format(&env->lfs, &env->cfg);
|
|
|
|
// mount the filesystem
|
|
err = lfs_mount(&env->lfs, &env->cfg);
|
|
|
|
// reformat if we can't mount the filesystem
|
|
// this should only happen on the first boot
|
|
if (err != 0) {
|
|
err = lfs_format(&env->lfs, &env->cfg);
|
|
err = lfs_mount(&env->lfs, &env->cfg);
|
|
}
|
|
|
|
return err;
|
|
} |