(正点原子例程)wifi实验(7.16)

正点原子wifi实验分析:
   fatfs文件系统分为三个层:应用层、FATFS模块、FATS模块提供底层接口驱动层。
    1.应用层只需要调用FATS提供的接口函数,如f_open、f_read、f_write和f_close等。
    2.FATFS模块提供的是ff.c和ff.h.除非有必要,一般情况下只需要直接包含进去即可。
    3.需要编写的是FATFS模块提供的底层接口,它包括存储媒介读/写接口(disk I/O)和供给文件创建修改时间的实时时钟。


   FATFS的介绍:doc里面是主要对FATFS的介绍,而src里面才是真正的源码。
    src中的源码有:
       ffconf.h    FATFS模块配置文件
ff.h      FATFS和应用模块公用的包含文件
FATFS       FATFS模块
diskio.h    FATFS和disk I/O模块公用的包含文件
interger.h  数据类型定义
  option.h    可选外部功能支持
    注意:以上不同层次间链接关系在于包含文件ff.h和diskio.h的作用!!!!
    重点:FATFS模块在移植的时候,我们一般只需要修改2个文件,即ffconf.h和diskio.c。FATFS的所有配置项都放在ffconf.h中。


在使用FATFS的时候,必须先要通过f_mount的函数注册一个工作区,才能对后续的API进行使用。即使用f_mount();
    f_mount(FATFS* fs,const TCHAR *path,BTYE opt)函数分析:
    其中fs为文件系统对象结构,path将要挂载的驱动的逻辑号,opt为挂载状态设置(0 不挂载:1 挂载)。
目的是为了注册一个工作区。


ff.h文件分析:
    1.定义了FATFS结构体为文件系统对象结构,其中包含了各项参数。同时还定义了FIL、DIR、FILINFO等结构体,还有sturct enum{}FRESULT返回错
误枚举类型。
    2.定义了各种FATFS模块的应用接口。


重要函数分析:
1.exfuns_init()函数分析:
     fs[i] = (FATFS *)mymalloc(SRAMIN,sizeof(FATS)); //其中i为支持磁盘的个数。
      file = (FIL *)mymalloc(SRAMIN,sizeof(FIL)); //为file申请内存
     ftemp = (FIL *)mymalloc(SRAMIN,sizeof(FIL)); //为ftemp申请内存
     fatbuf = (u8 *)mymalloc(SRAMIN,512);         //为fatbuf申请内存
2.f_mount(FATFS *fs,const TCHAR *path,BYTE opt)函数分析:
     vol = get_ldnumber(&rp);   //通过path name来提取逻辑驱动号
     其中get_ldnumber获取id的方式有两种,一种是数字id或者是string id。如果是string id ,则根据_VOLUME_STRS
定义的#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"的这些情况进行对比,然后
给出返回值vol.
     后面将FATFS * fs 赋值给了FATFS[vol],FATFS[vol] = fs;不同的存储介质有对应的一个FATFS结构.其中main.c中使用 的fs[0]、fs[1]是在exfuns.h中定义指向FATFS结构体的指针数组,其为全局变量extern FATFS * fs[_VOLUMES];所以main中能直接使用。
     f_mount(fs[0],"0:",1);
     f_mount(fs[1],"0:",1);
     综上所述两个函数的综上作用是从path中提取了FATFS[vol]数组中的vol编号,并分配了指针fs[i]指向
FATFS[vol]结构体。


3.font_init()字库检查函数分析:
fontok = font_init(); //检查字库是否OK.
     W25QXX_Init((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo));//读出ftinfo结构体数据
     以上函数可以看出对于main.c中的字库,首先对flash中的的字库地址 FONTINFOADDR 1024*1024*12,读取出一个ftinfo大小的结构体
,这个结构体定义为

    __packed typedef struct{
  u8 fontok;    //字库存在的标志,0xaa,字库正常;其他,字库不存在
  u32 ugbkaddr; //unigbk的地址
    u32 ugbksize; //unigbk的大小
  u32 f12addr;  //gbk12的地址
  u32 gbk12size;//gbk12的大小
  u32 f16addr;  //gbk16地址
  u32 gbk16size; //gbk16的地址
          u32 f24addr;
  u32 gkb24size;
}_font_info;  
extern _font_info  ftinfo;        //字库信息结构体
             同时要知道的是fatfs占用了前12M的内存空间(即FONTINFOADDR后),12M以后紧跟着3个字库+UNIGBK.BIN,总大小为3.09M,被字库占用,
