STM32下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,并进行擦写均衡分析
STM32F407移植FATFS文件系统(版本R0.09b)到SD卡(硬件SPI总线)
STM32F407移植FATFS⽂件系统(版本R0.09b)到SD卡(硬件SPI总线)⼀、序⾔经常在⽹上、群⾥看到很多⼈问关于STM32的FATFS⽂件系统移植的问题,刚好⾃⼰最近的⼯程项⽬需要使⽤SD卡,为了让⼤家少⾛弯路,我把我的学习过程和⽅法贡献给⼤家。
⼆、SD卡简介安全数字卡(简称SD卡),最初引进应⽤于⼿持式可携带电⼦产品,在⼀个⼩尺⼨产品上可靠的存储数据,如移动电话,数码相机等。
1、SD卡简介请参考如下博⽂2、SD卡种类请参考如下博⽂3、SD卡简介和种类请参考如下博⽂4、MMC、SD、TF、SDIO、SDMMC简介三、SD卡总线协议简介SD卡⽀持2种总线协议,即SDIO总线协议和SPI总线协议。
SDIO总线协议速度快,SPI总线相对SDIO总线速度要慢很多,但是⽬前市⾯上很多单⽚机不⽀持SDIO总线协议,只有中⾼端单⽚机(例如:STM32F407)才⽀持SDIO总线协议。
1、SDIO总线协议利⽤该总线协议,可以使⽤最多四条数据线实现主机与SD卡之间的数据传输,所以速度相对⽽⾔可以达到最⾼,但是需要主机具有SDIO控制器,才可以使⽤该协议。
2、SPI总线协议如果主机不⽀持SDIO协议,那么可以使⽤SPI协议对SD卡进⾏操作。
虽然速度⽐SDIO慢,但是硬件上更加简单,只需要四根线便可以实现与SD卡进⾏通讯。
3、SDIO协议与SPI协议的⽐较SDIO协议与SPI协议相较⽽⾔,SDIO协议读写SD卡的速度更快,再加上其⽀持4线模式,即利⽤4条数据线,同时发送4Bits数据,数据的传输效率就更⾼了,但是由于使⽤的引脚较多,所以也导致了控制相对⽐较困难。
⽽SPI外设只具有两条数据线MISO和MOSI,分别⽤作数据的输⼊和输出,由于引脚较少,所以控制相对较容易。
但是,数据的传输效率相对⽽⾔就⽐较低了。
但是,两中协议的共同之处在于:均是通过命令实现对SD卡的控制,仍然是结合状态机实现编程。
4、SD卡如何⼯作在SPI模式下当SD卡上电之后,只有第⼀次发送的CMD0命令才可以选择SD卡⼯作在SPI模式下。
STM32F429利用CUBEMX移植FATFS文件系统成功!!!
STM32F429利⽤CUBEMX移植FATFS⽂件系统成功⽂件系统对于⼀个专业的嵌⼊式系统⽽⾔必不可少,博主这两天利⽤STM32F429成功移植了FATFS,特来分享⼀下学习⼼得,避免新⼈采坑。
我是在SD卡上实现的,因此你需要利⽤SDIO接⼝扩展⼀个SD卡,具体实现如下:进⼊Configuration界⾯,基本参数的不⽤配置,但是需要开启中断和DMA,配置如下:点击OK,关闭Configuration窗⼝。
在MiddleWares下拉列表中打开FATFS,选中SD卡。
进⼊FATFS的Configuration界⾯,配置如下:解释⼀下改动的两个参数,⼀个选择读取中⽂类型的⽂件,另⼀个是使能长字节名称命名(如果不选择,只有8字节,超过8字节会出现Hardware Fault),⽂件系统的磁盘选择3个(⽅便挂载其他内存)最后,再设置选择中,把stack的空间⼤⼩设置为0X1000⼤⼩。
以上,便完成可在CUBEMX中配置FATFS⽂件系统,点击⽣成⼯程⽂件。
可以看到,在⼯程⽬录下,⽣成了这样⼀些⽂件:具体什么内容先不管,我们需要在main中添加⼀些代码测试我们的⽂件管理系统。
⾸先添加如下所⽰的全局变量:/* USER CODE BEGIN PV *//* Private variables ---------------------------------------------------------*/uint32_t byteswritten; /* File write counts */uint32_t bytesread; /* File read counts */uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */uint8_t rtext[100]; /* File read buffers */char filename[] = "STM32cube.txt";/* USER CODE END PV */在初始化之后,while(1)之前添加如下代码int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_TIM6_Init();MX_FMC_Init();MX_USART1_UART_Init();MX_TIM7_Init();MX_USART3_UART_Init();MX_DMA2D_Init();MX_LTDC_Init();MX_SPI5_Init();MX_SDIO_SD_Init();MX_FATFS_Init();/* Initialize interrupts */MX_NVIC_Init();/* USER CODE BEGIN 2 */delay_init(180);LED_Init();KEY_Init();SDRAM_Init();LCD_Init();ESP8266_Init(); //WIFI ͨѶģ¿éW25QXX_Init(); //Íⲿ SPI FLASH --- 32MBFTL_Init(); //Íⲿ NAND FLASH --- 512MBmy_mem_init(SRAMIN); //½«SRAMÖÐ60KBÄÚ´æÓÃÓÚÄÚ´æ¹ÜÀíϵͳ my_mem_init(SRAMEX); //½«SDRAMÖÐ15MBÄÚ´æÓÃÓÚÄÚ´æ¹ÜÀíϵͳ ITEnable();PeriphInit();GUI_Init();Show_SDcard_Info();LCD_ShowString(400,400,400,24,24,"****** FatFs Example ******");retSD = f_mount(&SDFatFS, "0:", 0);if(retSD){LCD_ShowString(400,440,400,24,24,"****** mount error ******");LCD_ShowNum(800,440,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,440,400,24,24,"****** mount success ******");retSD = f_open(&SDFile, filename, FA_CREATE_ALWAYS | FA_WRITE);if(retSD){LCD_ShowString(400,480,400,24,24,"****** open file error ******");LCD_ShowNum(800,480,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,480,400,24,24,"****** open file success ******");retSD = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten);if(retSD){LCD_ShowString(400,520,400,24,24,"****** write file error ******");LCD_ShowNum(800,520,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,520,400,24,24,"****** write file success ******");retSD = f_close(&SDFile);if(retSD){LCD_ShowString(400,560,400,24,24,"****** close file error ******");LCD_ShowNum(800,560,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,560,400,24,24,"****** close file success ******");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}OK,编译通过,下载程序,运⾏结果如下所⽰:之后你便可以在SD卡中找到你创建的⽂件STM32cube.txt。
基于STM32的FATFS文件系统移植
基于STM32的FATFS文件系统移植经过将近1个月的时间,终于完成了STM32是FATFS文件系统移植,说来是够艰辛的,SDIO章节是我学习cortex m3以来消耗时间最多的章节。
这里说一些个人对于SDIO的看法,其实SDIO属于意法半导体公司在cortex m3内核之外(在芯片之内)添加的功能外设,完全属于意法的杰作了。
关于SD卡的读写,分为SPI模式和SD模式(专用模式),这两种模式都必须遵循SD2.0协议。
SPI模式控制方法相对较为简单,操作简洁,但失去了速度;SD模式控制方法相对较为复杂一点,操作繁琐,但具有高速的特点。
FATFS文件系统是一种兼容性比较高的文件管理系统,兼容FAT32、FAT16。
关于文件系统的细节,如果认真研究的话,应该会觉得作者的伟大,惊叹代码的绝妙。
我们要想移植FATFS,首先要做的是编写基于SDIO模式的SD卡底层驱动,这部份完整的驱动代码较多,大概有2000多行,但我们首先需要克服心理作用,再长的代码只要理解之后,都很简单。
意法在参考手册中介绍SDIO时,上下文比较乱,其中还夹杂讲解了一些SD2.0协议,使得初学者云里雾里。
因为SDIO是属于一种完全的外设接口,所以在讲解的过程中必须与实际的外设SD卡联系起来。
STM32的SDIO接口兼容性很高,可以兼容SD1.0卡、2.0卡、MMC 卡、多媒体卡等,与多媒体卡4.2支持三种不同的数据总线模式:1位、4位和8位,在8位的模式下速度可以达到48MHZ,但在SD2.0协议中只支持两种总数总线模式:1位和4位,在SDIO中存在两种状态机:命令状态机(CPSM)和数据状态机(DPSM),两者的使能信号独立,用于控制外部双向驱动器,命令是通过CMD命令线单线串行发送的,而数据是由于DATx数据线传输(1位或4位),每当CPSM发送一条命令给卡时,如工作正常的话,卡都会有与CPSM中设置响应格式相对应的响应内容(短响应与长响应),两者的细节在下面讲到。
基于STM32F407平台实现FATFS读写大容量(128G)SD卡的心得
基于STM32F407平台实现FATFS读写大容量(128G)SD卡的心得本人是沈阳大学的一名小白,之前,无论是STM32,还是FATFS,都是小白一个,甚至不理解那是什么东西,但是据说这种技术目前为止好像是读写大容量卡挺费劲,只能64G,就到头了,但是最近接到一个任务就是做一个数据记录仪而且要把这个东西做成128G 的。
废话不多说,直接来把。
首先你要知道FATFS 是一个文件管理系统,看他的手册,分为应用层,底层驱动等等,但是对于我们嵌入式开发者来说,移植他,我们需要的是修改底层驱动!应用他给出的API 实现自己的任务。
修改底层驱动!应用他给出的API 实现自己的任务。
修改底层驱动!应用他给出的API 实现自己的任务。
1、修改底层驱动官网下载,需注意他的版本,如果你做32G ,64G, OK 那你下载哪个版本都可以,建议下载低版本,如0.10 版本左右的都可以。
如果你想做大容量卡,那一定要移植0.12 之后的版本,现在我写这篇文章的时候,最新版是0.13a,所以我就简单说一下0.13a。
0.13a 的底层驱动,也就是你下载下来的有一个diskio.c 的文件,你打开。
正常的移植,是在这里写或者修改底层驱动,底层驱动是什么呢,例如我这次用的是SDIO 操作读写SD 卡的,大家都知道,SDIO 操作SD 卡有两种方式,一个是SPI,一个是SDIO。
那我要写的就是这两种中的一个了。
我用的是SDIO,因为这种速度块。
继续说,当你打开0.13a 的diskio.c 的时候,你会发现这帮人TMD 写的很随意,这里如果你是个大手你可以自己写好你的底层驱动(就是刚才我说的那个如何通过SDIO 操作SD 卡),如果嫌费劲,直接拿你开发板给出的例程里的diskio.c(每个嵌入式开发者手里都会有开发板吧?!)因为它给出这个一定是调好的!。
STM32之FATFS文件系统(SPI方式)笔记
STM32之FATFS文件系统(SPI方式)笔记BY:T7Date:20171202At:YSU_B307开发环境:uVision: V5.12.0.0STM32F103V8T6库版本: STM32F10x_StdPeriph_Lib_V3.5.0FATSF : ff13a工程版本:FATFS_V1日期:硬件连接:SPI1_CS -> PA4 SPI1_CLK -> PA5 SPI1_MISO -> PA6 SPI1_MOSI -> PA7工程功能:建立在SPI_SD的基础上,完成文件系统的初步接触。
一、FATFS文件系统1.使用开源的FAT文件系统模块,其源代码的获取从官网:目前最新版本是:ff13a2.解压后得到两个文件:其中,documents相当于STM32的固件库使用手册,介绍FATFS系统的函数使用方法,source 中则是需要用到的源代码。
因为FATFS使用SD卡,所以FATFS的基础是SD卡的正常读写,这里采用SPI模式。
二、STM32之SD卡_SPI模式1.硬件连接:SPI1_CS -> PA4 SPI1_CLK -> PA5 SPI1_MISO -> PA6 SPI1_MOSI -> PA72.SPI模式下STM32读写SD卡的工程结构在确定STM32使用SPI模式读写SD卡没有问题后,进入FATSF文件系统的实验,另源代码在文档最后。
三、FATSF文件系统移植1.配置工程环境1)STM32读写SD卡-SPI模式成功2)将解压后的ff13a整个文件夹赋值到工程目录下,如图:3)返回到MDK界面下,添加ff13a项目组,并把ff13a\source\目录下ff.c,diskio.c,ffunicode.c,ffsystem.c添加到项目组中,如下图:4)在Target Options的C++编译器选项中添加文件包含路径,如下图四、为FATSF文件系统添加底层驱动(一)在diskio.c中添加函数代码1.DSTATUS disk_status (BYTE pdrv); 添加完成后如下图2.DSTATUS disk_initialize (BYTE pdrv); 添加完成后如下图3.DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);4.DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);5.DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);6.DWORD get_fattime (void);注意:在diskio.c中DEV_MMC的宏定义要为0,如下图(二)打开Ffconf.h函数1.改变FF_CODE_PAGE的值如下2.改变FF_USE_LFN的值如下五、Main主函数Main.c函数如下代码:#include "main.h"#define ONE_BLOCK 512#define TWO_BLOCK 1024uint8_t sd_RxBuf[TWO_BLOCK];//SD卡数据j接收缓存区uint8_t sd_TxBuf[TWO_BLOCK] = {0};//SD卡数据j接收缓存区FRESULT res;//读写文件的返回值FIL ;//文件系统结构体,包含文件指针等成员UINT br,bw;//Fil R/W countBYTE [ONE_BLOCK];// BUFFER//BYTE Tx[] = "This is the FATFS System!\r\n";BYTE Tx[] = "中文文件系统实验!\r\n";static const char * FR_Table[]={"FR_OK:成功", /* (0) Succeeded */"FR_DISK_ERR:底层硬件错误", /* (1) A hard error occurred in the low level disk I/O layer */"FR_INT_ERR:断言失败", /* (2) Assertion failed */"FR_NOT_READY:物理驱动没有工作", /* (3) The physicaldrive cannot work */"FR_NO_FILE:文件不存在", /* (4) Could not find the file */"FR_NO_PATH:路径不存在", /* (5) Could not find the path */"FR_INVALID_NAME:无效文件名", /* (6) The path name format is invalid */"FR_DENIED:由于禁止访问或者目录已满访问被拒绝", /* (7) Access denied due to prohibited access or directory full */"FR_EXIST:由于访问被禁止访问被拒绝", /* (8) Access denied due to prohibited access */"FR_INVALID_OBJECT:文件或者目录对象无效", /* (9) The object is invalid */"FR_WRITE_PROTECTED:物理驱动被写保护", /* (10) The physical drive is write protected */"FR_INVALID_DRIVE:逻辑驱动号无效", /* (11) The logical drive number is invalid */"FR_NOT_ENABLED:卷中无工作区", /* (12) The volume has no work area */"FR_NO_:没有有效的FAT卷", /* (13) There is no valid FAT volume */"FR_MKFS_ABORTED:由于参数错误f_mkfs()被终止", /* (14) The f_mkfs() aborted due to any parameter error */"FR_TIMEOUT:在规定的时间内无法获得访问卷的许可", /* (15) Could not get a grant to access the volume within defined period */"FR_LOCKED:由于文件共享策略操作被拒绝", /* (16) The operation is rejected according to the policy */"FR_NOT_ENOUGH_CORE:无法分配长文件名工作区", /* (17) LFN working buffer could not be allocated */"FR_TOO_MANY_OPEN_FILES:当前打开的文件数大于_FS_SHARE", /* (18) Number of open files > _FS_SHARE */"FR_INVALID_PARAMETER:参数无效" /* (19) Given parameter is invalid */};int main(void){int i = 0;FATFS fs;//记录文件系统盘符信息的结构体LED_Init();USARTx_Init();/* 调用f_mount()创建一个工作区,另一个功能是调用了底层的disk_initialize()函数,进行SDIO借口的初始化*/res = f_mount(&fs, "0:", 1 );if (res != FR_OK){printf("挂载文件系统失败(%s)\r\n", FR_Table[res]);}else{printf("挂载文件系统成功(%s)\r\n", FR_Table[res]);}/* 调用f_open()函数在刚刚开辟的工作区的盘符0下打开一个名为Demo.TXT的文件,以创建新文件或写入的方式打开(参数"FA_CREATE_NEW | FA_WRITE"),如果不存在的话则创建这个文件。
FatFs在32位微控制器STM32上的移植
0引言 目前微控制器的片上Flash越来越大,一般都有数十 到数百l(B的容量,可以满足多数情况下的应用,但在某 些应用中片上的Flash就不足,比如数据采集、文件存贮。 可见大容量数据的存贮是微控制器应用系统的瓶颈。为了 突破容量的限制,可以采取外扩存贮器,如u盘、移动硬 盘、SD卡等,并移植文件系统便于对文件进行管理。
AnnIication
FatFs m。duIe
Low leve disk I/0 (SD,ATA.USB,NAND)
l RTC
凸一国
2.2 SD卡初始化及读写
图6为SD卡的初始化过程,在SD卡刚刚上电的时候 至少要延时等待74个时钟周期,然后发送复位命令。
要注意的是,STM32连接SD卡的GPIO引脚频率至少 要配置为10MHz以上SD卡才能正常工作,SD卡初始化阶 段SPI的时钟频率必须小于400k,一旦初始化完成可以设 置为高速模式,SPI模式数据传输为高位在前。
2.3移植过程
圈6.SD卡的初始化
移植的第1步是定义数据类型,修改integer.h,使其 中定义的数据类型与相应的Mcu十fl匹配。
第二步是配置ff.h,首先可以看到#define
WORD ACCESS 0这一句,O表示微控制可以按位访问,l
表示微控制按字节访问,STM32是按字节访问的,所以
将其修改为1,另外还要修改#define FS TINY 0这句,如
究生,主要从事光电检测与控制技术方向的研究。 手机:13545196858 E-mail:zhangtao.hawk@gmail.tom
(上接29页) 作者简介:
方敏,女(汉族),(1984.1~),中国地质大学(武汉)机 电学院在读硕士,专业:信息与通信工程。研究方 向:信息与通信工程。
基于STM32的FATS文件系统移植全教程
基于STM32的FATS文件系统移植全教程一、移植目的1、结合命令界面的改结~结结文件系结命令界面的结合使用。
与2、在命令界面中结结以下文件系结操作命令,flist-列出前目结下的文件~当fmkdir-在前目结下结建目结~当fchgdir-改结前目结~当fread-结取文件容~内fwrite-新建文件入。
并写二、移植件条1、可以结结的串口命令界面。
参数2、FatFS007e版本。
三、结命令界面所结结功能的描述1、超结结端结置。
首先打结串口结端~结置波特率115200~8位据~无奇偶校结~无流控~结端结结数仿真ANSIW~asicc结结置结以结行符结尾;以前结置的~原因已结忘了,~反正结结结置了能结正常工作。
结结板结位后~结端结示,**********nthq2004 结的结结命令接口写!*********Sh>然后可以在结里结入命令结行。
比如结在支持的命令包括,"help","cls","ledon","ledoff","time","temp","i2cwr","i2crd","sdrd","s dwr"~共10个命令。
比如结入help me命令~结结示命令界面前支持的所有命令~结示会当并当参数前所有结入的命令。
所以命令结行结程的分析以help me结例~help是命令~me是。
参数2、串口结端命令结入结程在串口结端结入一字符结~其工作工程结,个void USART1_IRQHandler(void){ //结函在文件数stm32f10x_it.c中OS_CPU_SR cpu_sr;OS_ENTER_CRITICAL();OSIntNesting++; //中嵌套结断数OS_EXIT_CRITICAL();if ( USART_GetITStatus ( USART1, USART_IT_RXNE )!= RESET ){ Uart_ReceiveChar(); //串口接收字符 }OSIntExit(); //结里可以结任结切结结中触断}串口接收到字符引起结端、然后结用函数Uart_ReceiveChar()结取字符并放入串口消息结列~void Uart_ReceiveChar (void) { //结函在文件数uart.c中u32 RecChar;RecChar = (u32)(USART1->DR & 0xFF);OSQPost ( UartMsgOSQ, ( void* )RecChar ); //字符指结化放入消息结列将~结里接用了周慈航授结中的方法。
fatfs移植调试过程(在stm32上使用w25q64)
FATFS移植、调试过程(在STM32上使用W25Q64)花了几天的时间好不容易自己移植好了FATFS,以前一般都是用别个现成的东西,真的自己移植还是有一点点的操蛋。
移植FATFS其实不难,当然这是对于一个成功移植好的人来说。
FATFS移植资料网上有一大堆,但是在移植成功之前还是搞得我一头雾水.1、准备工作硬件:STM32F4+W25Q64软件:FATFS 0.1版本,好像现在最高的就是0.1版的吧,没去细查。
FATFS官方源码下载好之后只有几个文件。
添加两个C文件进去就好了,添加文件这种事比较基础,没什么好说的。
只要我这截图上有的文件都加上去了,基本上就可以了。
这里面需要我们修改的是diskio.c,其它文件不用动,当然有时候动动也没事,我用别人的东西总喜欢看看里面是什么。
在diskio.c里面,一共有6个接口函数,我按照重要性从最不重要的开始讲参考正点原子的代码,我在开头宏定义了扇区大小等内容。
[cpp] view plain copy print?#defineFLASH_SECTOR_SIZE 512 #defineFLASH_BLOCK_SIZE 8 uint32_tFLASH_SECTOR_COUNT = 2048*6; 这三个内容在diskio.c都会用到。
这里解释一下这三个东西,我之前查这个搞了半天没理解[cpp] view plain copy print?FLASH_SECTOR_SIZE 是指一个扇区块的大小512个字节[cpp] view plain copy print?<pre name="code"class="cpp">FLASH_BLOCK_SIZE 一个扇区分成了8块,也就是4K的大小,为什么是八块,百度后发现是因为与FAT类型有关,具体解释在正点原子<h1 class="ph" style="word-wrap: break-word; margin: 0px; padding: 15px0px 10px; font-size: 20px; font-family: 'Microsoft YaHei','Hiragino Sans GB', STHeiti, Tahoma, SimHei, sans-serif; font-weight: 100; color: rgb(68, 68, 68);">-第四十五章FATFS实验里面有说明</h1></pre><p></p><pre></pre> <pre name="code"class="cpp">FLASH_SECTOR_COUNT 这一段的内容是指有多少个扇区块,有什么用呢,在格式化W25Q64的时候,这个就可以认为是我的W25Q64的容量</pre>因为在W25Q64里面是没有MBR/DBR这些大小的,所以需要使用FATFS格式化成一个存储设备<p></p><p>要使用格式化就需要使用diskio.c里面的disk_ioctl 函数</p> <p>这是第一个函数。
STM32下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,并进行擦写均衡分析
STM32 下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,探写均衡分析作者:观海QQ:5316221、摘要在STM32 单片机上,成功移植 FatFs 0.12b,使用的 Nand Flash 芯片为K9F2G08 。
特点:系统配合 FatFs 实现了坏块管理,硬件ECC,软件 ECC 纠错2、代码分析2.1、擦写均衡分析在create_chain 函数中实现,每次分配都由当前scl 指向的free cluster 开始,逐块检查,是否有可用cluster 存在。
如果没有则取下一块,直到回到起始点,说明已经没有free cluster 了。
因为每次都紧邻scl 取free cluster, 那么每次的起始scl 值在哪里,就决定了擦写位置。
通过查看代码,很可惜,发现scl 每次都重新从1 开始查找free cluster。
所以,默认条件下,FatFs 不支持擦写均衡。
如果能把每次分配的cluster号记录下来,下次接着向后分配,则可实现擦写均衡。
未来有时间再来实现吧。
也许你现在就能实现哦,另忘了实现了分享一份给我。
2.2、坏块管理分析通过2.1对create_chain 函数的分析,我们知道get_fat是完成真实的free cluster的分配。
而每次get_fat 函数都会调用move_window 函数实际的读入一次该sector。
所以,我们只需要在读取函数中,对坏块进行检查,返回出错,则分配的cluster 自动移到下一个。
从而完成跳过坏块存储数据。
具体实现如下:如果FSMC_NAND_ReadSmallPage 检测到坏块,则NAND_disk_read 返回RES_ERROR。
2.3、STM32的硬件ECC在FSMC_NAND_Init 函数中打开STM32的硬件ECC配置。
如下红色字。
FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes;FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;这里使用的是FSMC_ECCPageSize_256Bytes,而K9F2G08 的最小page 为2048, 所以,我们在驱动中,会再把2048 的page 页再分为8个256的小页面分别进行ECC 运算。
FATFS移植
STM32中FatFS移植前言与废话做项目时网找资料,不会的东西上网查阅一下多半可以解决,一些尚未解决的问题也会有所启发。
最近由于项目的需要,仔细阅读了SD卡相关内容,顺藤摸瓜学习FatFS。
网上关于SD卡和FatFS的内容非常的多,重复的部分我就不介绍了,我把移植和使用部分的经验和大家分享一下。
刚开始的时候,我找来一些现成的代码研究一下,不用说看的是一头雾水。
看FatFS示例代码,也不知如何移植。
最后还是下定决心,慢慢的阅读FatFS的相关文档和范例代码,对于移植部分一点一点的研究,相信一定会有所收获。
一、硬件准备开始移植之前,你必须要有一块SD卡。
从形状上来说,有普通的SD卡,有很小的microSD卡,microSD卡就是手机中长见的TF卡。
购买microSD卡的时候,往往会附带一个SD卡套,那么小个头的microSD卡就变成了普通的SD卡,接口都是一样的。
但是还是您注意了,建议大家购买2G以下的SD卡(如果可以的话,买个128M 的SD卡就可以达到实验的效果,价格也非常便宜)。
刚开始移植的时候,我使用了4G的SD卡,但是发现程序无法完成SD卡的初始化。
查阅网上相关的资料,发现SD卡技术已2G作为分界线,大于或者等于4G的卡属于高速SD卡,和小于或者等于4G的SD卡略有区别。
二、软件准备在进行移植之前,先编写一些最简单的STM32程序。
在调试之前,我都会完成USART的初始化和发送函数,通过串口把STM32的运行状态打印出来,这样配合Jlink硬件调试,可以很快的找到错误。
由于SD卡可以使用SPI进行读写操作,所以还需要完成SPI 的初始化工作。
先来说一下USART的操作,我个人比较喜欢使用系统的printf函数,所以还需要引入stdio头文件。
在IAR中必须设定option的某个选项。
如下图所示。
除了完成USART的初始化工作以外,还需要重写fputc函数,具体的代码如下。
1int fputc(int ch, FILE * f)2{3USART_SendData(USART1, (uint8_t)ch);4while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );5return ch;6}复制代码然后说一下SPI的初始化工作。
基于STM32F407平台实现FATFS读写大容量SD卡的心得
基于STM32F407平台实现FATFS读写大容量SD卡的心得在基于STM32F407平台实现FATFS读写大容量(128G)SD卡的过程中,我积累了一些心得和经验。
下面我将简要介绍一下这些经验。
首先,在使用FATFS文件系统之前,我们需要确保已经正确初始化了SD卡的硬件和配置。
这包括对GPIO、SPI或SDIO等外设进行初始化,并设置正确的时钟源和参数。
对于不同的硬件配置,可能会有所不同,因此需要仔细查看STM32F407的相关文档和资料。
其次,在FATFS文件系统的使用中,我们需要了解和掌握以下几个核心概念和操作:1. 初始化文件系统和 Mount 卷标:在开始进行 SD 卡的读写之前,我们需要使用 f_mount 函数初始化文件系统,并使用 f_mount 函数挂载指定的卷标。
卷标可以是 0 到 9 之间的一个整数,用于表示 SD 卡上的不同分区或逻辑盘符。
2. 打开文件和读写操作:在进行文件读写之前,我们需要使用f_open 函数打开指定的文件,并返回一个文件指针。
然后可以使用f_read 和 f_write 函数进行读写操作。
读操作可以使用 f_read 函数读取指定长度的数据到缓冲区中,写操作可以使用 f_write 函数从缓冲区中写入指定长度的数据到文件中。
对于大容量的SD卡,我们可能需要提前进行一些准备工作,以确保能够正确读写数据:1. 使用 f_mkfs 函数进行格式化:在首次使用 SD 卡之前,我们可能需要对其进行格式化。
可以使用 f_mkfs 函数来完成格式化操作,指定分区号和扇区大小等参数。
2.适当分割文件:为了提高读写性能和避免内存溢出,我们可以将大的文件分割为多个小文件进行读写。
这可以通过调整缓冲区大小和每次读取或写入的数据长度来实现。
3.合理规划缓冲区内存:在进行SD卡读写时,我们需要使用一些缓冲区来暂存读取或写入的数据。
在选择缓冲区大小时,需要考虑到STM32F407的内存限制和其他功能的内存占用。
STM32ECC校验的一些心得
STM32ECC校验的一些心得在进行STM32ECC校验时,我有一些心得体会。
STM32ECC校验是一种用于检测和纠正数据传输错误的技术。
下面是我对该技术的理解和一些实践经验的总结。
首先,了解ECC的基本原理是非常重要的。
ECC是通过在数据中添加冗余字节来实现错误检测和纠正的。
理解如何计算冗余字节以及如何检测和纠正错误,可以帮助我们更好地使用STM32ECC校验。
其次,正确设置ECC模式是非常关键的。
在STM32芯片中,有不同的ECC模式可供选择,例如奇偶校验、海明码等。
根据实际需求选择合适的ECC模式,以满足数据传输的可靠性要求。
同时,还需要注意将ECC模式正确配置到硬件寄存器中,以确保正确实施校验。
另外,正确实施ECC校验的数据范围也是需要注意的。
通常情况下,我们只对重要的数据进行ECC校验,而对于不那么重要的数据,可以不进行校验。
这样可以减少计算量,并提高工作效率。
因此,在实施ECC校验前,需要明确哪些数据是需要校验的,哪些数据可以省略校验。
此外,要注意在传输过程中的数据完整性。
即使进行了ECC校验,也不能忽视数据传输的完整性。
在数据传输中,应尽量减少干扰和干扰引起的错误,例如正确设计电源线路、加强屏蔽设计等。
同时,还需要合理选择合适的传输速率和传输手段,以确保数据可以可靠地传输到目标设备。
最后,在进行ECC校验后,需要对错误进行处理。
当ECC校验出现错误时,我们可以根据校验结果对错误进行判断和处理。
一种常见的处理方式是重新请求数据传输,直到数据能够正确传输为止。
在实际应用中,还可以根据具体情况采取其他的补救措施,例如重新计算、重置等。
在实际使用STM32ECC校验的过程中,我们还需要注意一些细节。
首先,要根据硬件规格和需求合理设置ECC校验的参数,例如冗余字节的数量、ECC校验长度等。
其次,要仔细进行测试和调试,以保证校验的可靠性。
同时,还需要及时更新固件和驱动程序,以修复可能存在的软件漏洞。
stm32-SD卡FatFS文件系统
stm32-SD卡FatFS文件系统STM32平台SD卡的FatFS文件系统开发系统平台:STM32系列的STM32F103ZESPI方式与SD卡通信SD上移植FatFS系统1 FatFS文件系统1.1 FatFS简介FatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。
FatFs 的编写遵循ANSI C,并且完全与磁盘I/O 层分开。
因此,它独立(不依赖)于硬件架构,可以被嵌入到低成本的微控制器中,如A VR, 8051, PIC, ARM, Z80, 68K 等等,而不需要做任何修改。
特点:Windows兼容的FAT文件系统不依赖于平台,易于移植代码和工作区占用空间非常小多种配置选项多卷(物理驱动器和分区)多ANSI/OEM代码页,包括DBCS在ANSI/OEM或Unicode中长文件名的支持RTOS的支持多扇区大小的支持只读,最少API,I/O缓冲区等等1.2 FatFS文件系统移植FatFS文件系统移植需要的几个关键文件如下。
●ff.c(不动)文件系统的实现代码,里面主要是FatFS文件系统源码,移植的时候不需要修改;●diskio.h(不动)声明diskio.c文件中需要的一些接口函数和命令格式;●diskio.c(自写)这个文件是文件系统底层和SD驱动的中间接口的实现代码,移植的时候需要改写在diskio.h中声明的那几个函数,代码在ff.c中被调用;●integer.h(微改)这是FatFS用到的数据类型定义,按移植的平台修改;●ff.h(不动)是FatFS的文件系统的函数(在ff.c中)声明,以及一些选项的配置,具体选项及详细说明在文件中都有;●ffconf.h(按需要)这个是在FatFS的0.08a版本中有看到,0.06版本中还没有,是关于FatFS系统模块的一些配置;综上,需要修改的就是diskio.c文件,主要是6个函数,描述如下。
stm32 fatfs 中文编码
stm32 fatfs 中文编码摘要:1.简介- 介绍STM32- 介绍FATFS文件系统- 介绍中文编码2.STM32与FATFS的结合- 为什么选择FATFS文件系统- STM32如何支持FATFS- 实现过程的注意事项3.中文编码在FATFS中的处理- 中文编码的基本概念- FATFS文件系统对中文编码的支持- 中文编码在实际应用中的问题及解决方案4.总结- 回顾STM32、FATFS和中文编码的关系- 对未来发展的展望正文:1.简介STM32是一款由STMicroelectronics公司开发的基于ARM Cortex-M 内核的微控制器。
凭借其高性能、低功耗和丰富的外设资源,STM32在嵌入式领域得到了广泛应用。
为了更好地管理存储在STM32上的数据,文件系统成为了必不可少的组件。
FATFS(File Allocation Table File System)是一款经典的文件系统,适用于各种嵌入式系统。
然而,在处理中文编码文件时,STM32与FATFS的结合面临着一些挑战。
2.STM32与FATFS的结合FATFS文件系统以其简单、稳定、可移植性强等优点,成为了许多嵌入式系统的首选。
在STM32上实现FATFS,首先需要选择合适的库。
有许多开源库可供选择,如CubeMX、FatFS等。
这些库为开发者提供了丰富的例程和详细的文档,大大简化了开发过程。
在实际应用中,还需注意处理FATFS的初始化、挂载、卸载等操作,以确保文件系统的稳定运行。
3.中文编码在FATFS中的处理中文编码是指将中文字符映射为二进制序列的技术。
在FATFS中处理中文编码文件,需要确保文件系统能够正确识别并存储中文字符。
FATFS文件系统本身支持多种编码,如ASCII、UTF-8等。
为了在STM32上正确处理中文编码文件,开发者需在代码层面进行相应的处理。
例如,在写入文件时,需将中文字符转换为UTF-8编码,以确保文件系统能够正确识别。
fatfs使用例程
fatfs使用例程FatFs是一个嵌入式文件系统库,用于处理在嵌入式应用中使用的存储设备(例如SD卡、SPI存储芯片等)上的文件操作。
它由Elm Chan开发并开源,具有轻量级、可移植性强等特点,适用于各种嵌入式系统。
在使用FatFs之前,我们需要做几个准备工作。
首先,我们需要在我们的开发环境中添加FatFs库文件,并在我们的项目中引入相关的头文件。
其次,我们需要连接一个存储设备到我们的嵌入式系统,例如SD卡或SPI存储芯片。
接下来,我们将通过一个简单的示例来说明如何使用FatFs库。
我们将使用一个基于STM32F4的开发板和一个连接到内置SD卡插槽的SD卡来进行示范。
首先,在STM32CubeIDE中创建一个新的STM32工程,选择合适的开发板和芯片型号,然后通过CubeMX配置SD卡接口。
确保SD卡接口的时钟和引脚配置正确,并使能相关的中断。
然后,我们需要将FatFs库文件添加到我们的项目中。
将FatFs的源代码文件和对应的头文件复制到我们的工程目录下,并在STM32CubeIDE中添加这些文件。
在我们的工程中创建一个新的C文件,命名为"fatfs_example.c",然后在其中编写我们的FatFs使用示例代码。
```c#include "fatfs.h"#include "stdio.h"FATFS fs; /*文件系统对象*/FIL fil; /*文件对象*/FRESULT res; /* FatFs函数返回值*/UINT br, bw; /*读写的字节数*/int main(void){/*挂载文件系统*/if(f_mount(&fs, "0:", 1) != FR_OK){/*挂载失败*/printf("Mount failed.\n");while(1);}/*打开文件*/if(f_open(&fil, "test.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE) != FR_OK){/*文件打开失败*/printf("Open failed.\n");while(1);}/*写入数据*/if(f_write(&fil, "Hello,World!", 12, &bw) != FR_OK) {/*写入失败*/printf("Write failed.\n");while(1);}/*关闭文件*/if(f_close(&fil) != FR_OK){/*关闭失败*/printf("Close failed.\n");while(1);}/*卸载文件系统*/if(f_mount(NULL, "0:", 1) != FR_OK){/*卸载失败*/printf("Unmount failed.\n");while(1);}while(1);}```在这个示例中,我们首先挂载了文件系统,然后打开了一个名为"test.txt"的文件,如果文件不存在,则会创建一个新的文件。
STM32的FATFS文件系统移植笔记 - 黑-月 - 博客园
黑月人在江湖!STM32的FATFS文件系统移植笔记一、序言经常在网上、群里看到很多人问关于STM32的FATFS文件系统移植的问题,刚好自己最近也在调试这个程序,为了让大家少走弯路,我把我的调试过程和方法也贡献给大家。
二、FATFS简介FatFs Module是一种完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。
它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。
它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。
三、移植准备1、FATFS源代码的获取,可以到官网下载:http://elm/fsw/ff/00index_e.html 最新版本是R0.09版本,我们就移植这个版本的。
2、解压文件会得到两个文件夹,一个是doc文件夹,这里是FATFS的一些使用文档和说明,以后在文件编程的时候可以查看该文档。
另一个是src文件夹,里面就是我们所要的源文件。
3、建立一个STM32的工程,为方便调试,我们应重载printf()底层函数实现串口打印输出。
可以参考已经建立好的printf()打印输出工程:/bbs/foru ... d=77&extra=page%3D1四、开始移植1、在已经建立好的工程目录User文件夹下新建两个文件夹,FATFS_V0.09和SPI_SD_Card,FATFS_V0.09用于存放FATFS源文件,SPI_SD_Card用于存放SPI的驱动文件。
2、如图1将ff.c添加到工程文件夹中,并新建diskio.c文件,在diskio.c文件中实现五个函数:1. DSTATUS disk_initialize (BYTE);//SD卡的初始化2. DSTATUS disk_status (BYTE);//获取SD卡的状态,这里可以不用管3. DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);//从SD卡读取数据4. DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);//将数据写入SD卡,若该文件系统为只读文件系统则不用实现该函数5. DRESULT disk_ioctl (BYTE, BYTE, void*);//获取SD卡文件系统相关信息图1导航管理我的标签keil(335)C51(308)工作之外(204)行业了解(189)USB(184)NFC(178)硬件设计(142)PCB(123)RFID(122)JAVA CARD(96)更多Powered by:博客园Copyright © 黑月3、初步实现以上五个函数FATFS初始化函数:DSTATUS disk_initialize (BYTE drv /* Physical drive nmuber (0..) */){switch (drv){case 0 :return RES_OK;case 1 :return RES_OK;case 2 :return RES_OK;case 3 :return RES_OK;default:return STA_NOINIT;}}FATFS状态获取函数:DSTATUS disk_status (BYTE drv /* Physical drive nmuber (0..) */){switch (drv){case 0 :return RES_OK;case 1 :return RES_OK;case 2 :return RES_OK;default:return STA_NOINIT;}}FATFS底层读数据函数:DRESULT disk_read (BYTE drv, /* 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..255) */){if( !count ){return RES_PARERR; /* count不能等于0,否则返回参数错误 */}switch (drv){case 0:if(count==1) /* 1个sector的读操作 */{return RES_OK;} else /* 多个sector的读操作 */{return RES_OK;} case 1:if(count==1) /* 1个sector的读操作 */{return RES_OK;} else /* 多个sector的读操作 */{return RES_OK;}default:return RES_ERROR;}}FATFS底层写数据函数:DRESULT disk_write (BYTE drv, /* Physical drivenmuber (0..) */const BYTE *buff, /* Data to bewritten */DWORD sector, /* Sector address(LBA) */BYTE count /* Number ofsectors to write (1..255) */){if( !count ){return RES_PARERR; /* count不能等于0,否则返回参数错误 */}switch (drv){case 0:if(count==1) /* 1个sector的写操作 */{return RES_OK;} else /* 多个sector的写操作 */{return RES_OK;} case 1:if(count==1) /* 1个sector的写操作 */{return RES_OK;} else /* 多个sector的写操作 */{return RES_OK;}default:return RES_ERROR;}}FATFS磁盘控制函数:DRESULT disk_ioctl (BYTE drv, /* Physical drive nmuber(0..) */BYTE ctrl, /* Control code */void *buff /* Buffer tosend/receive control data */){if (drv==0){switch (ctrl){case CTRL_SYNC :return RES_OK;case GET_SECTOR_COUNT :return RES_OK;case GET_BLOCK_SIZE :return RES_OK;case CTRL_POWER :break;case CTRL_LOCK :break;case CTRL_EJECT :break;/* MMC/SDC command */case MMC_GET_TYPE :break;case MMC_GET_CSD :break;case MMC_GET_CID :break;case MMC_GET_OCR :break;case MMC_GET_SDSTAT :break;}}else if(drv==1){switch (ctrl){case CTRL_SYNC :return RES_OK;case GET_SECTOR_COUNT :return RES_OK;case GET_SECTOR_SIZE :return RES_OK;case GET_BLOCK_SIZE :return RES_OK;case CTRL_POWER :break;case CTRL_LOCK :break;case CTRL_EJECT :break;/* MMC/SDC command */case MMC_GET_TYPE :break;case MMC_GET_CSD :break;case MMC_GET_CID :break;case MMC_GET_OCR :break;case MMC_GET_SDSTAT :break;}}else{return RES_PARERR;}return RES_PARERR;}以上函数都只是实现一个框架,并没有做实际的事情,下一步就需要把操作SD卡的程序填充在这个框架里面。
FATFS移植、调试过程(在STM32上使用W25Q64)
FATFS移植、调试过程(在STM32上使用W25Q64)花了几天的时间好不容易自己移植好了FATFS,以前一般都是用别个现成的东西,真的自己移植还是有一点点的操蛋。
移植FATFS其实不难,当然这是对于一个成功移植好的人来说。
FATFS移植资料网上有一大堆,但是在移植成功之前还是搞得我一头雾水.1、准备工作硬件:STM32F4+W25Q64软件:FATFS 0.1版本,好像现在最高的就是0.1版的吧,没去细查。
FATFS官方源码下载好之后只有几个文件。
添加两个C文件进去就好了,添加文件这种事比较基础,没什么好说的。
只要我这截图上有的文件都加上去了,基本上就可以了。
这里面需要我们修改的是diskio.c,其它文件不用动,当然有时候动动也没事,我用别人的东西总喜欢看看里面是什么。
在diskio.c里面,一共有6个接口函数,我按照重要性从最不重要的开始讲参考正点原子的代码,我在开头宏定义了扇区大小等内容。
[cpp] view plain copyprint?1.#define FLASH_SECTOR_SIZE 5122.#define FLASH_BLOCK_SIZE 83.uint32_t FLASH_SECTOR_COUNT = 2048*6;这三个内容在diskio.c都会用到。
这里解释一下这三个东西,我之前查这个搞了半天没理解[cpp] view plain copyprint?1.FLASH_SECTOR_SIZE 是指一个扇区块的大小 512个字节[cpp] view plain copyprint?1.<pre name="code" class="cpp">FLASH_BLOCK_SIZE 一个扇区分成了8块,也就是4K的大小,为什么是八块,百度后发现是因为与FAT类型有关,具体解释在正点原子<h1 class="ph" style="word-wrap: break-word; margin: 0px; padding: 15px 0px 10px; font-size: 20px; font-family: 'Microsoft YaHei', 'Hiragino Sans GB', STHeiti, Tahoma, Si mHei, sans-serif; font-weight: 100; color: rgb(68, 68, 68);">-第四十五章 FATFS实验里面有说明</h1></pre><p></p>2.<pre></pre>3.<pre name="code" class="cpp">FLASH_SECTOR_COUNT 这一段的内容是指有多少个扇区块,有什么用呢,在格式化W25Q64的时候,这个就可以认为是我的W25Q64的容量</pre>因为在W25Q64里面是没有MBR/DBR这些大小的,所以需要使用FATFS格式化成一个存储设备4.<p></p>5.<p>要使用格式化就需要使用diskio.c里面的disk_ioctl函数</p>6.<p>这是第一个函数。
STM32的FatFS在数据采集系统中的应用
STM32的FatFS在数据采集系统中的应用秦伟【期刊名称】《单片机与嵌入式系统应用》【年(卷),期】2015(15)6【摘要】Aiming at the large-capacity data acquisition system,the paper designs a system which takes STM32F107 microcontroller as the core,and adopts SD card as the storage medium.The article outlines the transplant of the open source Fat file system on the STM32 processor and the programming of the low-level driver functions.The system achieves high-precision data acquisition by using the 24-bitsΣ-ΔADC,and uses the Fat file system to achieve a large-capacity storage and management for the collected data,which provides a con-venience for the subsequent processing and transmission of the data.%针对单片机大容量数据采集系统,设计了一种以STM32 F107微控制器为核心,以大容量SD卡为存储介质的数据采集系统。
简述了开源的FatFS文件系统在STM32处理器上的移植及其底层驱动函数的编写,利用24位∑Δ模/数转换器实现了高精度数据采集,利用FatFS文件系统实现了采集数据的大容量存储和管理,为数据后续处理和传输提供了便利。
为STM32移植FATFS读取SD卡上FAT121632文件系统
给stm32移植fatfs文件系统,今天终于取得阶段性胜利。
只需要提供这样几个函数即可[plain]view plaincopyprint?1.DSTATUS disk_initialize (BYTE);2.DSTATUS disk_status (BYTE);3.DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);4.DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); // 如果实现只读的文件系统就不需要了。
5.DRESULT disk_ioctl (BYTE, BYTE, void*);移植成功后,可以用如下方式读取SD卡了,实在太方便了,和PC机上编程差不了多少。
[csharp]view plaincopyprint?1.unsigned int i;2. BYTE buffer[512]; // file copy buffer3. FATFS fs; // Work area (file system object) for logical drive4. FIL fsrc; // file objects5. FRESULT res; // FatFs function common result code6. UINT br; // File R/W count7. USART1_Puts("Now, I'll read file 'i2c/uart.lst'.\n");8.9.// Register a work area for logical drive 010. f_mount(0, &fs);11.12.// Open source file13. res = f_open(&fsrc, "i2c/uart.lst", FA_OPEN_EXISTING | FA_READ);14.if (res)15. {16. USART1_Puts("Can't open i2c/uart.lst for read. :-(\n");17.goto exit;18. }19.20.for (;;) {21. res = f_read(&fsrc, buffer, sizeof(buffer), &br);22.if (res || br == 0) break; // error or eof23.for( i = 0; i < br; ++i )24. USART1_Putc(buffer[i]);25. }26.27. f_close(&fsrc);28.xit:29.// Unregister a work area before discard it30. f_mount(0, NULL);。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STM32 下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,探写均衡分析
作者:观海QQ:531622
1、摘要
在STM32 单片机上,成功移植 FatFs 0.12b,使用的 Nand Flash 芯片为K9F2G08 。
特点:系统配合 FatFs 实现了坏块管理,硬件ECC,软件 ECC 纠错
2、代码分析
2.1、擦写均衡分析
在create_chain 函数中实现,每次分配都由当前scl 指向的free cluster 开始,逐块检查,是否有可用cluster 存在。
如果没有则取下一块,直到回到起始点,说明已经没有free cluster 了。
因为每次都紧邻scl 取free cluster, 那么每次的起始scl 值在哪里,就决定了擦写位置。
通过查看代码,很可惜,发现scl 每次都重新从1 开始查找free cluster。
所以,默认条件下,FatFs 不支持擦写均衡。
如果能把每次分配的cluster号记录下来,下次接着向后分配,则可实现擦写均衡。
未来有时间再来实现吧。
也许你现在就能实现哦,另忘了实现了分享一份给我。
2.2、坏块管理分析
通过2.1对create_chain 函数的分析,我们知道get_fat是完成真实的free cluster的分配。
而每次get_fat 函数都会调用move_window 函数实际的读入一次该sector。
所以,我们只需要在读取函数中,对坏块进行检查,返回出错,则分配的cluster 自动移到下一个。
从而完成跳过坏块存储数据。
具体实现如下:
如果FSMC_NAND_ReadSmallPage 检测到坏块,则NAND_disk_read 返回RES_ERROR。
2.3、STM32的硬件ECC
在FSMC_NAND_Init 函数中打开STM32的硬件ECC配置。
如下红色字。
FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes;
FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
这里使用的是FSMC_ECCPageSize_256Bytes,而K9F2G08 的最小page 为2048, 所以,我们在驱动中,会再把2048 的page 页再分为8个256的小页面分别进行ECC 运算。
这
样做的好处很明显,坏处就是加大了复杂度。
具体实现参见FSMC_NAND_WriteSmallPage和FSMC_NAND_ReadSmallPage 函数。
每次在硬件运算ECC 开始时都需要打开ECC开关,算完一页后,又需要关闭开关。
在读取ECC值之前还必须等待计算完毕。
while(FSMC_GetFlagStatus(FSMC_Bank2_NAND,FSMC_FLAG_FEMPT)==Bit_RESET);
做到这几条就可以通过 FSMC_GetECC 函数获取正确的 ECC 值了。
另外因为我们的计算特性,所以在坏块标志后特别加入了一个我们自定义的ECC标识。
2.4、ECC纠错
首先是ECC 错误识别,代码如下:
说明:eccRd为存储时计算的ECC什值; eccCl 为当前运算的值。
eccXor 不为零时,说明检测到错误。
再通过FSMC_NAND_GetBitPosition 函数获得具体的出错bit的位置。
具体算法请阅参考文献。
2.5、文件组成
FatFs 目录
+---- ffconf.h 对FatFs 进行配置的文件
+---- ff.h
+---- ff.c 是FatFs 的实现文件,擦写均衡在create_chain 函数中已实现。
+---- ccsbcs.c 文件名支持英文
+---- cc936.c 文件名支技中文
+---- diskio.c 是FatFs 与自定义驱动层的接口函数
+---- NandDisk.c 为自己实现的NandFlash 匹配函数,坏块管理在这里实现。
BSP 目录
+---- fsmc_nand.h 对K9F2G08 的各种参数定义
+---- fsmc_nand.c 实现硬件级别的读写驱动,STM32 的硬件ECC 在这里使用。
还实现了ECC 自动纠错。
注:为了获得64*2K 的擦除缓冲区,系统还使用了一块SRAM 芯片,以支持malloc 内存分配函数。
这个文件由你自己的系统提供。
希望获得源码的同学,点这里:源码下载
3、引用文献
FatFs 系统/fsw/ff/00index_e.html
ECC 算法详细说明/content/11/0523/17/496343_118837985.
shtml
STM32 ECC校验的
/bbs/dpj-32707-1.html
一些心得。