www.pudn.com > OS.rar > DirectRead.c, change:2006-12-11,size:6493b
/*******************************************************************************
* Copyright (c) 2005 BEIJING HANDHELD ELECTRONIC TECHNOLOGY CO., LTD.
* All rights reserved.
* AUTHOR 亓爱慧
* FILENAME DirectRead.c
* CREATE_DATE 2005/09/01
* SHORT_DESCR 提供系统文件的快速读取
* NOTE 只适用于系统数据区,系统区簇的大小不超过16K bytes,因为是要求速度,所以数据
* 准确性及缓冲区大小需自行确认。
* 调用顺序:
* get_cluster_size
* direct_fopen
* direct_freadB
*******************************************************************************/
#include ".\System\GPL162002_Far\include\system_head.h"
#include ".\component\GPL162002_Far\include\component_head.h"
#include ".\driver\GPL162002_Far\include\driver_head.h"
#define INVALID_CLUSTER 0L
#define SYS_DISK_NO 1
#define SECTOR_SIZE 512
extern unsigned long Nand_Part0_Offset;
U16 sysdisk_cluster_size;
//------------------------------------------------------------------------------
// unsigned int get_cluster_size( void );
// function: 获得系统区的簇大小
// input: disk_no --- disk号
// return: -1 --- error, other --- 簇的大小
//------------------------------------------------------------------------------
unsigned int get_cluster_size( void )
{
sysdisk_cluster_size = ( GetSectorsPerCluster( SYS_DISK_NO )*512 ) & 0xffff;
return sysdisk_cluster_size;
}
//------------------------------------------------------------------------------
// int direct_fopen( LPTR path, LPTR cluster_buf, unsigned int cluster_buf_len );
// function: 搜索文件的簇号,并放在缓冲区中
// input: path --- 文件的路径名
// cluster_buf --- 存放簇号的缓冲区
// cluster_buf_len --- 缓冲区长度
// return: 0 --- no error
// -1 --- 打开文件错误
// -2 --- 缓冲区长度太小
//------------------------------------------------------------------------------
int direct_fopen( LPTR path, LPTR cluster_buf, unsigned int cluster_buf_len )
{
int fd;
unsigned long file_ofs, nand_log_addr, buf_ptr;
struct stat statbuf;
memset( (void *)cluster_buf, 0, cluster_buf_len );
stat( path, &statbuf );
fd = open( path, O_RDONLY );
if( -1 == fd ) return -1;
if( 0 == statbuf.st_size ) {
close( fd );
return 0;
}
buf_ptr = 0; file_ofs = 0;
do {
if( buf_ptr >= cluster_buf_len ) {
close( fd );
return -2;
}
lseek( fd, file_ofs, SEEK_SET );
nand_log_addr = Clus2Phy( SYS_DISK_NO, _GetCluster( fd ) ) * SECTOR_SIZE + Nand_Part0_Offset * SECTOR_SIZE;
WVUL( (cluster_buf+buf_ptr), nand_log_addr );
buf_ptr += 2;
file_ofs += sysdisk_cluster_size;
} while( file_ofs statbuf.st_size );
close( fd );
return 0;
}
//------------------------------------------------------------------------------
// int direct_freadB( LPTR cluster_buf, long file_ofs, LPTR dat_buf, unsigned int byte_len );
// function: 根据簇号缓冲区读取文件内容
// input: cluster_buf --- 簇号缓冲区
// file_ofs --- 文件偏移
// dat_buf --- 读取内容存放缓冲区
// byte_len --- 要读取内容的字节长度
// return: 0 --- OK
// -1 --- 读取error
//------------------------------------------------------------------------------
int direct_freadB( LPTR cluster_buf, long file_ofs, LPTR dat_buf, unsigned int byte_len )
{
unsigned long Addr;
unsigned int buf_ptr, len_bak, rd_len, cluster_ofs;
len_bak = byte_len;
if( 4096 == sysdisk_cluster_size ) {
buf_ptr = (unsigned int)((unsigned long)file_ofs>>12)*2;
cluster_ofs = file_ofs & 0xfff;
}
else {
buf_ptr = (unsigned int)((unsigned long)file_ofs / sysdisk_cluster_size)*2;
cluster_ofs = file_ofs % sysdisk_cluster_size;
}
rd_len = sysdisk_cluster_size - cluster_ofs;
if( rd_len > byte_len ) rd_len = byte_len;
do {
Addr = RVUL( (cluster_buf + buf_ptr) ) + cluster_ofs;
_Nand_LogicRead_Byte( Addr, dat_buf, rd_len );
cluster_ofs = 0;
byte_len -= rd_len;
dat_buf += rd_len;
rd_len = byte_len > sysdisk_cluster_size ? sysdisk_cluster_size : byte_len;
buf_ptr += 2;
} while ( byte_len );
return 0;
}
#if 1
//------------------------------------------------------------------------------
// int direct_freadW( LPTR cluster_buf, long file_ofs, LPTR dat_buf, unsigned int word_len )
// function: 根据簇号缓冲区读取文件内容
// input: cluster_buf --- 簇号缓冲区
// file_ofs --- 文件偏移
// dat_buf --- 读取内容存放缓冲区
// word_len --- 要读取内容的word长度
// return: 0 --- OK
// -1 --- 读取error
//------------------------------------------------------------------------------
int direct_freadW_sys( LPTR cluster_buf, long file_ofs, LPTR dat_buf, unsigned long byte_len)
{
unsigned long Addr;
unsigned int sectorsum;
unsigned int sectorno;
unsigned long buf_ptr, len_bak, rd_len, cluster_ofs,cluster_last;
unsigned long buf_t;
int i;
len_bak = byte_len;
buf_ptr = (unsigned int)((unsigned long)file_ofs / sysdisk_cluster_size)*2;
cluster_ofs = file_ofs % sysdisk_cluster_size;
rd_len = sysdisk_cluster_size - cluster_ofs;
if( rd_len > byte_len ) rd_len = byte_len;
do {
Addr = RVUL( (cluster_buf + buf_ptr) ) + cluster_ofs;
_Nand_LogicRead_Word( Addr, dat_buf, rd_len );
cluster_ofs = 0;
byte_len -= rd_len;
dat_buf += rd_len/2;
rd_len = byte_len > sysdisk_cluster_size ? sysdisk_cluster_size : byte_len;
buf_ptr += 2;
} while ( byte_len );
return 0;
}
#endif
#if 0
#define CLUSTER_BUF_LEN 2000
#define R_BUF_LEN 16384
#define R_LEN 100
#define F_POS 0x10000L
void test_direct_read( void )
{
int ret_val;
LPTR cluster_buf, read_buf, comp_buf;
int fp;
unsigned long ofs;
cluster_buf = fmalloc( CLUSTER_BUF_LEN );
read_buf = fmalloc( R_BUF_LEN );
comp_buf = fmalloc( R_BUF_LEN );
fp = open( GLPSTR("B:\\FONT\\HHGB16.BIN"), O_RDONLY );
get_cluster_size();
ret_val = direct_fopen( GLPSTR("B:\\FONT\\HHGB16.BIN"), cluster_buf, CLUSTER_BUF_LEN );
ofs = 0;
do {
ret_val = readB( fp, read_buf, R_BUF_LEN );
direct_freadB( cluster_buf, ofs, comp_buf, R_BUF_LEN );
if( memcmp( read_buf, comp_buf, ret_val ) ) {
__asm( "nop" );
__asm( "nop" );
__asm( "nop" );
}
ofs += ret_val;
} while( ret_val == R_BUF_LEN );
close( fp );
}
#endif
//--------------------------------------end of DirectRead.c----------------------------------------