📄 pmp_fs_api_za.c
字号:
/*-------------------------------------------------*
* $RCSfile: pmp_fs_api_ZA.c,v $
* $Date: 2007/01/17 12:28:43 $
* $Author: lanzhu $
* $Log: pmp_fs_api_ZA.c,v $
* Revision 1.1.1.1 2007/01/17 12:28:43 lanzhu
* 齐兰柱 准备一个新的代码分支
*
* Revision 1.4 2006/12/29 07:24:45 lanzhu
* 在进行ZA_fread ZA_fwrite 时, 进行CACHE 的清空动作
*
* Revision 1.3 2006/12/18 02:14:27 taiyun
* Modify include filename
*
* Revision 1.2 2006/12/12 00:29:29 lanzhu
* pmp_fs_ZA.c 修改了一个 读单个字符出错的BUG, 去除WARNING
*
* Revision 1.1.1.1 2006/12/05 03:01:16 lanzhu
* no message
*
* Revision 1.1.1.1 2006/12/01 09:49:35 lanzhu
* no message
*
* Revision 1.9 2006/10/13 06:10:24 taoli
* 函数中malloc改为栈内申请
*
* Revision 1.8 2006/10/13 01:34:00 taoli
* modify ZA_chdir
*
* Revision 1.7 2006/10/12 09:22:05 taoli
* ZA_access函数检测不存在的文件返回为存在,错误,已修改.
*
* Revision 1.6 2006/09/23 07:18:37 lanzhu
* 修改了get_unicode_ptr 的一个BUG
*
* Revision 1.5 2006/09/20 12:35:00 lanzhu
* 添加了编码的转换功能,并逐个进行了测试
*
* Revision 1.4 2006/09/19 08:49:05 taoli
* modify readdir
*
* Revision 1.3 2006/09/19 07:12:27 lanzhu
* 添加了 rewinddir 函数
*
* Revision 1.2 2006/09/11 12:29:13 lanzhu
* 对所发布的ZA FS API 进行测试, 初步测试OK!
*
* Revision 1.1 2006/09/08 01:05:08 lanzhu
* 为移植专案的程序,进行了FS API 的封装
*
*
*--------------------------------------------------*/
//#define DEBUG_ZA_FS
#define CHANGE_CODE
#include <ctype.h>
#include <string.h>
#include "SPMP_define.h"
#include "os_api.h"
#include "fs_api.h"
#include "za_fs_api.h"
#include "appdriver.h"
#include "SysUtility.h"
// 定义为专案的接口形式
#define _FOR_A3K_PROG
/**************************************************************************
* G E N E R A L C O N S T A N T S *
**************************************************************************/
#define THE_LAST_DIR (0)
#define FS_NAME_BUF (1024)
/**************************************************************************
* M A C R O S *
**************************************************************************/
/**************************************************************************
* D A T A T Y P E S *
**************************************************************************/
/**************************************************************************
* G L O B A L D A T A *
**************************************************************************/
// 进行码值转换时使用的内存
static UINT8 *gpFS_strbuf = NULL;
// 进行句柄、指针的转换
static UINT8 pFHandleBegin;
// FAT 短文件名目录项中不允许出现的字符, 共10个字符
static const INT8 fnamekeyword[] = "\\/:*?\"<>|";
#define PERSVSUM 34
// WINDOWS FAT 保留的不能作为文件名的字符串
static const INT8 *fnamepersive[PERSVSUM] =
{
"COM1",
"COM2",
"COM3",
"COM4",
"COM5",
"COM6",
"COM7",
"COM8",
"COM9",
"COM10",
"COM11",
"COM12",
"COM13",
"COM14",
"COM15",
"COM16",
"LPT1",
"LPT2",
"LPT3",
"LPT4",
"LPT5",
"LPT6",
"LPT7",
"LPT8",
"LPT9",
"LPT10",
"LPT11",
"LPT12",
"LPT13",
"LPT14",
"LPT15",
"LPT16",
"CON",
"PRN"
};
/**************************************************************************
* E X T E R N A L R E F E R E N C E S *
**************************************************************************/
// lanzhu add @[12/29/2006]
extern void mmuFlushDCache( void );
/**************************************************************************
* F U N C T I O N D E C L A R A T I O N S *
**************************************************************************/
// 根据输入的字符串,获得打开模式的内部定义值
static INT16 QFS_get_open_mode( INT8 * in_str);
// 检查输入的文件名是否含有非法字符
static INT32 QFS_check_fname(INT8 *name );
// 通过逻辑盘的字符串获得逻辑盘的内部代号
static UINT16 get_devid_by_name( UINT8 * pDevName, UINT16 *pDevID);
// 从一个多级目录串中,只取出一级目录文本串
static INT16 get_dir_from_str(const INT8 *in_str, INT8 *out_str);
// 从ZA 接口层的句柄指针中, 获得文件句柄代码值
static INT16 get_file_handle( void * stream, UINT32 *pHandle );
// 获得 UNICOE 编码的地址指针
static UINT8 * get_unicode_ptr(const INT8 *plocal);
/************************************************************************/
/*
*/
/************************************************************************/
#ifdef DEBUG_ZA_FS
void test_za_fs( void )
{
INT32 err;
UINT8 *pdir;
FILE_INFO tmp_info;
struct f_info tinfo;
UINT8 buffer[0x100];
UINT8 *pfile;
/*
pfile = ZA_fopen("D:\\阿健康法活动都将返回家","W");
ZA_fclose(pfile);
*/
/*
err = ZA_access("03. 草原之夜.mp3", F_OK);
DEBUG_OUTPUT(("err 0x%x\r\n", err));
*/
// stat OK!
err = ZA_stat("03. 草原之夜.mp3", &tinfo);
DEBUG_OUTPUT(("attr: 0x%x\r\n", tinfo.attribute));
DEBUG_OUTPUT(("size: %d\r\n", tinfo.file_size));
/*
//chdir opendir readdir closedir TEST OK!
DEBUG_OUTPUT(("\r\ntest ZA begin!\r\n"));
ZA_chdir("D:\\AUDIO");
pdir = ZA_opendir("D:\\");
DEBUG_OUTPUT(("%x \r\n", pdir));
while (1)
{
err = ZA_readdir(pdir, buffer, &tmp_info);
if ( !err ){
DEBUG_OUTPUT(("+++++ %s\r\n", buffer));
DEBUG_OUTPUT(("+++++ %x\r\n", tmp_info.attribute));
continue;
}
break;
}
err = ZA_closedir( pdir );
DEBUG_OUTPUT(("%x \r\n", err));
ZA_getcwd(buffer, sizeof(buffer));
DEBUG_OUTPUT(("CWD: %s\r\n", buffer));
*/
/*
ZA_init();
err = fsFormat(1);
DEBUG_OUTPUT(("000 err %x\r\n", err));
err = fsMount(1);
DEBUG_OUTPUT(("0'' err %x\r\n", err));
*/
err = ZA_mkdir("D:\\阿阿阿111222");
sio_printf("mkdir err:%x\r\n", err);
err = ZA_chdir("D:\\阿阿阿111222");
sio_printf("chdir err:%x\r\n", err);
err = ZA_chdir("AAABBB111222");
sio_printf("chdir err:%x\r\n", err);
err = ZA_getcwd(buffer, sizeof(buffer));
sio_printf("%s\r\n", buffer);
while (1);
}
#endif
/************************************************************************/
/* QFS_init
input:
void
output:
void
func:
在使用 QFS layer之前,进行初始化的动作
note:
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
void QFS_init( void )
#else
void ZA_init( void )
#endif
{
/*
UINT8 *pbuf;
// 进行内存的申请
pbuf = MEM_ALLOC( FS_NAME_BUF );
if (NULL == pbuf) {
ERROR_REPORT;
return;
}
// 保存内存指针
gpFS_strbuf = pbuf;
*/
return;
}
/************************************************************************/
/* QFS_stat
input:
fname 文件名字符串的指针, 支持全路径名
finfo 文件信息结构体的指针
output:
0 成功 从 info 结构体中获取文件信息
<0 失败
function:
获得文件的属性信息 时间 长度 占用空间的大小 读写属性
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_stat(INT8 * pfile_name, struct f_info * pfileinfo)
#else
INT32 ZA_stat (INT8 * pfile_name, struct f_info * pfileinfo)
#endif
{
UINT16 err;
File_Info_t FileInfoAttr;
INT8 *file_name;
// 判断输入参数是否合法
if ((NULL == pfile_name) || (NULL == pfileinfo) ){
ERROR_REPORT;
return QFS_ERR;
}
#ifndef CHANGE_CODE
file_name = pfile_name;
#else
file_name = get_unicode_ptr(pfile_name);
#endif
// 将输入进行清空的动作
memset( pfileinfo, 0x00, sizeof(struct f_info));
// 获得文件属性信息
err = fsFileInfoGet(file_name, &FileInfoAttr);
if ( err ) {
ERROR_REPORT;
return QFS_ERR;
}
// 进行信息的复制
pfileinfo->attribute = FileInfoAttr.attr;
pfileinfo->file_size = FileInfoAttr.fileSize;
pfileinfo->f_tm.tm_year = FileInfoAttr.tCreate.tm_year;
pfileinfo->f_tm.tm_mon = FileInfoAttr.tCreate.tm_mon;
pfileinfo->f_tm.tm_mday = FileInfoAttr.tCreate.tm_mday;
pfileinfo->f_tm.tm_hour = FileInfoAttr.tCreate.tm_hour;
pfileinfo->f_tm.tm_min = FileInfoAttr.tCreate.tm_min;
pfileinfo->f_tm.tm_sec = FileInfoAttr.tCreate.tm_sec;
// 返回成功
return QFS_OK;
}
/************************************************************************/
/*
input:
drvname 逻辑盘字符串指针
output:
0 成功 非0值 失败
func:
格式化指定的逻辑盘
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_formart(const INT8 * drvname)
#else
INT32 ZA_formart(const INT8 * drvname)
#endif
{
UINT16 dev;
UINT16 err;
// 判断输入参数是否合法
if (NULL == drvname) {
ERROR_REPORT;
return NULL;
}
// 通过逻辑设备驱动器的名称, 获得内部设备ID
err = get_devid_by_name( (UINT8 *)drvname, &dev );
if ( err ) {
ERROR_REPORT;
return NULL;
}
// 进行逻辑盘的格式化
err = fsFormat( (UINT8) dev );
// 返回结果
return err;
}
/************************************************************************/
/* QFS_open
input:
file_name [in] 文件名字符串指针, // 可以支持全路径
"C:\\A.BIN"
"C:\\DIR111\\A.BIN"
mode [in] 文件打开模式字符串指针
"R" // 只读方式,文件必须已经存在
"R+" // 读写方式, 文件必须已经存在
"W" // 只写方式,不存在,则创建,存在则,清空全部内容
"W+" // 读写方式,不存在,则创建,存在则,清空全部内容
"A" // 添加模式,不存在,则创建,存在则,打开,指针指向文件尾
"A+" // 添加模式,不存在,则创建,存在则,打开,指针指向文件尾
output:
NULL 失败
其他值 成功
func:
输入文件名字符串和文件打开模式, 打开文件
note:
[6/5/2006] 增加对文件名 合法性的检查
如果输入的文件名中 含有 windows FAT 所不允许的 字符, 直接返回失败
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
ZA_FILE * QFS_fopen(const INT8 *pfile_name, const INT8 * mode)
#else
ZA_FILE * ZA_fopen(const INT8 *pfile_name, const INT8 * mode)
#endif
{
// INT32 i;
INT16 open_mode;
INT32 vfs_open_flag;
UINT16 err;
UINT32 FileHandle;
INT8 *file_name;
err = 0x00;
// 判断输入参数是否合法, 非法直接返回失败
if( (pfile_name == NULL) || (mode == NULL) ){
ERROR_REPORT;
return NULL;
}
#ifndef CHANGE_CODE
file_name = pfile_name; // 直接使用文件名字符串
#else
file_name = get_unicode_ptr(pfile_name);
#endif
// 获得打开模式
open_mode = QFS_get_open_mode((INT8 *) mode ); // 获得文件的打开模式
if(open_mode <0 ){
ERROR_REPORT;
return NULL;
}
// 暂时不进行打开文件的总数检查动作
// 556 系统上可以支持全路径文件名的打开, 不需要进行目录的逐级切换
/*
// 对输入的文件名,进行检查, 如果含有 windows FAT 不允许的字符,直接返回失败
i = QFS_check_fname( (INT8 *)file_name );
// 字符串非法, 直接返回失败
if(i) {
ERROR_REPORT;
return NULL; // 返回NULL 指针
}
*/
vfs_open_flag = 0x00;
switch(open_mode)
{
case F_O_RDONLY: // R
case F_O_RD_PLUS: // R+
vfs_open_flag = FS_O_RDONLY; // 以只读的方式
if( open_mode == F_O_RD_PLUS )
{
DEBUG_OUTPUT((" Mode: read write! \r\n "));
vfs_open_flag = FS_O_RDWR; // 以读写的方式
}
// 使用 SPMP 内部文件函数实现
err = fsOpen((UINT8 *)file_name, (UINT32) vfs_open_flag, &FileHandle);
break;
case F_O_WRONLY: // W
case F_O_WR_PLUS: // W+
// 进行文件的删除动作
err = fsDelete((UINT8 *)file_name );
// 创建文件,以读写的方式进行文件的操作
err = fsOpen((UINT8 *)file_name, (UINT32) FS_O_RDWR | FS_O_CREATE, &FileHandle);
break;
case F_O_APPEND: // A
case F_O_APPEND_PLUS: // A+
// 以读写的方式打开文件
err = fsOpen((UINT8 *)file_name, (UINT32) FS_O_RDWR, &FileHandle);
// 文件可以打开,说明文件存在,移动文件指针到文件尾
if (err){
err = fsSeek(FileHandle, (UINT32)FS_SEEK_END, 0x00);
}
else{ // 进行文件的创建动作
err = fsOpen((UINT8 *)file_name, (UINT32) FS_O_RDWR | FS_O_CREATE, &FileHandle);
}
break;
default:
ERROR_REPORT;
break;
}
// 判断是否有错误发生
if ( err ) {
ERROR_REPORT;
return NULL;
}
return (&pFHandleBegin + FileHandle);
}
/************************************************************************/
/* QFS_fread
input:
buf [out] 数据读出后存放的地址值
unit_size [in] 一个数据单位的长度值
unit_count [in] 数据单位的数量
stream [in] 文件句柄的指针
output:
< 0 失败
>= 0 成功
func:
进行进行文件的读动作
*/
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_fread (INT8 *buf, UINT32 unit_size, UINT32 unit_count, ZA_FILE * stream )
#else
INT32 ZA_fread (INT8 *buf, UINT32 unit_size, UINT32 unit_count, ZA_FILE * stream )
#endif
{
UINT16 err;
UINT32 BytesWant2Read;
UINT32 BytesRead;
UINT32 FileHandle;
// 判断输入参数的合法性
if ( (NULL == buf) || (NULL == stream)
|| !unit_size || !unit_count )
{
ERROR_REPORT;
return (INT32) QFS_ERR;
}
err = get_file_handle(stream, &FileHandle);
if ( err ){
ERROR_REPORT;
return (INT32) QFS_ERR;
}
// 计算需要读出的数据的总数
BytesWant2Read = unit_size * unit_count;
// lanzhu add@[12/29/2006]
mmuFlushDCache( );
// 使用内部函数进行数据的读取动作
err = fsRead( (UINT32) FileHandle, buf, BytesWant2Read, &BytesRead );
if ( err ) {
ERROR_REPORT;
return (INT32) QFS_ERR;
}
// 返回数据单位的总数
return (INT32) BytesRead/unit_size;
}
/************************************************************************/
/* QFS_fwrite
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -