当前位置:首页 > 单片机 > 单片机
[导读]对于固态存储器,其存储容量可以很大,往往需要一款文件系统对存储器用户数据进行组织文件的管理。它对文件存储器空间进行组织和分配,负责文件的存储并对存入的文件进行保护和检索。在嵌入式系统中,往往需要采用wi

对于固态存储器,其存储容量可以很大,往往需要一款文件系统对存储器用户数据进行组织文件的管理。它对文件存储器空间进行组织和分配,负责文件的存储并对存入的文件进行保护和检索。在嵌入式系统中,往往需要采用windows兼容的文件系统,像相机的照片、视频监控、语音产品等,很多都需要从windows计算机上提取资源或在windows计算机上进一步处理。Fatfs由于其开源免费,支持fat32,受到了广泛的应用,笔者此处就s3c2416移植Fatfs,对sd卡进行读写访问作一个简单的介绍。

1. Fatfs概述

Fatfs是由日本工程师ChaN所编写的fat文件系统模块,从06年发布第一个Fatfs版本开始,作者就从未停止维护和更新。Fatfs的编写遵循ANSI C,并且完全与磁盘I/O层分开。它不依赖于硬件架构,代码和工作区占用空间小,使之可以嵌入到各个低成本的微控制器中,如AVR、8051、PIC、ARM、Z80、68K等。

2. 代码准备

Fatfs源码,请读者自行从Fatfs官网http://elm-chan.org/fsw/ff/00index_e.html下载最新的源码。

s3c2416启动代码工程,启动代码是s3c2416/50/51这系列arm9芯片在运行用户c代码main函数之前必须先运行的代码,启动代码支持sd、Nand启动,为用户设置系统时钟,初始化内存,自动识别启动设备并搬移代码到RAM,MMU映射,中断管理等,用户只需专注于用c开发其它功能函数即可。关于启动代码以及启动代码的实现过程,笔者前面章节有非常详细的介绍。此处以GCC下移植Fatfs为讲解,下载”GCC启动代码工程应用实例”中的启动代码源码即可。如果在MDK下开发,下载”MDK启动代码工程应用实例”中的启动代码源码。

用户代码,用c开发的所有功能代码,其中,用户代码入口为main()函数,在这里需要实现sd卡驱动模块等。

3. 工程搭建

在linux操作系统下任一路径下新建一个Fatfs_GCC的工程目录,该目录下新建Fatfs目录,下载Fatfs最新源码并解压,把src目录内容全部拷贝到Fatfs目录下。

把启用代码目录start_code拷贝到Fatfs_GCC目录下,这部分代码无需任何的修改。并保留其中的Makefile这些文件,按照Makefile的模板添加各个目录的Makefile。GCC启动代码下的工程管理Makefile提取自uboot,可以方便地增加源代码以及代码目录。

在Fatfs_GCC目录下新建apps目录,用来保存应用相关的源码以及各个模块驱动。

4. Fatfs移植

Fatfs模块完全独立于磁盘I/O层,因此底层磁盘I/O访问并不属于Fatfs的模块部分,用户必须自己实现这部分用来访问存储设备。通常在diskio.c中实现这六个函数disk_initialize()、disk_status()、disk_read()、disk_wirte()、disk_ioctl()、get_fattime()即可。如果使能了OS相关的特性,则还需额外实现进程/内存函数。sd卡底层驱动实现在前面的章节有详细的介绍,此处直接在Fatfs移植接口中调用sd驱动模块中的相关函数。

4.1. disk_initialize函数

初始化存储设备,若设备初始化成功,应清除STA_NOINIT这个标志返回。若初始化不成功,应置位STA_NOINIT标志再返回。如果在初始化时,未检测到卡,可设置STA_NODISK标志表明无卡,检测到写保护,可设置STA_PROTECT标志表明写保护。

static DSTATUS State = STA_NOINIT;

DSTATUS disk_initialize (

BYTE pdrv /* Physical drive nmuber (0..) */

)

{

if (pdrv != 0) {

return STA_NOINIT; // 仅支持driver0

}

if (!Hsmmc_Init()) { // 调用sd卡初始化

State &= ~STA_NOINIT; // 初始化成功

} else {

State |= STA_NOINIT;

}

return State;

}

4.2. disk_status函数

获取设备的状态,返回STA_NOINIT、STA_NODISK、STA_PROTECT这三个标志的组合。磁盘设备的状态随时都可能发生变化,例如初始化后的sd卡在某一时刻被拔出,此时无卡,Fatfs通过disk_status函数重新获知STA_NODISK无卡这一标志。

DSTATUS disk_status (

BYTE pdrv /* Physical drive nmuber (0..) */

)

{

if (pdrv != 0) {

return STA_NOINIT; // 仅支持driver0

}

return State;

}

4.3. disk_read函数

读取扇区,Fatfs通过该函数从磁盘某一扇区地址开始获取一块或多块扇区的数据,Fatfs最多支持一次性读写128个扇区的数据,通常磁盘都支持多块读、多块写,并且这样的读写性能远远好于分单块的读写。

DRESULT disk_read (

BYTE pdrv, /* Physical drive nmuber (0..) */

BYTE *buff, /* Data buffer to store read data */

DWORD sector, /* Sector address (LBA) */

UINT count /* Number of sectors to read (1..128) */

)

{

if (pdrv || !count) {

return RES_PARERR;

}

if (State & STA_NOINIT) {

return RES_NOTRDY;

}

if (!Hsmmc_ReadBlock(buff, sector,count)) {

return RES_OK; // 读取成功

} else {

return RES_ERROR; // 读取出错

}

}

4.4. disk_wirte函数

写扇区,Fatfs通过该函数从磁盘某一扇区地址开始写入一块或多块扇区的数据。如果只读(_FS_READONLY == 1),可以不实现该函数。

#if _USE_WRITE

DRESULT disk_write (

BYTE pdrv, /* Physical drive nmuber (0..) */

const BYTE *buff, /* Data to be written */

DWORD sector, /* Sector address (LBA) */

UINT count /* Number of sectors to write (1..128) */

)

{

if (pdrv || !count) {

return RES_PARERR;

}

if (State & STA_NOINIT) {

return RES_NOTRDY;

}

if (State & STA_PROTECT) {

return RES_WRPRT;

}

if (!Hsmmc_WriteBlock((unsignedchar *)buff, sector, count)) {

return RES_OK; // 写成功

} else {

return RES_ERROR; // 写错误

}

}

#endif

4.5. disk_ioctl函数

控制设备相关的功能,Fatfs使用5个设备独立的命令控制/获取设备特定的功能。

CTRL_SYNC:写同步,在关闭文件等操作时,如果磁盘I/O口层使用了写缓存,那么通知磁盘I/O口层把写缓存中的数据写回到磁盘中。对于没有写缓存,即每次disk_write均写入到磁盘中,无需处理该命令,只需返回RES_OK即可。在可写时_FS_READONLY == 0,该命令才会被使用。

GET_SECTOR_COUNT:获取磁盘的总扇区数,在用f_mkfs()格式化文件系统,f_fdisk对磁盘分区时均会使用这个命令来获取磁盘的总扇区数,对于sd卡,通过CSD获取卡容量信息。在支持格式化文件系统或多分区的情况下(_USE_MKFS == 1 或 _MULTI_PARTITION== 1),该命令才会被使用。

GET_SECTOR_SIZE:获取磁盘一个扇区的字节数,有效值为512、1024、2048或4096。对于大部分的系统,所有内存卡,硬盘,通常返回扇区大小为512字节,但对于flash,一页可能为512字节,也可能为1k字节,2k字节,4k字节,需要根据具体的flash页大小进行配置。

GET_BLOCK_SIZE:以扇区为单位获取擦除块的大小。在用f_mkfs()格式化文件系统时,用来使数据区对齐到擦除块。例如,第一个擦除块往往用来保存系统信息等,真正的数据在第二个擦除块位置开始存放。该命令并不重要,可直接返回1表明1个扇区对齐。此处与原作者移植例程保持一致,对sd2.0版本卡,返回AU(可分配单元)的大小,sd1.0版本卡,返回擦除块大小。在_USE_MKFS == 1时,该命令才被使用。

