Browse Source

【主线待合】增加tail命令,解决lfs初始化问题,修复Rd_Mgets

paint_robot_new-v1.5
Lizongdi 1 week ago
parent
commit
976b5fca05
  1. 33
      library/common/rd_stdio.c
  2. 86
      lua/lua.c

33
library/common/rd_stdio.c

@ -56,12 +56,14 @@ lfs_t g_lfs;
lfs_flashbd_t g_bd;
struct lfs_flashbd_config g_bd_cfg;
struct lfs_config g_cfg;
static uint8_t g_lfs_ready = 0; /* mount 成功后才允许读写,防止 mount 失败后继续写坏盘 */
#endif
#ifndef WIN32
WEAK void *Rd_Fopen(const char *path, const char *mode)
{
#ifdef USE_W25QXX
if (!g_lfs_ready) return NULL;
#if LV_USE_FS_LITTLEFS
lv_fs_mode_t lv_mode;
if (strchr(mode, 'r') != NULL) lv_mode = LV_FS_MODE_RD;
@ -144,6 +146,7 @@ WEAK ssize_t Rd_Mread(void *buf, size_t count, void *file)
WEAK ssize_t Rd_Mwrite(const void *buf, size_t count, void *file)
{
#ifdef USE_W25QXX
if (!g_lfs_ready) return RD_FAILURE;
#if LV_USE_FS_LITTLEFS
uint32_t size = 0;
lv_fs_file_t *fp = (lv_fs_file_t *)file;
@ -244,7 +247,7 @@ WEAK char *Rd_Mgets(char *buf, int size, void *file)
while (i < size - 1)
{
ssize_t n = Rd_Mread(&c, 1, file);
if (n != 0)
if (n != 1)
{
// 读到 EOF 或 错误(Rd_Mread 返回 0 表示读满请求的字节数)
if (i == 0) return NULL; // 什么都没读到
@ -334,6 +337,7 @@ WEAK int Rd_fflush(void *file)
WEAK int Rd_remove(const char *filename)
{
#ifdef USE_W25QXX
if (!g_lfs_ready) return RD_FAILURE;
const char *p = filename;
if (strlen(filename) >= 2 && filename[1] == ':') p = filename + 2;
int err = lfs_remove(&g_lfs, p);
@ -347,6 +351,7 @@ WEAK int Rd_remove(const char *filename)
WEAK int Rd_rename(const char *oldpath, const char *newpath)
{
#ifdef USE_W25QXX
if (!g_lfs_ready) return RD_FAILURE;
const char *o = oldpath, *n = newpath;
if (strlen(oldpath) >= 2 && oldpath[1] == ':') o = oldpath + 2;
if (strlen(newpath) >= 2 && newpath[1] == ':') n = newpath + 2;
@ -375,12 +380,32 @@ WEAK void Rd_LittleFSInit(void)
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)
if (err == LFS_ERR_CORRUPT)
{
printf("mount error format...\n");
(void)Rd_Lfs_Mount();
/* 只有真正的“无文件系统/损坏”才格式化;IO/内存错误格式化只会越弄越糟 */
printf("lfs: no fs / corrupt, formatting...\n");
err = lfs_format(&g_lfs, &g_cfg);
if (err == LFS_ERR_OK)
{
err = lfs_mount(&g_lfs, &g_cfg);
}
else
{
printf("lfs: format failed, err=%d\n", err);
}
}
else if (err != LFS_ERR_OK)
{
/* LFS_ERR_IO / LFS_ERR_NOMEM 等:不格式化,避免破坏已有数据 */
printf("lfs: mount failed, err=%d (not formatted)\n", err);
}
if (err != LFS_ERR_OK)
{
g_lfs_ready = 0;
return;
}
g_lfs_ready = 1;
#else
return;
#endif

86
lua/lua.c

@ -483,6 +483,91 @@ static int l_cat(lua_State *L)
return 0; /* 直接打印到终端,不再向 Lua 返回字符串 */
}
static int l_tail(lua_State *L)
{
const char *path = luaL_optstring(L, 1, "C:rd.log");
long n = luaL_optinteger(L, 2, 15);
long start_off = 0; /* 实际输出的起始偏移 */
long lines = 0; /* 文件总行数 */
if (n > 0)
{
/* 环形缓冲:只保留最近最多 n 行的行首偏移 */
long *off = (long *)RD_MALLOC(sizeof(long) * (size_t)n);
if (off == NULL)
{
lua_print("tail: out of memory\n");
return 0;
}
void *fp = Rd_Fopen(path, "r");
if (fp == NULL)
{
RD_FREE(off);
lua_print("tail: cannot open '%s'\n", path);
return 0;
}
/* 第一遍:像 l_cat 一样用 Rd_Mread 分块读取,
* 手动按字节跟踪偏移并记录每行行首偏移(避免使用有问题的 Rd_Mgets) */
long pos = 0; /* 当前已读到的文件偏移 */
int at_line_start = 1; /* 当前位置是否是一行的开头 */
char buf[128];
ssize_t m;
while ((m = Rd_Mread(buf, sizeof(buf), fp)) > 0)
{
int i;
for (i = 0; i < (int)m; i++)
{
if (at_line_start)
{
off[lines % n] = pos; /* 记录本行行首偏移 */
lines++;
at_line_start = 0;
}
pos++;
if (buf[i] == '\n')
at_line_start = 1;
}
}
Rd_Mclose(fp);
if (lines > 0)
{
long first = (lines <= n) ? 0 : (lines - n);
start_off = off[first % n];
}
RD_FREE(off);
}
else
{
return 0; /* n <= 0 时不输出 */
}
/* 第二遍:从 start_off 重新打开并打印到文件末尾 */
void *fp = Rd_Fopen(path, "r");
if (fp == NULL)
{
lua_print("tail: cannot open '%s'\n", path);
return 0;
}
if (Rd_Mseek(fp, start_off, SEEK_SET) < 0) /* Rd_Mseek 失败返回 -1 */
{
Rd_Mclose(fp);
return 0;
}
char buf[128];
ssize_t m;
while ((m = Rd_Mread(buf, sizeof(buf), fp)) > 0)
{
lua_print("%.*s", (int)m, buf);
}
Rd_Mclose(fp);
return 0;
}
static int l_mv(lua_State *L)
{
size_t len;
@ -582,6 +667,7 @@ static int luaopen_default(lua_State *L)
lua_register_help(L, "name", l_name, "Show build time");
lua_register_help(L, "echo", l_echo, "eg: echo(\"Hello\", \"C:a.txt\")");
lua_register_help(L, "cat", l_cat, "eg: cat(\"C:a.txt\")");
lua_register_help(L, "tail", l_tail, "eg: tail(\"C:rd.log\") tail(\"C:rd.log\", 30)");
lua_register_help(L, "mv", l_mv, "eg: mv(\"C:a.txt\", \"C:b.txt\")");
lua_register_help(L, "rm", l_rm, "eg: rm(\"C:a.txt\")");
lua_register_help(L, "ls", l_ls, "eg: ls()");

Loading…
Cancel
Save