912 lines
15 KiB
C
912 lines
15 KiB
C
|
||
/*
|
||
|
||
C语言库函数实现
|
||
|
||
*/
|
||
|
||
|
||
#include "stdio.h"
|
||
#include "ff.h"
|
||
#include "errno.h"
|
||
#include "stdlib.h"
|
||
#include "string.h"
|
||
#include "libc.h"
|
||
#include "flash_manager.h"
|
||
#include "bsp_init.h"
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 常规文件
|
||
#define FILE_TYPE_FILE 0
|
||
// 设备文件
|
||
#define FILE_TYPE_DEVICE 1
|
||
// 内存文件
|
||
#define FILE_TYPE_MEM 2
|
||
|
||
// 定义内存文件大小
|
||
#define MEM_FILE_SIZE (100*1024)
|
||
|
||
|
||
|
||
// 定义flash中的文件
|
||
typedef struct
|
||
{
|
||
u32 addr;
|
||
u32 ptr;
|
||
u32 size;
|
||
}libc_flash_file;
|
||
|
||
|
||
// 定义常规文件
|
||
typedef struct
|
||
{
|
||
libc_flash_file flash;
|
||
FILINFO file_info;
|
||
FIL file;
|
||
|
||
}file_struct_private;
|
||
|
||
|
||
|
||
|
||
|
||
// 定义内存文件
|
||
typedef struct
|
||
{
|
||
uint8_t data[MEM_FILE_SIZE];
|
||
int size;
|
||
int ptr;
|
||
}libc_mem_file;
|
||
|
||
|
||
|
||
// 定义文件结构体
|
||
struct __FILE
|
||
{
|
||
int type;
|
||
file_struct_private *ptr;
|
||
const libc_device_file *dev;
|
||
libc_mem_file *mem;
|
||
};
|
||
|
||
// 寻找指定名称的设备
|
||
extern const unsigned int Load$$libc_dev$$Base;
|
||
extern const unsigned int Load$$libc_dev$$Limit;
|
||
const libc_device_file *libc_find_dev(const char *name)
|
||
{
|
||
libc_device_file *start=(libc_device_file *)&Load$$libc_dev$$Base;
|
||
libc_device_file *end=(libc_device_file *)&Load$$libc_dev$$Limit;
|
||
|
||
libc_device_file *ptr=0;
|
||
for(ptr=start;ptr<end;ptr++)
|
||
{
|
||
if(strcmp(ptr->name,name)==0)
|
||
return ptr;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
|
||
|
||
// 基本输入输出流
|
||
FILE __stdin={
|
||
.type=FILE_TYPE_DEVICE,
|
||
.dev=0,
|
||
};
|
||
FILE __stdout={
|
||
.type=FILE_TYPE_DEVICE,
|
||
.dev=0,
|
||
};
|
||
FILE __stderr={
|
||
.type=FILE_TYPE_DEVICE,
|
||
.dev=0,
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
static int libc_init(void)
|
||
{
|
||
freopen("usart","r+",stdin);
|
||
freopen("usart","r+",stdout);
|
||
freopen("usart","r+",stderr);
|
||
return 0;
|
||
}
|
||
|
||
extern_init(libc,libc_init);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 删除文件,返回0成功
|
||
int remove(const char * filename)
|
||
{
|
||
if (f_unlink(filename)==FR_OK)
|
||
return 0;
|
||
else
|
||
return -1;
|
||
}
|
||
|
||
|
||
|
||
//重命名,返回0成功
|
||
int rename(const char * old_, const char * new_)
|
||
{
|
||
if (f_rename (old_,new_)==FR_OK)
|
||
return 0;
|
||
else
|
||
return -1;
|
||
}
|
||
|
||
|
||
// 在指定流上创建临时文件
|
||
static FILE *tmpfile_s(FILE * stream)
|
||
{
|
||
FILE *file=stream;
|
||
if(file==NULL) file=calloc (1,sizeof (FILE));
|
||
file->type=FILE_TYPE_MEM;
|
||
|
||
file->mem=calloc(1,sizeof(libc_mem_file));
|
||
file->mem->size=MEM_FILE_SIZE;
|
||
|
||
return file;
|
||
}
|
||
|
||
// 创建临时文件,在文件关闭时自动删除
|
||
FILE *tmpfile(void)
|
||
{
|
||
return tmpfile_s(NULL);
|
||
}
|
||
|
||
|
||
// 返回一个和现有文件名不同的字符串,这里始终返回 NULL
|
||
char *tmpnam(char * s)
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
|
||
// 关闭文件,返回0成功
|
||
int fclose(FILE * stream)
|
||
{
|
||
FILE * file=stream;
|
||
if (file)
|
||
{
|
||
if(file->ptr)
|
||
{
|
||
if (file->ptr->flash.size==0)
|
||
f_close(&file->ptr->file);
|
||
free(file->ptr);
|
||
file->ptr=NULL;
|
||
}
|
||
if(file->mem)
|
||
{
|
||
free(file->mem);
|
||
file->mem=NULL;
|
||
}
|
||
if(file->dev)
|
||
{
|
||
if(file->dev->close)
|
||
file->dev->close();
|
||
file->dev=NULL;
|
||
}
|
||
if((file!=stdin)&&(file!=stdout)&&(file!=stderr))
|
||
{
|
||
// 基本输入输出流使用的是静态内存
|
||
free(file);
|
||
}
|
||
else
|
||
{
|
||
// 设置为初始流设备
|
||
// freopen("uart5","r+",file);
|
||
}
|
||
return 0;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
// 刷新,返回0成功
|
||
int fflush(FILE * stream)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
int ferror(FILE * stream)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
// 由字符得到打开类型
|
||
static BYTE f_get_mode(const char *mode)
|
||
{
|
||
typedef struct{
|
||
const char *mode;
|
||
BYTE mb;
|
||
}m_item;
|
||
|
||
m_item items[]={
|
||
{"r",FA_READ},//open text file for reading
|
||
{"w",FA_WRITE},//create text file for writing, or truncate to zero length
|
||
{"a",FA_OPEN_ALWAYS|FA_OPEN_APPEND|FA_WRITE},//append; open text file or create for writing at eof
|
||
{"rb",FA_READ},//open binary file for reading
|
||
{"wb",FA_WRITE},//create binary file for writing, or truncate to zero length
|
||
{"ab",FA_OPEN_ALWAYS|FA_OPEN_APPEND|FA_WRITE},//append; open binary file or create for writing at eof
|
||
{"r+",FA_READ|FA_WRITE},//open text file for update (reading and writing)
|
||
{"w+",FA_CREATE_NEW|FA_READ|FA_WRITE},//create text file for update, or truncate to zero length
|
||
{"a+",FA_OPEN_ALWAYS|FA_OPEN_APPEND|FA_READ|FA_WRITE},//append; open text file or create for update, writing at eof
|
||
{"rb+",FA_READ|FA_WRITE},//open binary file for update (reading and writing)
|
||
{"wb+",FA_CREATE_NEW|FA_READ|FA_WRITE},//create binary file for update, or truncate to zero length
|
||
{"ab+",FA_OPEN_ALWAYS|FA_OPEN_APPEND|FA_READ|FA_WRITE},//append; open binary file or create for update, writing at eof
|
||
{NULL,NULL},
|
||
};
|
||
|
||
for(int i=0;items[i].mode;i++)
|
||
{
|
||
if(strcmp(items[i].mode,mode)==0)
|
||
return items[i].mb;
|
||
}
|
||
return FA_READ;
|
||
}
|
||
|
||
|
||
|
||
|
||
// 在指定流上打开文件
|
||
static FILE *fopen_s(const char * filename,const char * mode,FILE *stream)
|
||
{
|
||
FILE *file=stream;
|
||
if(file==NULL)
|
||
file=calloc (1,sizeof(FILE));
|
||
file_struct_private *file_p=NULL;
|
||
u8 ret=0;
|
||
|
||
// 首先查找同名设备
|
||
file->type=FILE_TYPE_DEVICE;
|
||
file->dev=libc_find_dev(filename);
|
||
if(file->dev!=NULL)
|
||
{
|
||
if(file->dev->open) file->dev->open();
|
||
return file;
|
||
}
|
||
|
||
file->type=FILE_TYPE_FILE;
|
||
if (filename[0]=='0'&&filename[1]==':')
|
||
{
|
||
file_p=calloc (1,sizeof (file_struct_private));
|
||
ret=f_stat (filename,&file_p->file_info);
|
||
if (ret==FR_OK)
|
||
{
|
||
f_open(&file_p->file,filename,f_get_mode(mode));
|
||
file->ptr=file_p;
|
||
}
|
||
else
|
||
{
|
||
free(file_p);
|
||
file_p=NULL;
|
||
free(file);
|
||
file=NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
file_p=calloc (1,sizeof (file_struct_private));
|
||
if (file_p->flash.addr= FLASH_FindFile((char *)filename,&file_p->flash.size),file_p->flash.addr==0)
|
||
{
|
||
free(file_p);
|
||
file_p=NULL;
|
||
free(file);
|
||
file=NULL;
|
||
}
|
||
else
|
||
{
|
||
file->ptr=file_p;
|
||
}
|
||
}
|
||
return (FILE *)file;
|
||
}
|
||
|
||
|
||
// 打开文件
|
||
FILE *fopen(const char * filename,const char * mode)
|
||
{
|
||
return fopen_s(filename,mode,NULL);
|
||
}
|
||
|
||
// 把新的文件名和流关联,输出新的流
|
||
// 如果filename==NULL,则创建一个内存文件
|
||
FILE *freopen(const char * filename, const char * mode, FILE * stream)
|
||
{
|
||
FILE * file=stream;
|
||
if(file==NULL) return NULL;
|
||
|
||
// 在本例中只允许修改基本输入输出流
|
||
if((file!=stdin)&&(file!=stdout)&&(file!=stderr)) return NULL;
|
||
|
||
// 首先尝试关闭与流关联的文件
|
||
fclose(stream);
|
||
|
||
// 把新文件关联到流
|
||
if(filename!=NULL)
|
||
return fopen_s(filename,mode,stream);
|
||
else
|
||
return tmpfile_s(stream);
|
||
}
|
||
|
||
|
||
// 设置缓冲区,返回0成功
|
||
int setvbuf(FILE * stream, char * buf, int mode, size_t size)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
void setbuf(FILE * stream,char * buf)
|
||
{
|
||
if(buf)
|
||
setvbuf(stream,buf,_IOFBF,BUFSIZ);
|
||
else
|
||
setvbuf(stream,buf,_IONBF,BUFSIZ);
|
||
}
|
||
|
||
|
||
|
||
// 设备文件获取一个字符
|
||
static int fgetc_dev(FILE * stream)
|
||
{
|
||
int c=EOF;
|
||
const libc_device_file *dev=stream->dev;
|
||
if(dev)
|
||
{
|
||
if(dev->putc)
|
||
{
|
||
c=dev->getc();
|
||
return c;
|
||
}
|
||
}
|
||
return c;
|
||
}
|
||
|
||
// 内存文件获取一个字符
|
||
static int fgetc_mem(FILE * stream)
|
||
{
|
||
int c=EOF;
|
||
libc_mem_file *mem=stream->mem;
|
||
if(mem)
|
||
{
|
||
if(mem->ptr<mem->size)
|
||
{
|
||
c=mem->data[mem->ptr];
|
||
mem->ptr++;
|
||
return c;
|
||
}
|
||
}
|
||
return c;
|
||
}
|
||
|
||
// 普通文件获取一个字符
|
||
static int fgetc_fil(FILE * stream)
|
||
{
|
||
int c=EOF;
|
||
uint8_t d;
|
||
if(fread(&d, 1, 1, stream)==1)
|
||
c=d;
|
||
return c;
|
||
}
|
||
|
||
static int (*const g_getc_funs[3])(FILE *)={
|
||
fgetc_fil,
|
||
fgetc_dev,
|
||
fgetc_mem,
|
||
};
|
||
|
||
|
||
// 获取文件流中的一个字符
|
||
int fgetc(FILE * stream)
|
||
{
|
||
int c=EOF;
|
||
if(stream)
|
||
{
|
||
c=g_getc_funs[stream->type](stream);
|
||
}
|
||
return c;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
// 设备文件写入一个字符
|
||
static int fputc_dev(int c,FILE * stream)
|
||
{
|
||
const libc_device_file *dev=stream->dev;
|
||
if(dev)
|
||
{
|
||
if(dev->putc)
|
||
{
|
||
dev->putc(c);
|
||
return c;
|
||
}
|
||
}
|
||
return EOF;
|
||
}
|
||
|
||
// 内存文件写入一个字符
|
||
static int fputc_mem(int c,FILE * stream)
|
||
{
|
||
libc_mem_file *mem=stream->mem;
|
||
if(mem)
|
||
{
|
||
if(mem->ptr<mem->size)
|
||
{
|
||
mem->data[mem->ptr]=c;
|
||
mem->ptr++;
|
||
return c;
|
||
}
|
||
}
|
||
return EOF;
|
||
}
|
||
|
||
// 普通文件写入一个字符
|
||
static int fputc_fil(int c,FILE * stream)
|
||
{
|
||
uint8_t d=c;
|
||
if(fwrite(&d, 1, 1, stream)==1)
|
||
return c;
|
||
else
|
||
return EOF;
|
||
}
|
||
|
||
static int (*const g_putc_funs[3])(int,FILE *)={
|
||
fputc_fil,
|
||
fputc_dev,
|
||
fputc_mem,
|
||
};
|
||
|
||
|
||
// 写入一个字符
|
||
int fputc(int c, FILE * stream)
|
||
{
|
||
if(stream)
|
||
{
|
||
return g_putc_funs[stream->type](c,stream);
|
||
}
|
||
return EOF;
|
||
}
|
||
|
||
|
||
// 普通文件读取
|
||
static size_t fread_fil(void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
file_struct_private * file=stream->ptr;
|
||
if (file)
|
||
{
|
||
if (file->flash.size==0)
|
||
{
|
||
UINT rb=0;
|
||
f_read (&file->file,ptr,size*nmemb,&rb);
|
||
return rb/size;
|
||
}
|
||
else
|
||
{
|
||
u32 read_size=size*nmemb;
|
||
if (read_size>file->flash.size-file->flash.ptr)
|
||
read_size=file->flash.size-file->flash.ptr;
|
||
FLASH_ReadData(ptr,file->flash.ptr+file->flash.addr,size*nmemb);
|
||
file->flash.ptr+=read_size;
|
||
return read_size/size;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// 设备文件读取
|
||
static size_t fread_dev(void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
const libc_device_file *dev=stream->dev;
|
||
|
||
if(dev)
|
||
{
|
||
// 暂时不支持设备文件读取
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 内存文件读取
|
||
static size_t fread_mem(void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
libc_mem_file *mem=stream->mem;
|
||
|
||
if(mem)
|
||
{
|
||
// 暂时不支持内存文件读取
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
static size_t (*const g_read_funs[3])(void *,size_t,size_t,FILE *)={
|
||
fread_fil,
|
||
fread_dev,
|
||
fread_mem,
|
||
};
|
||
|
||
// 读取文件
|
||
size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
if(stream)
|
||
{
|
||
return g_read_funs[stream->type](ptr,size,nmemb,stream);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 设备文件写入
|
||
static size_t fwrite_dev(const void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
const libc_device_file *dev=stream->dev;
|
||
|
||
if(dev)
|
||
{
|
||
if(dev->write)
|
||
{
|
||
return dev->write(ptr,size*nmemb)/size;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 内存文件写入
|
||
static size_t fwrite_mem(const void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
libc_mem_file *mem=stream->mem;
|
||
|
||
if(mem)
|
||
{
|
||
// 暂时不支持内存文件写入
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 普通文件写入
|
||
static size_t fwrite_fil(const void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
file_struct_private * file=stream->ptr;
|
||
if (file)
|
||
{
|
||
if (file->flash.size==0)
|
||
{
|
||
UINT rb=0;
|
||
f_write(&file->file,ptr,size*nmemb,&rb);
|
||
return nmemb;
|
||
}
|
||
else
|
||
{
|
||
//flash暂时不支持写入
|
||
return 0;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
static size_t (*const g_write_funs[3])(const void *,size_t,size_t,FILE *)={
|
||
fwrite_fil,
|
||
fwrite_dev,
|
||
fwrite_mem,
|
||
};
|
||
|
||
|
||
// 写入文件
|
||
size_t fwrite(const void * ptr, size_t size, size_t nmemb, FILE * stream)
|
||
{
|
||
if(stream)
|
||
{
|
||
return g_write_funs[stream->type](ptr,size,nmemb,stream);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
// 获取文件位置,成功返回0
|
||
int fgetpos(FILE * stream, fpos_t *pos)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
// 设置文件位置,成功返回0
|
||
int fsetpos(FILE * stream, const fpos_t * pos)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// 普通文件设置文件偏移,成功返回0
|
||
static int fseek_fil(FILE * stream, long int offset, int whence)
|
||
{
|
||
file_struct_private * file=stream->ptr;
|
||
if (file)
|
||
{
|
||
if (file->flash.size==0)
|
||
{
|
||
//文件开头
|
||
if (SEEK_SET==whence)
|
||
{
|
||
if (f_lseek(&file->file,offset)==FR_OK)
|
||
return 0;
|
||
}
|
||
else if (SEEK_END==whence)
|
||
{
|
||
//这时offset为负数
|
||
offset=file->file_info.fsize+offset;
|
||
if (f_lseek(&file->file,offset)==FR_OK)
|
||
return 0;
|
||
}
|
||
else if (SEEK_CUR==whence)
|
||
{
|
||
//这时offset可正可负
|
||
long int pos=f_tell(&file->file);
|
||
offset=pos+offset;
|
||
if (f_lseek(&file->file,offset)==FR_OK)
|
||
return 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//文件开头
|
||
if (SEEK_SET==whence)
|
||
{
|
||
if(offset>=0&&offset<=file->flash.size)
|
||
{
|
||
file->flash.ptr=offset;
|
||
return 0;
|
||
}
|
||
}
|
||
else if (SEEK_END==whence)
|
||
{
|
||
offset=file->flash.size+offset;
|
||
if(offset>=0&&offset<=file->flash.size)
|
||
{
|
||
file->flash.ptr=offset;
|
||
return 0;
|
||
}
|
||
}
|
||
else if (SEEK_CUR==whence)
|
||
{
|
||
//这时offset可正可负
|
||
long int pos=file->flash.ptr;
|
||
offset=pos+offset;
|
||
if(offset>=0&&offset<=file->flash.size)
|
||
{
|
||
file->flash.ptr=offset;
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// 设备文件设置文件偏移,成功返回0
|
||
static int fseek_dev(FILE * stream, long int offset, int whence)
|
||
{
|
||
const libc_device_file *dev=stream->dev;
|
||
|
||
if(dev)
|
||
{
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
// 内存文件设置文件偏移,成功返回0
|
||
static int fseek_mem(FILE * stream, long int offset, int whence)
|
||
{
|
||
libc_mem_file *mem=stream->mem;
|
||
|
||
if(mem)
|
||
{
|
||
//文件开头
|
||
if (SEEK_SET==whence)
|
||
{
|
||
if(offset>=0&&offset<=mem->size)
|
||
{
|
||
mem->ptr=offset;
|
||
return 0;
|
||
}
|
||
}
|
||
else if (SEEK_END==whence)
|
||
{
|
||
offset=mem->size+offset;
|
||
if(offset>=0&&offset<=mem->size)
|
||
{
|
||
mem->ptr=offset;
|
||
return 0;
|
||
}
|
||
}
|
||
else if (SEEK_CUR==whence)
|
||
{
|
||
//这时offset可正可负
|
||
long int pos=mem->ptr;
|
||
offset=pos+offset;
|
||
if(offset>=0&&offset<=mem->size)
|
||
{
|
||
mem->ptr=offset;
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
static int (*const g_seek_funs[3])(FILE *,long int,int)={
|
||
fseek_fil,
|
||
fseek_dev,
|
||
fseek_mem,
|
||
};
|
||
|
||
// 设置文件偏移,成功返回0
|
||
int fseek(FILE * stream, long int offset, int whence)
|
||
{
|
||
if(stream)
|
||
{
|
||
return g_seek_funs[stream->type](stream,offset,whence);
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
// 返回文件指针偏移
|
||
static long int ftell_fil(FILE * stream)
|
||
{
|
||
file_struct_private * file=stream->ptr;
|
||
if (file)
|
||
{
|
||
if (file->flash.size==0)
|
||
{
|
||
return f_tell(&file->file);
|
||
}
|
||
else
|
||
{
|
||
return file->flash.ptr;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// 返回文件指针偏移
|
||
static long int ftell_dev(FILE * stream)
|
||
{
|
||
const libc_device_file *dev=stream->dev;
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 返回文件指针偏移
|
||
static long int ftell_mem(FILE * stream)
|
||
{
|
||
libc_mem_file *mem=stream->mem;
|
||
if(mem)
|
||
return mem->ptr;
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
static long int (*const g_tell_funs[3])(FILE *)={
|
||
ftell_fil,
|
||
ftell_dev,
|
||
ftell_mem,
|
||
};
|
||
|
||
|
||
// 返回文件指针偏移
|
||
long int ftell(FILE * stream)
|
||
{
|
||
if(stream)
|
||
{
|
||
return g_tell_funs[stream->type](stream);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
// 把文件指针设置为文件开头
|
||
void rewind(FILE * stream)
|
||
{
|
||
fseek(stream, 0L, SEEK_SET);
|
||
}
|
||
|
||
|
||
// 测试文件结束,未结束返回0,已结束返回1
|
||
static int feof_fil(FILE * stream)
|
||
{
|
||
file_struct_private * file=stream->ptr;
|
||
if(file)
|
||
{
|
||
if (file->flash.size==0)
|
||
{
|
||
FIL *fp=&file->file;
|
||
return f_eof(fp);
|
||
}
|
||
else
|
||
{
|
||
return (int)(file->flash.ptr==file->flash.size);
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
// 测试文件结束,未结束返回0,已结束返回1
|
||
static int feof_dev(FILE * stream)
|
||
{
|
||
const libc_device_file *dev=stream->dev;
|
||
|
||
if(dev)
|
||
return 0;
|
||
else
|
||
return 1;
|
||
}
|
||
|
||
static int feof_mem(FILE * stream)
|
||
{
|
||
libc_mem_file *mem=stream->mem;
|
||
|
||
if(mem)
|
||
return (int)(mem->ptr==mem->size);
|
||
else
|
||
return 1;
|
||
}
|
||
|
||
static int (*const g_eof_funs[3])(FILE *)={
|
||
feof_fil,
|
||
feof_dev,
|
||
feof_mem,
|
||
};
|
||
|
||
|
||
// 测试文件结束,未结束返回0,已结束返回1
|
||
int feof(FILE * stream)
|
||
{
|
||
if(stream)
|
||
{
|
||
return g_eof_funs[stream->type](stream);
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
// 断言,c语言标准库使用这个函数
|
||
void __aeabi_assert(const char * e, const char *_file_, int _line_)
|
||
{
|
||
printf("%s:%s,at %d\r\n",e,_file_,_line_);
|
||
while(1);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|