CTRL_ERASE_SECTOR:擦除某一段扇区,对于flash,都是要先擦除才能正确写入,对于nor、nand flash,某一个文件不再使用时(例如删除或被覆盖),先发出这个命令强制设备擦除这个文件所在的空间区域,之后在disk_write无需再对flash进行擦除操作,因为每次文件不再使用时,都已经先擦除了这部分。对于sd卡等,这个命令没有任何用处,因为sd卡接收到块写命令均是先擦除再写。如果再开启这个命令_USE_ERASE == 1,相当重复擦除。对于sd卡,建议设置_USE_ERASE == 0,不使用这个命令。

#if _USE_IOCTL

DRESULT disk_ioctl (

BYTE pdrv, /* Physical drive nmuber (0..) */

BYTE cmd, /* Control code */

void *buff /* Buffer to send/receive control data */

)

{

unsigned char CSD[16];

unsigned charSdState[64];

unsigned int c_size,c_size_multi, read_bl_len, sector_size, au_size;

DRESULT Result =RES_ERROR;

if (pd

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

上海2023年2月16日 /美通社/ -- 近日,诺华中国宣布与中国红十字基金会正式启动"中国地中海贫血救助项目"广西地区专项援助,将在当地定向资助困难家庭地中海贫血患儿,同时通过相关医生培...

关键字: BSP 控制 移植 大众

北京2022年12月7日 /美通社/ -- 2022年12月3日,由高博医学(血液病)广东研究中心南方春富(儿童)血液病研究院、南方医科大学南方医院共同主办的高博医学论坛·华南造血干细胞移植论坛通过线下线上...

关键字: 移植 HD PID 血细胞

捐款近4000万 上海2022年12月7日 /美通社/ -- 2022年12月7日下午,中芯国际"芯肝宝贝计划"十年纪念暨2022年度捐赠仪式在上海仁济医院举行。十年来,该项目捐赠善款总额近4000...

关键字: 中芯国际 移植

北京2022年11月14日 /美通社/ -- 2022年10月,高博医学(血液病)北京研究中心北京高博博仁医院造血干细胞移植科迎来了五周岁"生日"。在吴彤主任带领下,移植科于2017年从无到有,历经五...

关键字: 移植 OS MT CD

上海2022年11月6日 /美通社/ -- 在第五届中国国际进口博览会期间,武田制药携5款创新产品亮相武田罕见遗传与血液疾病领域专场发布会。用于移植后抗巨细胞病毒(CMV)感染或疾病治疗[1]的马立巴韦[2]迎来&quo...

关键字: 移植 BSP CD FDA

亘喜生物科技集团宣布正在中国开展的、旨在全面评估GC007g治疗复发/难治性急性B淋巴细胞白血病效果的1/2期注册性临床试验顺利进入2期研究阶段,首例入组患者已给药。GC007g是亘喜生物旗下的一款靶向CD19的供者来源...

关键字: 移植 CD

北京2022年9月9日 /美通社/ -- 诺诚健华(香港联交所代码:09969)今天宣布,tafasitamab (Minjuvi®)联合来那度胺治疗不适合自体干细胞移植 (ASCT) 条件的复发/难治弥漫性大B...

关键字: VI NJU BSP 移植

苏州2022年8月19日 /美通社/ -- 近日,华中科技大学同济医学院附属协和医院心外科董念国教授团队运用与心擎医疗联合研发的短中期体外全磁悬浮心室辅助装置MoyoAssist®,成功救治三例危重的终...

关键字: 磁悬浮 移植 IC 静脉

上海2022年8月17日 /美通社/ -- 2022年8月16日,聚焦于基因和细胞治疗的上海邦耀生物科技有限公司(以下简称"邦耀生物")宣布,其...

关键字: CD 移植 BSP ISP

苏州2022年6月28日 /美通社/ -- 2022年6月23日,首都医科大学附属北京安贞医院(以下简称安贞医院)与苏州心擎医疗技术有限公司(以下简称心擎)在北京、苏州两地线上连线,隆重召开体外心室辅助系统临床...

关键字: BSP 磁悬浮 创始人 移植
关闭
关闭