1、经常会碰到一些可移植代码使用c的file相关操作函数;
2、file这些一般在有操作系统和文件管理系统的程序运行,如果是简易MCU是不支持这些
3、如何快速替换这些函数呢,可以考虑使用数组操作替换这些接口函数,或者直接操作指针
我整理了一下我的替换接口,注意只能单线程运行,参考如下:
#include "usr_file.h"
#include "string.h"
//下面几个可以在头文件定义
#define FILE unsigned char
#define fopen(file,attr) g_aje_file //g_aje_file是定义的file *指针
#define fclose(file)
//stdio.h
#define EOF (-1)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define File_OFFSET_BASE 0x0000 //file存储在flash首地址,或者数组的首地址
#define Size_File 128*1024 //存储的文件大小,注意定义为有符号数
extern FILE* g_aje_file; //操作file的指针
int fgetc(FILE * file)
{
int byte = *((volatile unsigned char*)(g_aje_file));
g_aje_file = ((unsigned char*)g_aje_file)+1; //先这样+,看能否读
if ((unsigned long)(g_aje_file) >= (File_OFFSET_BASE + Size_File)) return -1; //超过文件存储区域了
return byte;
}
char *fgets(char *str, int num, FILE *stream)
{
if (g_aje_file == NULL || num <= 0 || str == NULL)
return NULL;
char *ptr = str;
// size_t remaining = num - 1;
unsigned short i = 0;
for (i = 0; i < num - 1; i++)
{
unsigned char ch = *((volatile unsigned char*)(g_aje_file));
*ptr++ = ch;
(volatile unsigned char*)(g_aje_file)++;
if (ch == '\n') {
break;
}
}
if ((unsigned long)(g_aje_file) >= (File_OFFSET_BASE + Size_File)) return NULL;
*ptr = '\0';
if (str == ptr) {
return NULL;
}
return str;
// u16 i = 0;
// for (i = 0; i < n - 1; i++)
// {
// str[i] = *((volatile u8*)(stream + i));
// if ((str[i] == EOF))
// {
// return NULL;
// }
// }
}
long int ftell(FILE* file)
{
if ((unsigned long)g_aje_file >= (File_OFFSET_BASE + Size_File)) return -1;
return ((unsigned long)g_aje_file - File_OFFSET_BASE);
}
int fseek(FILE* stream, long int offset, int whence)
{
if (g_aje_file == NULL /*|| stream->buffer == NULL*/)
return -1;
switch (whence) {
case SEEK_SET:
if (offset <0 || offset >(Size_File))
return -1;
g_aje_file = (FILE*)(offset + File_OFFSET_BASE);
break;
case SEEK_CUR:
if (((unsigned long)(g_aje_file + offset) <File_OFFSET_BASE) || ((unsigned long)(g_aje_file + offset) >(File_OFFSET_BASE + Size_File))/*(offset >(Size_File))*/)
return -1;
g_aje_file += offset;
break;
case SEEK_END:
if (offset > 0 || (unsigned long)(g_aje_file + offset) < File_OFFSET_BASE)
return -1;
g_aje_file = (FILE*)(File_OFFSET_BASE + Size_File + offset); //并不是实际文件的末尾,是存这个文件flash地址的最尾端的值
break;
default:
return -1;
}
return 0;
}
int feof(FILE* stream)
{
if ((unsigned long)g_aje_file >= (File_OFFSET_BASE + Size_File)) return -1;
if ((unsigned long)g_aje_file >= (File_OFFSET_BASE + Size_File - 1)) {
return 1;
}
return 0;
}
只替换了我需要使用的几个函数,其他的可参考类似的编写;
注意,需要将原先源文件中调用的stdio.h都屏蔽掉,不然多重定义;
或者将所有接口都重命名
还有一篇可参考:https://www.cnblogs.com/sureZ-learning/p/18598154#29-fseek
2728

被折叠的 条评论
为什么被折叠?