不能动
!!!!!15.10M以后,用户可以自由使用,建议用最后的100k字节比较好。
             而对于字库检查是通过10次读finfo结构体的信息,并判断finfo.fontok == 0xAA,才能正确判断字库正常。


4.SD_Init()和updata_font()从SD卡更新字库函数分析:
   上面分析了从flash(W25Q128)中检查字库的方式,但如果检查失败则必须通过SD卡来进行更新字库操作。
 (1).SD_Init()函数初始化了SD卡,通过设置为SDIO初始化、获取卡信息、选中SD卡、设置为4位宽度(MMC卡不能用这种方式)、设置SDIO时钟、DMA
模式、查询模式等进行初始化。


 (2).updata_font(u16 x,u16 y,u8 size,u8 *src);
          strcpy((char*)pname,(char*)src);      //copy src内容到pname
 strcat((char*)pname,(char*)UNIGBK_PATH); 
   res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
          ...
    W25QXX_Read((u8*)buf,((FONTINFOADDR/4096)+i)*4096,4096);
    第一步:其中x、y提示信息的显示地址,size字体大小,src字库来源磁盘:"0:",SD卡;"1:",FLASH盘,"2:",U盘。这个函数首先将指定的盘src(0、1或者2)的UNIGBK目录(//SYSTEM/FONT/UNIGBK.BIN)和GBK12_PATH、GBK16_PATH、GBK24_PATH定义的目录文件进行打开检查是否成功。 
    第二步:然后检查是否FLASH卡(W25Q128)(实验默认为FLASH卡)弄脏(dirty),否则进行擦除操作。
          strcpy((char*)pname,(char*)src);      //copy src到pname
 strcat((char*)pname,(char*)UNIGBK_PATH); 
 res=updata_fontx(x+20*size/2,y,size,pname,0);
    第三步:在确认文件可以打开,flash无dirty或dirty被擦除后,就可以进行第三步的更新操作,将
          updata_fontx(u16 x,u16 y,u8 size,u8 *fxpath,u8 fx)函数分析:
                fftemp = (FIL*)malloc(SRAMIN,sizeof(FIL)); //分配内存
                tempbuf = mymalloc(SRAMIN,4096);           //分配4096个字节
                res = f_open(fftemp,(const TCHAR*)fxpath,FA_READ); //将函数fxpath:0/SYSTEM/FONT/UNIGBK.BIN文件打开
  //并且赋给fftemp.
                上述函数将fxpath路径下的文件打开后,通过f_open()函数得到了该路径目录下的文件的参数,并且赋给了文件
                 结构体FIL。fftemp->fsize就是在f_open()函数后得到的

                switch(fx)
                {
case 0:
ftinfo.ugbkaddr = FONTINFOADDR+sizeof(ftinfo);
                                ftinfo.ugbksize = fftemp->fsize;
flashaddr = ftinfo.ugbkaddr;  
                         .....
}
                上述语句将打开的SD卡的path(有4种情况)后,通过f_open()得到大小,得到每个文件的大小fftemp->fsize,然后将其赋给字库信息全局结构体ftinfo,每个fxpath路径下的文件有两个参数要赋给ftinfo结构体:ftinofo.ugbkaddr和ftinfo.ugbksize。
                while(res == FR_OK)
{
...
res = f_read(fftemp,tempbuf,4096,(UINT *)&bread);//读取数据
...
W25QXX_Write(tempbuf,offx+flashaddr,4096);  //从0处读取4096个数据
...
}
                上述代码是从fftemp结构体使用f_read()函数读取数据到tempbuf,然后将其写入到flash(W25Q128)的地址offx+flashaddr。( 其中fftemp是fxpath路径用f_open()赋予的,所以数据来源于SD卡,数据目的是FLASH )。


                 

你可能感兴趣的:(学习笔记)