www.pudn.com > STM32F4_bootloader.zip > exfuns.c, change:2017-04-27,size:5428b


#include "string.h" 
#include "exfuns.h" 
#include "fattester.h"	 
#include "malloc.h" 
#include "usart.h" 
#include "iap.h" 
#include "24cxx.h" 
  
//////////////////////////////////////////////////////////////////////////////////	  
 	 
#define FILE_MAX_TYPE_NUM		7	//最多FILE_MAX_TYPE_NUM个大类 
#define FILE_MAX_SUBT_NUM		4	//最多FILE_MAX_SUBT_NUM个小类 
 
 //文件类型列表 
u8*const FILE_TYPE_TBL[FILE_MAX_TYPE_NUM][FILE_MAX_SUBT_NUM]= 
{ 
{"BIN"},			//BIN文件 
{"LRC"},			//LRC文件 
{"NES"},			//NES文件 
{"TXT","C","H"},	//文本文件 
{"WAV","MP3","APE","FLAC"},//支持的音乐文件 
{"BMP","JPG","JPEG","GIF"},//图片文件 
{"AVI"},			//视频文件 
}; 
///////////////////////////////公共文件区,使用malloc的时候//////////////////////////////////////////// 
FATFS *fs[_VOLUMES];//逻辑磁盘工作区.	  
FIL *file;	  		//文件1 
UINT br,bw;			//读写变量 
FILINFO fileinfo;	//文件信息 
DIR dir;  			//目录 
 
u8 Receive_dat_buffer[STM_PAGE_SIZE];			  	//数据接收缓存数组 
 
u8 *fatbuf;			//SD卡数据缓存区 
/////////////////////////////////////////////////////////////////////////////////////// 
//为exfuns申请内存 
//返回值:0,成功 
//1,失败 
u8 exfuns_init(void) 
{ 
	u8 i; 
	fs[0]=(FATFS*)mymalloc(SRAMIN,sizeof(FATFS)); 
	file=(FIL*)mymalloc(SRAMIN,sizeof(FIL));		//为file申请内存 
//	fatbuf=(u8*)mymalloc(SRAMIN,512);				//为fatbuf申请内存 
	if(i==_VOLUMES&&file)return 0;  //申请有一个失败,即失败. 
	else return 1;	 
} 
 
//遍历文件夹,找到BIN升级文件 
void scan_files(char* flname) 
{ 
	FRESULT res;	   
	char filename[9]={0}; 
 
 #if _USE_LFN 
 	fileinfo.lfsize = _MAX_LFN * 2 + 1; 
	fileinfo.lfname = mymalloc(SRAMIN,fileinfo.lfsize); 
 #endif		   
 
  res = f_opendir(&dir,"0:"); //打开一个目录 
  if (res == FR_OK)  
	{	 
		while(1) 
		{ 
	    res = f_readdir(&dir, &fileinfo);                   //读取目录下的一个文件 
	    if (res != FR_OK || fileinfo.fname[0] == 0) break;  //错误了/到末尾了,退出 
			//if (fileinfo.fname[0] == '.') continue;  
			if(fileinfo.fattrib&AM_ARC)     //文件           
			{ 
			 #if _USE_LFN 
			  sprintf(filename,"%s",*fileinfo.lfname ? fileinfo.lfname : fileinfo.fname); 
			 #else 
				sprintf(filename,fileinfo.fname); 
			 #endif 
			 if((filename[5]=='b')&&(filename[6]=='i')&&(filename[7]=='n')) 
			 { 
				 strcpy(flname,filename);   // 
			 } 
			} 
		} 
 
  } 
	myfree(SRAMIN,fileinfo.lfname); 
 
} 
 
