/****************************************************************************** 版权所有 (C), 2018-2099, Radkil ****************************************************************************** 文 件 名 : rd_stdio.c 版 本 号 : 初稿 作 者 : Radkil 生成日期 : 2026年3月11日星期三 最近修改 : 功能描述 : 标准IO的实现 修改历史 : 1.日 期 : 2026年3月11日星期三 作 者 : Radkil 修改内容 : 创建文件 ******************************************************************************/ #include "rd_stdio.h" #if LV_USE_FS_LITTLEFS #include "../../lvgl/lvgl.h" #endif /*----------------------------------------------* * 外部变量说明 * *----------------------------------------------*/ /*----------------------------------------------* * 外部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 内部函数原型说明 * *----------------------------------------------*/ /*----------------------------------------------* * 全局变量 * *----------------------------------------------*/ /*----------------------------------------------* * 模块级变量 * *----------------------------------------------*/ /*----------------------------------------------* * 常量定义 * *----------------------------------------------*/ /*----------------------------------------------* * 宏定义 * *----------------------------------------------*/ #ifdef USE_W25QXX #include "../littlefs/include/lfs.h" #include "../littlefs/include/lfs_flashbd.h" lfs_t g_lfs; lfs_flashbd_t g_bd; struct lfs_flashbd_config g_bd_cfg; struct lfs_config g_cfg; #endif #ifndef WIN32 WEAK void *Rd_Fopen(const char *path, const char *mode) { #ifdef USE_W25QXX #if LV_USE_FS_LITTLEFS lv_fs_mode_t lv_mode; if (strchr(mode, 'r') != NULL) lv_mode = LV_FS_MODE_RD; else lv_mode = LV_FS_MODE_WR; lv_fs_file_t *file = RD_MALLOC(sizeof(lv_fs_file_t)); if (NULL == file) return NULL; lv_fs_res_t res = lv_fs_open(file, path, lv_mode); if (LV_FS_RES_OK == res) { return (void *)file; } else { printf("%s[%d]fs errno is %d\n", __FILE__, __LINE__, res); return NULL; } #else const char *p = path; lfs_file_t *file = RD_MALLOC(sizeof(lfs_file_t)); int flags; if (strlen(path) >= 2 && path[1] == ':') p = path + 2; if (strchr(mode, 'r') != NULL) flags = LFS_O_RDONLY; else flags = LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC; int err = lfs_file_open(&g_lfs, file, p, flags); if(err) return NULL; else return (void *)file; #endif #endif return NULL; } WEAK void *Rd_Open(const char *path, int flags, mode_t mode) { return NULL; } WEAK ssize_t Rd_Mread(void *buf, size_t count, void *file) { #ifdef USE_W25QXX #if LV_USE_FS_LITTLEFS uint32_t size = 0; lv_fs_file_t *fp = (lv_fs_file_t *)file; lv_fs_res_t res = lv_fs_read(fp, buf, count, &size); if (LV_FS_RES_OK == res) { return (ssize_t)size; } else { printf("%s[%d]fs errno is %d\n", __FILE__, __LINE__, res); return RD_FAILURE; } #else lfs_ssize_t size = 0; lfs_file_t *fp = (lfs_file_t *)file; size = lfs_file_read(&g_lfs, fp, buf, count); if (size >= 0) { return (ssize_t)size; } else { printf("%s[%d]fs errno is %ld\n", __FILE__, __LINE__, size); return RD_FAILURE; } #endif #endif return RD_FAILURE; } WEAK ssize_t Rd_Mwrite(const void *buf, size_t count, void *file) { #ifdef USE_W25QXX #if LV_USE_FS_LITTLEFS uint32_t size = 0; lv_fs_file_t *fp = (lv_fs_file_t *)file; lv_fs_res_t res = lv_fs_write(fp, buf, count, &size); if (LV_FS_RES_OK == res) { return (ssize_t)size; } else { printf("%s[%d]fs errno is %d\n", __FILE__, __LINE__, res); return RD_FAILURE; } #else uint32_t size = 0; lfs_file_t *fp = (lfs_file_t *)file; size = lfs_file_write(&g_lfs, fp, buf, count); if (size >= 0) { return (ssize_t)size; } else { printf("%s[%d]fs errno is %ld\n", __FILE__, __LINE__, size); return RD_FAILURE; } #endif #endif return RD_FAILURE; } WEAK int Rd_Mclose(void *file) { #ifdef USE_W25QXX #if LV_USE_FS_LITTLEFS lv_fs_file_t *fp = (lv_fs_file_t *)file; lv_fs_close(fp); RD_FREE(file); return 0; #else lfs_file_t *fp = (lfs_file_t *)file; lfs_file_close(&g_lfs, fp); RD_FREE(file); return 0; #endif #endif return RD_FAILURE; } WEAK int Rd_Mseek(void *file, long offset, int whence) { #ifdef USE_W25QXX #if LV_USE_FS_LITTLEFS lv_fs_file_t *fp = (lv_fs_file_t *)file; lv_fs_whence_t lv_whence; if (SEEK_END == whence) lv_whence = LV_FS_SEEK_END; else if (SEEK_CUR == whence) lv_whence = LV_FS_SEEK_CUR; else lv_whence = LV_FS_SEEK_SET; lv_fs_res_t res = lv_fs_seek(fp, offset, lv_whence); if (LV_FS_RES_OK == res) { return offset; } else { printf("%s[%d]fs errno is %d\n", __FILE__, __LINE__, res); return RD_FAILURE; } #else lfs_file_t *fp = (lfs_file_t *)file; int flags; if (SEEK_END == whence) flags = LFS_SEEK_END; else if (SEEK_CUR == whence) flags = LFS_SEEK_CUR; else flags = LFS_SEEK_SET; int res = lfs_file_seek(&g_lfs, fp, offset, flags); if (res >= 0) { return offset; } else { printf("%s[%d]fs errno is %d\n", __FILE__, __LINE__, res); return RD_FAILURE; } #endif #endif return RD_FAILURE; } WEAK char *Rd_Mgets(char *buf, int size, void *file) { if (!file || !buf || size <= 0) return NULL; int i = 0; char c; while (i < size - 1) { ssize_t n = Rd_Mread(&c, 1, file); if (n != 0) { // 读到 EOF 或 错误(Rd_Mread 返回 0 表示读满请求的字节数) if (i == 0) return NULL; // 什么都没读到 break; // 读到了部分数据,也返回 } buf[i++] = c; if (c == '\n') break; // 遇到换行符停止 } buf[i] = '\0'; // 添加字符串结束符 return buf; } WEAK int Rd_Mputs(const char *str, void *file) { if (!file || !str) return RD_FAILURE; size_t len = RD_STRLEN(str); ssize_t written = Rd_Mwrite(str, len, file); return (written == (ssize_t)len) ? RD_SUCCESS : RD_FAILURE; } WEAK long Rd_Mtell(void *file) { #ifdef USE_W25QXX #if LV_USE_FS_LITTLEFS uint32_t pos = 0; lv_fs_file_t *fp = (lv_fs_file_t *)file; lv_fs_res_t res = lv_fs_tell(fp, &pos); if (LV_FS_RES_OK == res) { return pos; } else { printf("%s[%d]fs errno is %d\n", __FILE__, __LINE__, res); return RD_FAILURE; } #else lfs_file_t *fp = (lfs_file_t *)file; long pos = lfs_file_tell(&g_lfs, fp); if (pos >= 0) { return pos; } else { printf("%s[%d]fs errno is %ld\n", __FILE__, __LINE__, pos); return RD_FAILURE; } #endif #endif return RD_FAILURE; } WEAK int Rd_fflush(void *file) { return RD_SUCCESS; } WEAK int Rd_remove(const char *filename) { #ifdef USE_W25QXX const char *p = filename; if (strlen(filename) >= 2 && filename[1] == ':') p = filename + 2; int err = lfs_remove(&g_lfs, p); if (err) { printf("lfs_remove(%s) failed: %d\n", p, err); return RD_FAILURE; } return RD_SUCCESS; #else return RD_FAILURE; #endif } WEAK int Rd_rename(const char *oldpath, const char *newpath) { #ifdef USE_W25QXX const char *o = oldpath, *n = newpath; if (strlen(oldpath) >= 2 && oldpath[1] == ':') o = oldpath + 2; if (strlen(newpath) >= 2 && newpath[1] == ':') n = newpath + 2; int err = lfs_rename(&g_lfs, o, n); if (err) { printf("lfs_rename(%s,%s) failed: %d\n", o, n, err); return RD_FAILURE; } return RD_SUCCESS; #else return RD_FAILURE; #endif } WEAK void Rd_LittleFSInit(void) { #ifdef USE_W25QXX // 1MB = 256 个扇区,从地址 1M 开始全部使用,即前边空出1M留做他用(1*1024*1024表示空出1M,12*256表示使用12M空间) lfs_flashbd_default_config(&g_cfg, &g_bd, &g_bd_cfg, 1 * 1024 * 1024, 12 * 256, NULL, NULL, NULL); int err = lfs_mount(&g_lfs, &g_cfg); if (err) { printf("mount error format...\n"); lfs_format(&g_lfs, &g_cfg); lfs_mount(&g_lfs, &g_cfg); } return; #else return; #endif } WEAK void Rd_FatFSInit(void) { return; } #endif