好久没更新blog了,本屌最近比较懒了,呵呵~
好的,转入正题吧~上节基于simple-spi把SD卡的驱动编写OK,至于SD驱动的测试,骚年们你们可以自行去调试,在写这个驱动的时候我没遇到什么bug,写完编译就可以用了,这可能是传说中的人品,但是这样写代码没有bug我个人感觉是不爽的,写程序怎么可能没bug呢?
本来按原计划这节是移植znFat文件系统,虽然说ZN兄做出这个文件系统我也很佩服他个人的技术造诣,但是平时在QQ交流群里面老是说我们这些初学者如何如何菜,虽然我在群里平时也不怎么发言,但是给我的感觉老是很不爽,尊敬是尊敬,可能自己愤青的缘故所以老是很不爽那种高高在上的态度,好了,移植znFat文件系统之前已经boot通了,代码有朋友有需要请联系我,但是在这里不打算详细解说这个了,可能我没真正和他本人交流过,但是我现在也就那样的感觉,所以这篇blog改为移植FatFs文件系统。
OK,接下来,到FatFs的官网download源码,我这里用的版本是R0.09b,应该是现在的最新版本,顺便把官网提供的example demoes下下来,移植的过程可以参考demo,移植这个file system非常的简单,简单驳接几个底层函数就OK了。
http://elm-chan.org/fsw/ff/00index_e.html
Download源码和demoes
好,下下来之后先放一边去,小喝两口茶,然后掏出的8G的~~~~~~~U盘?额,SD卡吧,我等穷屌只有1个2G的SD卡,而且还是公司偷偷借用的,仅仅是借用而且啦~然后拿出你的套套,插进你的电脑,然后,格了吧~记得选择Fat的格式,Fat32吧,难说有的高富帅用得起大容量的SD卡,统一一下吧,好,格好之后,用winhex来看看这个SD卡的分区情况
看到没有~看到没有,真的只有2G啊,童叟无欺啊,绝对只是借用公司的而已啊~
然后,在看看boot sector,看看启动扇区里面都有些什么东东了。
很好很强大,话说用的winhex也是盗版的,唉,对于崇尚开源的我们情何以堪,MS的FAT文件系统不多说了,随便google就可以看到启动扇区的信息代表什么了,或者找特权同学那本《深入浅出XXX》看SD卡有关的章节和知识就OK了。
这里注意一下的就是,有时候在MSWinX格式化之后启动扇区不是写入在第0扇区的,如果是这样情况不幸地发生了,那就怪人品不行吧,解决方法还是有的,就是用顺便用这个盗版的winhex将启动扇区的信息改写到第0扇区吧~亲~自己动手做实验的,我自己格的时候也是人品不行啊,说多了都是泪啊~
貌似就差不多了咧,把你的SD卡插上卡槽卡进去你的开发板吧~
至于基于simple-spi这个core的SD card的bare driver上篇blog已经搞好了,忘记了自己去看看吧~
再下来,就把几个简单的函数驳接到fatFs的硬件抽象层就OK了,好最简单的,见证奇迹的时候到了。
在见证奇迹之前,我们看看fatFs目录下都有些什么鸟东西。
/option:不明?
Readme文件:叫你自己看
Ff.c:fatFs文件系统的实现,不作修改
Ff.h:fatFs用到的结构体定义啊,函数声明啊,不管
Ffconf.h:fatFs文件系统的配置头文件,有要特殊服务的自行修改
Integer.h:平台相关的基本数据类型redefine,懒得管
Diskio.h:diskio.c结构体声明啊,函数声明啊,不管
Diskio.c:这个就是硬件抽象层的src了,我们就是要改这个鸟东西,下面,我直接把源码粘出来,最简单的实现就是这样子的了,毫无疑问~
那就这样吧~
再休息一下,抽支烟先,码字累死本屌了,不过真心没有画电路和码代码来的累,发发牢骚,我觉得在天朝的程序猿,这样说不是很正确,哥真正的技术岗位是有个很专业的学术名称的:嵌入式软硬件工程师,包括职责有:帮领导擦屁股,啃历史遗留下来的毫无美感的代码,帮助老大完成那些繁琐又恶心的评审文档和产品使用说明,加班做那些没有技术含量又不得不做的测试工作,在领导的唾骂和嫌弃中完成电路图纸设计,帮助产线哥哥姐姐们解决一般性问题,还有最最恶心的一个:码代码~说到这里,我只想说三个字:求带走~
对号入座的握个抓~
啊~多么痛的领悟~~~悟~~~
/*-----------------------------------------------------------------------*/ /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2013 */ /*-----------------------------------------------------------------------*/ /* If a working storage control module is available, it should be */ /* attached to the FatFs via a glue function rather than modifying it. */ /* This is an example of glue functions to attach various exsisting */ /* storage control module to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ #include "diskio.h" /* FatFs lower layer API */ #include "sdcard.h" /* SD card driver base on simple-spi ipcore */ #include "application.h" /* for debug via UART */ /* Definitions of physical drive number for each media */ #define ATA 0 #define MMC 1 #define USB 2 /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber (0..) */ ) { return RES_OK; } /*-----------------------------------------------------------------------*/ /* Get Disk Status */ /*-----------------------------------------------------------------------*/ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber (0..) */ ) { return RES_OK; } /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address (LBA) */ BYTE count /* Number of sectors to read (1..128) */ ) { if(count==1){ SDReadSector(sector, buff); // raw_printk("SD card one block reading ...\n"); } else{ SDReadnSector(count, sector, buff); // raw_printk("SD card multiblocks reading ...\n"); } return RES_OK; } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ #if _USE_WRITE DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber (0..) */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector address (LBA) */ BYTE count /* Number of sectors to write (1..128) */ ) { if(count==1){ SDWriteSector(sector, buff); // raw_printk("SD card one block writting ...\n"); } else{ SDWritenSector(count, sector, buff); // raw_printk("SD card multiblocks writting ...\n"); } return RES_OK; } #endif /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ #if _USE_IOCTL DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { return RES_OK; } #endif DWORD get_fattime(void){ /* Nothing to do */ return RES_OK; }
抽完了,继续干活,上面的代码是不是很神奇,仅仅改掉4行啊,就完成移植了,我人生的代码量又大大地增加了4行,艹~
好,移植完成~但是还要在makefile中补充几行编译命令~啊,人生的代码量又可以增加了,尼玛~然后,我和我的小伙伴们都惊呆了~
这移植做的,好吧~我承认了,其实这篇blog我都是在扯淡的,不幸点进来的朋友们不要吐槽了,非要吐槽的话可以留言我们互吐~啊呵呵呵呵~
以上摘自和一位大神的聊天~
废话不说了,接下来在应用层那边写个test code试试移植是不是成功了~
#include "application.h" FATFS Fatfs; /* File system object */ FIL Fil; /* File object */ BYTE Buff[128]; /* File read buffer */ void die ( /* Stop with dying message */ FRESULT rc /* FatFs return value */ ) { printf("Failed with rc=%u.\n", rc); for (;;) ; } #if 1 int main() { uart_init(); raw_printk("uart init ...\n"); SDReady(); raw_printk("SD card init ...\n"); FRESULT rc; /* Result code */ DIR dir; /* Directory object */ FILINFO fno; /* File information object */ UINT bw, br, i; f_mount(0, &Fatfs); /* Register volume work area (never fails) */ printf("\nOpen an existing file (message.txt).\n"); rc = f_open(&Fil, "MESSAGE.TXT", FA_CREATE_ALWAYS | FA_READ | FA_WRITE); if (rc) die(rc); printf("\nType the file content.\n"); for (;;) { rc = f_read(&Fil, Buff, sizeof Buff, &br); /* Read a chunk of file */ if (rc || !br) break; /* Error or end of file */ for (i = 0; i < br; i++) /* Type the data */ putchar(Buff[i]); } if (rc) die(rc); printf("\nClose the file.\n"); rc = f_close(&Fil); if (rc) die(rc); printf("\nCreate a new file (hello.txt).\n"); rc = f_open(&Fil, "HELLO.TXT", FA_CREATE_ALWAYS | FA_READ | FA_WRITE); if (rc) die(rc); printf("\nWrite a text data. (Hello world!)\n"); rc = f_write(&Fil, "Hello world!\r\n", 14, &bw); if (rc) die(rc); printf("%u bytes written.\n", bw); printf("\nClose the file.\n"); rc = f_close(&Fil); if (rc) die(rc); printf("\nOpen root directory.\n"); rc = f_opendir(&dir, ""); if (rc) die(rc); printf("\nDirectory listing...\n"); for (;;) { rc = f_readdir(&dir, &fno); /* Read a directory item */ if (rc || !fno.fname[0]) break; /* Error or end of dir */ if (fno.fattrib & AM_DIR) printf(" <dir> %s\n", fno.fname); else printf("%8lu %s\n", fno.fsize, fno.fname); } if (rc) die(rc); printf("\nTest completed.\n"); for (;;) ; do{ }while(1); return 0; } #endif
这个我是抄的,具体抄哪里,具体自己找吧~说句实在话,我写代码绝对是个懒人~
好,根据以往的经验,sim是sim不出来了~直接load到CPU上面跑吧,好打开我们的串口工具~startup,出来log了~
还是那个SOC,core的话自己加进去了,有懒人问我要也OK~欢迎来搞~
然后,打开你的tftp服务器,由于我在linux上面没搭,用win版的凑合着先吧
然后就load到ram里面,步骤就面谈了,自行解决~
妥妥滴load进来了,然后见证奇迹的发生~
看到没有,这就OK,测试代码就能工作,但是要把文件系统用好起来的话,移植的硬件抽象层还是写完善一点吧,ffsample里面有其他架构的移植参考demoes,自己去看吧,然后你再把SD卡插到你电脑上面看看是不是原来空的SD卡现在又两个txt文件,是吧,是了吧~然后就没有然后了。
那就说说为什么要移植这个文件系统吧,目前的进度是小弟我自己写了一个很拙劣的i2s的core,现在bare driver也能跑起来了,能驱动起wm8731这个codec发出正弦波,下个步骤就是写个MP3的解码程序,但是发觉没有文件系统操作起来很不方面,所以花了我1个小时的时间去把这个fatFs移植起来~
那下步工作就是想用4篇blog的篇幅有rtl代码设计,bare driver,MP3解码设计,linux端的音频驱动学习,ALSA的codec驱动设计完完整整的把自己如何设计在or1200上设计一个音频小系统的过程和大家分享分享~
但是至于什么时候能完成,看小弟我的心情吧,心情好,休息一下,心情不好,更要多休息一下~也希望有兴趣的朋友们一起研究研究哈~
顺带看看这里有没有组织上的搞技术的屌丝,可以交交朋友哈~~~天王盖地虎~~~!记得吐槽一下~