#include "syscalls.h" #include "string.h" #include "stdint.h" #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "lfs_file.h" #include "bsp_print.h" #define PATH_MAX_LENTH 256 #define MAX_OPEN_FILES 8 #define FD_OFFSET 3 #if (__ARMCC_VERSION >= 6010050) /* 使用AC6编译器时 */ __asm(".global __use_no_semihosting\n\t"); /* 声明不使用半主机模式 */ __asm(".global __ARM_use_no_argv \n\t"); /* AC6下需要声明main函数为无参数格式,否则部分例程可能出现半主机模式 */ #else /* 使用AC5编译器时, 要在这里定义__FILE 和 不使用半主机模式 */ #pragma import(__use_no_semihosting) struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; #endif #define STDIN 0 #define STDOUT 1 #define STDERR 2 typedef struct{ lfs_file_t *ptr; char path[PATH_MAX_LENTH]; uint8_t in_use; }fd_map_t; static fd_map_t s_fd_map[MAX_OPEN_FILES] = {0}; static SemaphoreHandle_t s_fd_mutex = NULL; const char __stdin_name[] = "STDIN"; const char __stdout_name[] = "STDOUT"; const char __stderr_name[] = "STDERR"; int _sys_open(const char *name, int openmode) { int mode = 0; /* Register standard Input Output devices. */ if (strcmp(name, __stdin_name) == 0) return (STDIN); if (strcmp(name, __stdout_name) == 0) return (STDOUT); if (strcmp(name, __stderr_name) == 0) return (STDERR); if (openmode & OPEN_PLUS) { if (openmode & OPEN_W) { mode |= (LFS_O_RDWR | LFS_O_TRUNC | LFS_O_CREAT); } else if (openmode & OPEN_A) { mode |= (LFS_O_RDWR | LFS_O_APPEND | LFS_O_CREAT); } else mode |= LFS_O_RDWR; } else { if (openmode & OPEN_W) { mode |= (LFS_O_WRONLY | LFS_O_TRUNC | LFS_O_CREAT); } else if (openmode & OPEN_A) { mode |= (LFS_O_WRONLY | LFS_O_APPEND | LFS_O_CREAT); } } int index = -1; for (int i = 0; i < MAX_OPEN_FILES; i++) { if (!s_fd_map[i].in_use) { index = i; break; } } if(index == -1) return -1; lfs_file_t *fp = l_open(name,mode); if(fp == NULL) return -1; strcpy(s_fd_map[index].path,name); s_fd_map[index].ptr = fp; s_fd_map[index].in_use = 1; return index + FD_OFFSET; } int _sys_close(int fd) { int index = fd - FD_OFFSET; if (index < 0 || index >= MAX_OPEN_FILES) { return -1; } if (!s_fd_map[index].in_use) { return -1; } lfs_file_t *fp = s_fd_map[index].ptr; l_close(fp); s_fd_map[index].in_use = 0; memset(s_fd_map[index].path,0,128); s_fd_map[index].ptr = NULL; return 0; } int _sys_write(FILEHANDLE fh, const unsigned char *buf, size_t count,int mode) { int size = 0; if (fh == STDOUT || fh == STDERR) { fr_printf("%s\r\n",buf); return 0; }else if(fh == STDIN) { return -1; }else { int index = fh - FD_OFFSET; if (index < 0 || index >= MAX_OPEN_FILES) { return -1; } if (!s_fd_map[index].in_use) { return -1; } lfs_file_t *fp = s_fd_map[index].ptr; int ret = l_write(fp,buf,count); if(ret >= 0) { l_sync(fp); ret = count - ret; } else return ret; } } int _sys_read(int fh,unsigned char *buf, unsigned int count,int mode) { int size = 0; if (fh == STDOUT || fh == STDERR) { //printf("%s\r\n",buf); return -1; }else if(fh == STDIN) { return -1; }else { int index = fh - FD_OFFSET; if (index < 0 || index >= MAX_OPEN_FILES) { return -1; } if (!s_fd_map[index].in_use) { return -1; } lfs_file_t *fp = s_fd_map[index].ptr; int ret = l_read(fp,buf,count); if(ret >= 0) { ret = count - ret; }else ret = 0; return ret; } } int _sys_ensure(int fh) { return -1; } int _sys_seek(int fh, long pos) { if (fh < STDERR) return 0; int index = fh - FD_OFFSET; if (index < 0 || index >= MAX_OPEN_FILES) { return -1; } if (!s_fd_map[index].in_use) { return -1; } lfs_file_t *fp = s_fd_map[index].ptr; return l_seek(fp,pos,0); } #if __ARMCC_VERSION >= 6190000 void _sys_tmpnam(char *name, int fileno, unsigned maxlength) { rt_snprintf(name, maxlength, "tem%03d", fileno); } #else int _sys_tmpnam(char *name, int fileno, unsigned maxlength) { fr_printf(name, maxlength, "tem%03d", fileno); return 1; } #endif /* __ARMCC_VERSION >= 6190000 */ long _sys_flen(int fh) { if (fh < STDERR) return 0; /* error */ int index = fh - FD_OFFSET; if (index < 0 || index >= MAX_OPEN_FILES) { return -1; } if (!s_fd_map[index].in_use) { return -1; } //lfs_file_t *fp = s_fd_map[index].ptr; size_t size = 0; l_stat(s_fd_map[index].path,&size); return size; } int _sys_istty(int fh) { if ((STDIN <= fh) && (fh <= STDERR)) return 1; else return 0; } weak void _sys_exit(int return_code) { while (1); } int _sys_remove(const char *filename) { for(int index = 0; index < MAX_OPEN_FILES;index ++) { if(strcmp(s_fd_map[index].path,filename) == 0) { //close lfs_file_t *fp = s_fd_map[index].ptr; l_close(fp); s_fd_map[index].ptr = NULL; s_fd_map[index].in_use = 0; memset(s_fd_map[index].path,0,PATH_MAX_LENTH); break; } } return l_remove(filename); } int remove(const char *filename) { for(int index = 0; index < MAX_OPEN_FILES;index ++) { if(strcmp(s_fd_map[index].path,filename) == 0) { //close lfs_file_t *fp = s_fd_map[index].ptr; l_close(fp); s_fd_map[index].ptr = NULL; s_fd_map[index].in_use = 0; memset(s_fd_map[index].path,0,PATH_MAX_LENTH); break; } } return l_remove(filename); } int rename(const char *old_file, const char *new_file) { int result; if (old_file == NULL || new_file == NULL) { return -1; } for(int index = 0; index < MAX_OPEN_FILES;index ++) { if(strcmp(s_fd_map[index].path,old_file) == 0) { //close return -1; } } result = l_rename(old_file, new_file); if (result < 0) { return -1; } return 0; } int mkdir(const char *path, int mode) { size_t size = 0; if (path == NULL) { return -1; } int type = l_stat(path,&size); if(type >= 0) { return -1; } l_mkdir(path); return 0; }