# FATS的移植过程

1.[参考文档](https://blog.csdn.net/weixin_42042056/article/details/118190017?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=1)
	课程资料EX8
2.添加FATS的库文件，把.C改成.CPP，移除头文件里面所有的 

```c
#ifdef __cplusplus
	extern "C" {
#endif
```

3.添加FLASH读写的接口文件

4.改写diskio.cpp文件的接口函数，参考如下，FATS的版本为:12c

```c
/*第一步:添加自己的头文件*/
#include "../W25QXXArduino/w25qxx.h"
/*第二步:添加一些宏定义*/
#define FLASH_SECTOR_SIZE   512
#define FLASH_SECTOR_COUNT  2048 * 16
#define FLASH_BLOCK_SIZE 8
/*第三步:改写如下函数*/
DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
  DSTATUS stat = RES_OK;

  W25QXX_Init();
  return stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Start sector in LBA */
	UINT count		/* Number of sectors to read */
)
{
  DRESULT res = RES_OK;
  if(!count) return RES_PARERR; //count????0,????????
	for(;count > 0;count--){
		W25QXX_Read(buff,sector * FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
		sector ++;
		buff += FLASH_SECTOR_SIZE;
	}
  return res;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Start sector in LBA */
	UINT count			/* Number of sectors to write */
)
{
  DRESULT res = RES_OK;
  if(!count) return RES_PARERR; //count????0,????????
	for(;count > 0;count --){
		W25QXX_Write((uint8_t *)buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE);
		sector ++;
		buff += FLASH_SECTOR_SIZE;
	}
  return res;
}
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
  DRESULT res = RES_OK;
	switch(cmd)
	{
		case CTRL_SYNC: res = RES_OK;  break;
		case GET_SECTOR_SIZE:  *(WORD*)buff = FLASH_SECTOR_SIZE;
		         res = RES_OK;         break;
		case GET_BLOCK_SIZE:   *(WORD*)buff = FLASH_BLOCK_SIZE;
		         res = RES_OK;         break;
		case GET_SECTOR_COUNT:  *(DWORD*)buff = FLASH_SECTOR_COUNT;
		         res = RES_OK;         break;
		default:     res = RES_PARERR; break;
	}
  return res;
}
```

5.修改**ffconf.h**宏定义:

```c
#define _FS_NORTC	1  //修改为1，禁用时间
#define	_MIN_SS		512 //不修改
#define	_MAX_SS		4096 //修改为4096
#define	_USE_MKFS	1 //使能一些函数
```

6.写入测试块

```c
/***FATS 这几个变量设置为全局变量，不然会栈溢出错误***/
BYTE work[4096]; //FATFS工作缓冲区
FATFS fs;   //文件系统对象
FIL fil;    //文件对象
FRESULT res;//操作返回对象
UINT bw, i; //临时变量
BYTE mm[500]; //临时数组
/***FATS***/
```

```
	 res = f_mount(&fs, "0:",1);
	 if(res == 0X0D) //FLASH磁盘，FAT文件系统错误，重新格式化FLASH
	 {
		 Serial.printf("Flash Disk Formatting...\n"); //格式化FLASH
		 res = f_mkfs("0:",FM_ANY,0,work,sizeof(work));
		 if(res != FR_OK)
			Serial.printf("mkfs error.\n");
	 }
	 if(res == FR_OK)
		 Serial.printf("FATFS Init ok!\n");
	 res = f_open(&fil,"0:/test.txt",FA_CREATE_NEW);
	 if(res != FR_OK && res != FR_EXIST)
		 Serial.printf("create file error.\n");
	 if(res == FR_EXIST)
		 res = f_open(&fil,"0:test.txt",FA_WRITE|FA_READ|FA_OPEN_APPEND);
	 if(res != FR_OK)
		 Serial.printf("open file error.\n");
	 else{
		Serial.printf("open file ok.\n");
		f_puts("Hello,World!\n你好世界\n",&fil);
		Serial.printf("file size:%lu Bytes.\n", f_size(&fil));
		memset(mm,0x0,500);
		f_lseek(&fil,0);
		res = f_read(&fil,mm,500,&i);
		if(res == FR_OK)  printf("read size:%d Bytes.\n%s",i,mm);
		else     Serial.printf("read error!\r\n");
		f_close(&fil);
		/*卸载文件系统*/
		f_mount(0,"0:",0);
	 }
```

正常结果显示:

```c
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0
flash is EF17
FATFS Init ok!
open file ok.
file size:104 Bytes.
read size:104 Bytes.
Hello,World!
你好世界
Hello,World!
你好世界
Hello,World!
你好世界
Hello,World!
你好世界
```

## 注意点

1. [Arduino头文件包含的注意](https://blog.csdn.net/weixin_42042056/article/details/118190017?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=1)

2. C++和C语言冲突的问题解决相关C语言和C++冲突的问题:

   ```c
   error: unknown type name 'class'
   error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
   error: unknown type name 'SPIClass'
   
   ```
   
   解决 ：把所有的.c改成.cpp；删除 

   ```c
   #ifdef __cplusplus
   	extern "C" {
   #endif
         /*代码块*/
    #ifdef __cplusplus
   	extern "C" }
   #endif     

3. 栈溢出错误导致无限重启，将FATS测试变量设置为全局的,[参考解释](https://blog.csdn.net/qq_41828707/article/details/108527610)

