⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmp_fs_api_za.c

📁 嵌入式系统下的文件管理处理,和基本图片jpg格式处理原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*-------------------------------------------------*
* $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 + -