填问卷,赢周边!Gemma 4 真实使用反馈征集
2026/5/13 10:50:34
将串口打印的日志,同时备份到sd卡里
#include <stdio.h> #include <unistd.h> #include <pthread.h> #include <string.h> #include <stdlib.h> #include <errno.h> static int pipe_fd[2] = {-1, -1}; static int stdout_backup = -1; static int stderr_backup = -1; static FILE *log_fp = NULL; static pthread_t log_tid; static int log_running = 0; void strip_ansi_and_write(FILE *fp, const char *buf, int len) { char clean[1024]; int j = 0; for (int i = 0; i < len; i++) { // ANSI 转义开始 if (buf[i] == 0x1B && buf[i + 1] == '[') { i += 2; // 跳过直到字母结束 while (i < len && ((buf[i] >= '0' && buf[i] <= '9') || buf[i] == ';')) { i++; } continue; } clean[j++] = buf[i]; if (j >= sizeof(clean) - 1) break; } fwrite(clean, 1, j, fp); } void *log_thread(void *arg) { char buf[512]; int n; while (log_running) { n = read(pipe_fd[0], buf, sizeof(buf)); if (n <= 0) { break; } // 输出到原串口 if (stdout_backup >= 0) { write(stdout_backup, buf, n); } // 写文件 if (log_fp) { strip_ansi_and_write(log_fp, buf, n); } } return NULL; } void log_redirect_init() { if (log_running) return; if (pipe(pipe_fd) < 0) { perror("pipe"); return; } stdout_backup = dup(STDOUT_FILENO); stderr_backup = dup(STDERR_FILENO); log_fp = fopen("/mnt/sdcard/ipc_dev.txt", "a+"); if (!log_fp) { perror("open log file failed"); } // 缓冲区大小 5KB setvbuf(log_fp, NULL, _IOFBF, 5*1024); dup2(pipe_fd[1], STDOUT_FILENO); dup2(pipe_fd[1], STDERR_FILENO); log_running = 1; pthread_create(&log_tid, NULL, log_thread, NULL); } void log_redirect_deinit() { if (!log_running) return; printf("log_redirect_deinit\n"); log_running = 0; // 恢复 stdout/stderr if (stdout_backup >= 0) { dup2(stdout_backup, STDOUT_FILENO); close(stdout_backup); stdout_backup = -1; } if (stderr_backup >= 0) { dup2(stderr_backup, STDERR_FILENO); close(stderr_backup); stderr_backup = -1; } // 关闭 pipe if (pipe_fd[0] >= 0) { close(pipe_fd[0]); pipe_fd[0] = -1; } if (pipe_fd[1] >= 0) { close(pipe_fd[1]); pipe_fd[1] = -1; } // 等待线程退出 pthread_join(log_tid, NULL); // 关闭文件 if (log_fp) { fflush(log_fp); fclose(log_fp); log_fp = NULL; } printf("log redirect stopped\n"); } //// 调用示例 if (sdcard_mounted) { // sd卡插上,将日志备份到 sd卡上 log_redirect_init(); } if (sdcard_removed) { // sd卡拔出,终止将日志备份到 sd卡上 log_redirect_deinit(); }