#include #include #include #include #include "aem_platform.h" #include "aem_log.h" #include "aem_adapter_err_if.h" #include "aem_adapter_flash.h" #include "sys_wakelock.h" #define APP_DATA_PARTITION_NAME CONFIG_APP_FAT_DISK static ssize_t aem_fs_write(const char *pname, uint32_t offset, const uint8_t *buff, size_t size) { char file_name[50] = {0}; struct fs_file_t zfp = {0}; ssize_t ret_val = 0; snprintf(file_name, sizeof(file_name), "%s/%s", APP_DATA_PARTITION_NAME, pname); fs_mode_t flags = FS_O_RDWR | FS_O_CREATE; fs_file_t_init(&zfp); if (fs_open(&zfp, file_name, flags) != 0) { AEM_LOG_E("write open file (%s) faile\n", file_name); return -ENOENT; } AEM_LOG_I("write open file (%s) ok\n", file_name); fs_seek(&zfp, 0, FS_SEEK_END); off_t file_size = fs_tell(&zfp); if (offset > file_size) { uint32_t fill_size = offset - file_size; uint32_t fill_offset = 0; uint16_t fill_size_once = 4096; // 每次写4K AEM_LOG_I("file fill data: %d, offset: %d, file_size: %d\n", fill_size, offset, (int)file_size); char *pfill = aem_malloc(fill_size_once); if (pfill == NULL) { AEM_LOG_E("malloc fill mem\n"); ret_val = -ENOMEM; goto fs_write_end; } aem_memset(pfill, 0xFF, fill_size_once); // 填充空数据 while (fill_size > fill_offset) { if ((fill_size - fill_offset) < fill_size_once) { fill_size_once = fill_size - fill_offset; } ssize_t temp = fs_write(&zfp, pfill, fill_size_once); if (temp != fill_size_once) { AEM_LOG_E("temp = %d,file_size_once = %d fs_write fill data\n", temp, fill_size_once); ret_val = -EAGAIN; aem_free(pfill); goto fs_write_end; } fill_offset += fill_size_once; } aem_free(pfill); } if (fs_seek(&zfp, offset, FS_SEEK_SET) < 0) { AEM_LOG_E("open fs_seek, offset: %d\n", offset); ret_val = -ESPIPE; goto fs_write_end; } ret_val = fs_write(&zfp, buff, size); if (ret_val != size) { AEM_LOG_E("fs_write, size: %d, ret_val: %d\n", size, ret_val); ret_val = -EAGAIN; goto fs_write_end; } fs_seek(&zfp, 0, FS_SEEK_END); off_t new_file_size = fs_tell(&zfp); if (file_size < new_file_size) { AEM_LOG_I("fs_write, file_size : %ld, new_file_size: %ld\n", file_size, new_file_size); } fs_write_end: AEM_LOG_I("fs_write end\n"); fs_close(&zfp); AEM_LOG_I("fs_write ret\n"); return ret_val; } uint32_t flash_write(const char *name, uint32_t offset, void *data, uint32_t size) { if (NULL == name) { return AEM_ADAPTER_ERR_PARAM_NULL; } sys_wake_lock(PARTIAL_WAKE_LOCK); ssize_t w_size = aem_fs_write(name, offset, data, size); sys_wake_unlock(PARTIAL_WAKE_LOCK); if (w_size >= 0) { return AEM_ADAPTER_OK; } return AEM_ADAPTER_ERR_INVALID_DATA; } static size_t aem_fs_read(const char *pname, uint32_t offset, uint8_t *buff, size_t size) { char file_name[50] = {0}; struct fs_file_t fd = {0}; ssize_t ret_val = 0; snprintf(file_name, sizeof(file_name), "%s/%s", APP_DATA_PARTITION_NAME, pname); fs_mode_t flags = FS_O_RDWR; fs_file_t_init(&fd); if (fs_open(&fd, file_name, flags) != 0) { AEM_LOG_E("read open file (%s) faile\n", file_name); return -ENOENT; } AEM_LOG_I("read open file (%s) ok\n", file_name); fs_seek(&fd, 0, FS_SEEK_END); off_t file_size = fs_tell(&fd); if (offset > file_size) { AEM_LOG_E("read offset is big then file\n"); ret_val = -ESPIPE; goto fs_read_end; } if (fs_seek(&fd, offset, FS_SEEK_SET) < 0) { AEM_LOG_E("read fs_seek err, offset: %d\n", offset); ret_val = -ESPIPE; goto fs_read_end; } ret_val = fs_read(&fd, buff, size); if (ret_val != size) { memset(buff, 0, size); AEM_LOG_E("fs_read, size: %d, ret_val: %d\n", size, ret_val); ret_val = -EAGAIN; goto fs_read_end; } fs_read_end: fs_close(&fd); return ret_val; } static int aem_fs_delete(const char *pname) { char file_name[50] = {0}; struct fs_file_t fd = {0}; int ret_val = 0; snprintf(file_name, sizeof(file_name), "%s/%s", APP_DATA_PARTITION_NAME, pname); fs_mode_t flags = FS_O_RDWR; AEM_LOG_I("delete file (%s) \n", file_name); ret_val = fs_unlink(file_name); if (ret_val != 0) { AEM_LOG_W("delete file (%s) fail ret(%d)\r\n", file_name, ret_val); } return ret_val; } uint32_t flash_read(const char *name, uint32_t offset, void *data, uint32_t size) { if (name == NULL) { return AEM_ADAPTER_ERR_PARAM_NULL; } sys_wake_lock(PARTIAL_WAKE_LOCK); ssize_t r_size = aem_fs_read(name, offset, data, size); sys_wake_unlock(PARTIAL_WAKE_LOCK); if (r_size == -EAGAIN || r_size >= 0) { return AEM_ADAPTER_OK; } return AEM_ADAPTER_ERR_INVALID_DATA; } static uint32_t flash_erase(const char *name) { if (name == NULL) { return AEM_ADAPTER_ERR_PARAM_NULL; } sys_wake_lock(PARTIAL_WAKE_LOCK); int ret = aem_fs_delete(name); sys_wake_unlock(PARTIAL_WAKE_LOCK); if (ret != 0) { return AEM_ADAPTER_ERR_INTERNAL; } return AEM_ADAPTER_OK; } static const aem_flash_ops_t s_flash_ops = { .flash_read = flash_read, .flash_write = flash_write, .flash_erase = flash_erase, }; const aem_flash_ops_t *aem_get_flash_ops(void) { return &s_flash_ops; }