u8 Check_for_Updates(u16 codenum) 
{ 
//  u8 i=0; 
  u8 res; 
  u16 num = 0; 
  u16 readlen; 
  u32 addrx; 
  u32 Receive_data=0; //计算接收的总数据数 
  u32 file_size=0;    //文件size 
  char filename[9]={0}; 
	 
	exfuns_init();	 
  f_mount(fs[0],"0:",1); 		//挂载SD卡 
   
  scan_files(filename);  //找出bin文件 
  if(filename[7] == 'n') 
  { 
   //bin文件的文件名为4位数的版本号 与存在EEPROM里面的版本号对比 值大就更新程序 
   num = (filename[0]-'0')*1000+(filename[1]-'0')*100+(filename[2]-'0')*10+(filename[3]-'0'); 
  } 
  if(num <= codenum) return 1; 
  	 
	res = f_open(file, filename, FA_OPEN_EXISTING | FA_READ); 
  if(res != FR_OK) return 2;  //没有更新文件 
  file_size=f_size(file);    //读取的文件大小Byte 
  addrx=FLASH_APP_ADDR; 
  while(1) 
	{ 
		/*每次读取2K的数据到内存缓冲区buffer*/ 
    res = f_read(file, Receive_dat_buffer, STM_PAGE_SIZE,&br); 
 
    readlen=br; 
    Receive_data+=br;   //读取的总字节数 
    if (res || br == 0)  
    {  
      break;  
    }    
    iap_write_appbin(addrx,Receive_dat_buffer,readlen);//将读取的数据写入Flash中 
    addrx+=STM_PAGE_SIZE;//偏移2048  512*4=2048 
  } 
  if(Receive_data == file_size)  //字节长度正确 
	{ 
	 AT24CXX_Write(0,(u8*)filename,4); 
	 return 0;   
	}  
	else 
	 return 3; 
} 
 
//将小写字母转为大写字母,如果是数字,则保持不变. 
u8 char_upper(u8 c) 
{ 
	if(c<'A')return c;//数字,保持不变. 
	if(c>='a')return c-0x20;//变为大写. 
	else return c;//大写,保持不变 
}	       
//报告文件的类型 
//fname:文件名 
//返回值:0XFF,表示无法识别的文件类型编号. 
//		 其他,高四位表示所属大类,低四位表示所属小类. 
u8 f_typetell(u8 *fname) 
{ 
	u8 tbuf[5]; 
	u8 *attr='\0';//后缀名 
	u8 i=0,j; 
	while(i<250) 
	{ 
		i++; 
		if(*fname=='\0')break;//偏移到了最后了. 
		fname++; 
	} 
	if(i==250)return 0XFF;//错误的字符串. 
 	for(i=0;i<5;i++)//得到后缀名 
	{ 
		fname--; 
		if(*fname=='.') 
		{ 
			fname++; 
			attr=fname; 
			break; 
		} 
  	} 
	strcpy((char *)tbuf,(const char*)attr);//copy 
 	for(i=0;i<4;i++)tbuf[i]=char_upper(tbuf[i]);//全部变为大写  
	for(i=0;i<FILE_MAX_TYPE_NUM;i++)	//大类对比 
	{ 
		for(j=0;j<FILE_MAX_SUBT_NUM;j++)//子类对比 
		{ 
			if(*FILE_TYPE_TBL[i][j]==0)break;//此组已经没有可对比的成员了. 
			if(strcmp((const char *)FILE_TYPE_TBL[i][j],(const char *)tbuf)==0)//找到了 
			{ 
				return (i<<4)|j; 
			} 
		} 
	} 
	return 0XFF;//没找到		 			    
}	  
 
//得到磁盘剩余容量 
//drv:磁盘编号("0:"/"1:") 
//total:总容量	 (单位KB) 
//free:剩余容量	 (单位KB) 
//返回值:0,正常.其他,错误代码 
u8 exf_getfree(u8 *drv,u32 *total,u32 *free) 
{ 
	FATFS *fs1; 
	u8 res; 
    u32 fre_clust=0, fre_sect=0, tot_sect=0; 
    //得到磁盘信息及空闲簇数量 
    res =(u32)f_getfree((const TCHAR*)drv, (DWORD*)&fre_clust, &fs1); 
    if(res==0) 
	{											    
	    tot_sect=(fs1->n_fatent-2)*fs1->csize;	//得到总扇区数 
	    fre_sect=fre_clust*fs1->csize;			//得到空闲扇区数	    
#if _MAX_SS!=512				  				//扇区大小不是512字节,则转换为512字节 
		tot_sect*=fs1->ssize/512; 
		fre_sect*=fs1->ssize/512; 
#endif	   
		*total=tot_sect>>1;	//单位为KB 
		*free=fre_sect>>1;	//单位为KB  
 	} 
	return res; 
}