STM32 之 標準外設版 USB 驅動 + MSC(Host) + Fatfs 移植
寫在前面
- 現在,網上關於STM32的USB的文章數不勝數。寫這篇文章僅僅是對於自我學習的一個記錄。主要是對實際學習中遇到的一些棘手問題做個備忘錄。使用的晶片為STM32F407VG 。
- 目前,ST的USB驅動有兩套,一套是早期的獨立版USB驅動,官方培訓文件中稱為Legacy library,最新版為2.2.0;一套為針對其Cube系列的驅動,根據晶片不同可能有區別,具體見對應晶片的Cube驅動包,官方培訓文件中稱為Cube library。 本文使用的為Legacy libraryUSB驅動。更詳細的請參考博文STM32 之 USB IP(USB模組) 詳解。
- HAL庫 + Legacy library USB庫兩個混用
- 目前,Fatfs 驅動最新版為R0.13a 。
- 本文多出自於ST的官方文件,讀者也可以直接去ST官網查閱相關文件。
- 本文主要涉及USB Host(全速)+ MSC + Fatfs的移植。其他移植後續用到再說。
USB驅動部分
原始碼移植
原始碼的移植相對來說比較簡單,使用時,根據需要複製相關的檔案即可。需要注意的是,整理一下原始碼的結構。這個在上一篇博文中已經由說明了。具體見下圖:
在移植其他部分的時候與之類似,只需要替換成對應部分的原始碼檔案即可。
- 原始碼中的 USB OTG部分是所有其他模組的驅動程式。
usbh_msc_fatfs.c
為ST提供的FatFs的diskio.c
的具體實現檔案。在使用了該檔案後,使用者不必再自行實現FafFs的diskio.c
了。
###原始碼配置
整個USB驅動用於靈活的配置選項,且通過一個配置檔案的形式給出。這樣,使用者可以儘量少的修改的驅動原始碼。這些配置檔案均為使用者級別的檔案,通常來說置於使用者程式碼目錄下。如下如所示:
作為使用者級檔案,通常所有的使用者程式碼均在以上檔案做修改即可,只有少數特殊處理會設計到驅動程式原始碼的修改。在配置好後,一般來說,所有修改均在usbh_usr.h/.c
中。
usb_config.h
usb_config.h
是USB OTG 底層驅動的配置檔案。在USB OTG的原始碼中,ST提供了usb_conf_template.h
/** ******************************************************************************
* @file usb_conf.h
* @author
* @version V2.2.0
* @date 2017.12.27
* @brief USB的底層驅動配置
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT 2017 ST</center></h2>
*
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CONF__H__
#define __USB_CONF__H__
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h" /* 這裡需要包含自己使用的ST的庫的標頭檔案 */
/** @addtogroup USB_OTG_DRIVER
* @{
*/
/** @defgroup USB_CONF
* @brief USB 底層驅動配置檔案
* @{
*/
/** @defgroup USB_CONF_Exported_Defines
* @{
*/
/* USB Core and PHY interface 配置.
Tip: To avoid modifying these defines each time you need to change the USB configuration, you can declare the needed define in your toolchain compiler preprocessor.
*/
/**** 配置檔案包含了Full Speed 和 High Speed 兩種速率的配置,使用時,從兩者選擇其一即可。****/
/****************** USB OTG FS PHY 配置 *******************************
* USB OTG FS Core 支援 one on-chip Full Speed PHY。通常,ST晶片內部已經集成了該PHY。
*
* 當使用了FS core時,巨集USE_EMBEDDED_PHY 需要在編譯器中定義.
*
*******************************************************************************/
#ifndef USE_USB_OTG_FS
#define USE_USB_OTG_FS /* 使用 FS, 與下面的 HS 只能選一個。目前,終端只支援FS */
#endif /* USE_USB_OTG_FS */
#ifdef USE_USB_OTG_FS
#define USB_OTG_FS_CORE
#endif
/****************** USB OTG HS PHY 配置 *******************************
* USB OTG HS Core 支援 兩種 PHY 介面:
* (i) 使用外部高速PHY的ULPI 介面: USB HS Core 工作在高速模式下
* (ii) 片內Full Speed PHY: USB HS Core 工作在全速模式下
* 通過下面兩個巨集,選擇使用哪種PHY:
* (i) USE_ULPI_PHY: if the USB OTG HS Core is to be used in High speed mode
* (ii) USE_EMBEDDED_PHY: if the USB OTG HS Core is to be used in Full speed mode
*
* Notes:
* - The USE_ULPI_PHY symbol is defined in the project compiler preprocessor as default PHY when HS core is used.
* - On STM322xG-EVAL and STM324xG-EVAL boards, only configuration(i) is available.
* Configuration (ii) need a different hardware, for more details refer to your STM32 device datasheet.
*******************************************************************************/
#ifndef USE_USB_OTG_HS
//#define USE_USB_OTG_HS
#endif /* USE_USB_OTG_HS */
#ifndef USE_ULPI_PHY
//#define USE_ULPI_PHY
#endif /* USE_ULPI_PHY */
#ifndef USE_EMBEDDED_PHY
//#define USE_EMBEDDED_PHY
#endif /* USE_EMBEDDED_PHY */
#ifdef USE_USB_OTG_HS
#define USB_OTG_HS_CORE
#endif
/*******************************************************************************
* FIFO Size Configuration in Device mode
*
* (i) Receive data FIFO size = RAM for setup packets +
* OUT endpoint control information +
* data OUT packets + miscellaneous
* Space = ONE 32-bits words
* --> RAM for setup packets = 10 spaces
* (n is the nbr of CTRL EPs the device core supports)
* --> OUT EP CTRL info = 1 space
* (one space for status information written to the FIFO along with each
* received packet)
* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces
* (MINIMUM to receive packets)
* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces
* (if high-bandwidth EP is enabled or multiple isochronous EPs)
* --> miscellaneous = 1 space per OUT EP
* (one space for transfer complete status information also pushed to the
* FIFO with each endpoint's last packet)
*
* (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
* that particular IN EP. More space allocated in the IN EP Tx FIFO results
* in a better performance on the USB and can hide latencies on the AHB.
*
* (iii) TXn min size = 16 words. (n : Transmit FIFO index)
* (iv) When a TxFIFO is not used, the Configuration should be as follows:
* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txm can use the space allocated for Txn.
* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txn should be configured with the minimum space of 16 words
* (v) The FIFO is used optimally when used TxFIFOs are allocated in the top
* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
*******************************************************************************/
/*******************************************************************************
* FIFO Size Configuration in Host mode
*
* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or
* 2x (Largest Packet Size / 4) + 1, If a
* high-bandwidth channel or multiple isochronous
* channels are enabled
*
* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size
* for all supported nonperiodic OUT channels. Typically, a space
* corresponding to two Largest Packet Size is recommended.
*
* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is
* the largest maximum packet size for all supported periodic OUT channels.
* If there is at least one High Bandwidth Isochronous OUT endpoint,
* then the space must be at least two times the maximum packet size for
* that channel.
*******************************************************************************/
/****************** USB OTG HS CONFIGURATION **********************************/
/* 以下暫不使用 */
#ifdef USB_OTG_HS_CORE
#define RX_FIFO_HS_SIZE 512 /* 設定高速核心的接收FIFO大小。*/
/* 設定裝置端點的傳送FIFO大小(高速),其中0~3是要使用的端點的索引。*/
#define TX0_FIFO_HS_SIZE 512
#define TX1_FIFO_HS_SIZE 512
#define TX2_FIFO_HS_SIZE 0
#define TX3_FIFO_HS_SIZE 0
#define TX4_FIFO_HS_SIZE 0
#define TX5_FIFO_HS_SIZE 0
#define TXH_NP_HS_FIFOSIZ 96 /* 設定主機模式(高速)的非週期性傳送FIFO大小。 */
#define TXH_P_HS_FIFOSIZ 96 /* 設定主機模式(高速)的週期性傳送FIFO大小。*/
// #define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT /* 實現高速核心(USB核心時鐘門控等)的低功耗管理。 */
// #define USB_OTG_HS_SOF_OUTPUT_ENABLED
// #define USB_OTG_INTERNAL_VBUS_ENABLED
#define USB_OTG_EXTERNAL_VBUS_ENABLED
#ifdef USE_ULPI_PHY
#define USB_OTG_ULPI_PHY_ENABLED /* 啟用高速核心的ULPI PHY。 */
#endif
#ifdef USE_EMBEDDED_PHY
#define USB_OTG_EMBEDDED_PHY_ENABLED /* 為高速核心啟用嵌入式FS PHY。 */
#endif
#define USB_OTG_HS_INTERNAL_DMA_ENABLED /* 啟用高速核心的內部DMA功能。 */
#define USB_OTG_HS_DEDICATED_EP1_ENABLED /* 在高速核心中為器件模式啟用專用的端點1功能。 */
#endif
/****************** USB OTG FS CONFIGURATION **********************************/
#ifdef USB_OTG_FS_CORE
#define RX_FIFO_FS_SIZE 128 /* 設定全速核心的接收FIFO大小。 */
/* 設定裝置端點的傳送FIFO大小(全速),其中0~3是要使用的端點的索引。*/
#define TX0_FIFO_FS_SIZE 64
#define TX1_FIFO_FS_SIZE 128
#define TX2_FIFO_FS_SIZE 0
#define TX3_FIFO_FS_SIZE 0
#define TXH_NP_FS_FIFOSIZ 96 /* 設定主機模式(全速)的非週期性傳送FIFO大小。 */
#define TXH_P_FS_FIFOSIZ 96 /* 設定主機模式(全速)的週期性傳送FIFO大小。*/
// #define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT /* 實現全速核心(USB核心時鐘門控等)的低功耗管理。 */
// #define USB_OTG_FS_SOF_OUTPUT_ENABLED
#endif
/****************** USB OTG MISC CONFIGURATION ********************************/
//#define VBUS_SENSING_ENABLED
/****************** USB OTG MODE CONFIGURATION ********************************/
#define USE_HOST_MODE /* 採用 Host 模式 與下面的 USE_DEVICE_MODE 和 USE_OTG_MODE 任選其一 */
//#define USE_DEVICE_MODE
//#define USE_OTG_MODE
#ifndef USB_OTG_FS_CORE
#ifndef USB_OTG_HS_CORE
#error "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined"
#endif
#endif
#ifndef USE_DEVICE_MODE
#ifndef USE_HOST_MODE
#error "USE_DEVICE_MODE or USE_HOST_MODE should be defined"
#endif
#endif
#ifndef USE_USB_OTG_HS
#ifndef USE_USB_OTG_FS
#error "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined"
#endif
#else //USE_USB_OTG_HS
#ifndef USE_ULPI_PHY
#ifndef USE_EMBEDDED_PHY
#error "USE_ULPI_PHY or USE_EMBEDDED_PHY should be defined"
#endif
#endif
#endif
/****************** C Compilers dependant keywords ****************************/
/* In HS mode and when the DMA is used, all variables and data structures dealing
with the DMA during the transaction process should be 4-bytes aligned */
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined (__GNUC__) /* GNU Compiler */
#define __ALIGN_END __attribute__ ((aligned (4)))
#define __ALIGN_BEGIN
#else
#define __ALIGN_END
#if defined (__CC_ARM) /* ARM Compiler */
#define __ALIGN_BEGIN __align(4)
#elif defined (__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#elif defined (__TASKING__) /* TASKING Compiler */
#define __ALIGN_BEGIN __align(4)
#endif /* __CC_ARM */
#endif /* __GNUC__ */
#else
#define __ALIGN_BEGIN
#define __ALIGN_END
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* __packed keyword used to decrease the data type alignment to 1-byte */
#if defined (__CC_ARM) /* ARM Compiler */
#define __packed __packed
#elif defined (__ICCARM__) /* IAR Compiler */
#define __packed __packed
#elif defined ( __GNUC__ ) /* GNU Compiler */
#define __packed __attribute__ ((__packed__))
#elif defined (__TASKING__) /* TASKING Compiler */
#define __packed __unaligned
#endif /* __CC_ARM */
/**
* @}
*/
/*省略*/
#endif //__USB_CONF__H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT *****END OF FILE****/
usbh_config.h
usbh_config.h
是USB Host 底層驅動的配置檔案。在USB OTG的原始碼中,ST提供了usbh_conf_template.h
。使用者只需要複製該檔案到自己的程式碼目錄下,修改即可。具體配置見下文的註釋部分:
/**
******************************************************************************
* @file usbh_conf.h
* @author
* @version V2.2.0
* @date 2017.12.27
* @brief USB Host library 配置
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT 2017 </center></h2>
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBH_CONF__H__
#define __USBH_CONF__H__
/* Includes ------------------------------------------------------------------*/
// #include "xxx.h" /* 包含自己的各種標頭檔案*/
/** @addtogroup USBH_OTG_DRIVER
* @{
*/
/** @defgroup USBH_CONF
* @brief USB Host 底層驅動配置檔案
* @{
*/
/** @defgroup USBH_CONF_Exported_Defines
* @{
*/
#define USBH_MAX_NUM_ENDPOINTS 2 /* 支援端點的最大數量 1 bulk IN + 1 bulk Out */
#define USBH_MAX_NUM_INTERFACES 2 /* 支援介面的最大數量 */
#ifdef USE_USB_OTG_FS
#define USBH_MSC_MPS_SIZE 0x40
#else
#define USBH_MSC_MPS_SIZE 0x200
#endif
#define USBH_MAX_DATA_BUFFER 0x400
/* 錯誤資訊列印函式 重定向 這裡需要注意:該庫使用了LCD_ErrLog,需要進行重定向,否則報錯 */
/* 感覺 庫直接將 其改名為 USB_Log 或者 USB_ErrLog 最好了 */
#define LCD_ErrLog(str) udwComSendData(COM_CONSOLE, str, strlen(str));
/* 與Fatfs對接使用 */
#define _USE_IOCTL 1
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_FunctionsPrototype
* @{
*/
/**
* @}
*/
#endif //__USBH_CONF__H__
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT *****END OF FILE****/
usbh_bsp.c
包含(在USB OTG低階驅動程式的usb_bsp.h檔案中宣告)來初始化GPIO的核心,延時方法和中斷啟用/禁用的函式的實現。在USB OTG的原始碼中,ST提供了usb_bsp_template.c
。使用者只需要複製該檔案到自己的程式碼目錄下,修改即可。具體需要實現的函式在usb_bsp.h
中已經定義好了,使用者不能更改介面名。見下文的註釋部分:
void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev); /* 該介面中 實現 USB Host 使用的各種 GPIO等*/
void USB_OTG_BSP_uDelay (const uint32_t usec); /* USB 使用的延時函式 */
void USB_OTG_BSP_mDelay (const uint32_t msec); /* USB 使用的延時函式 */
void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev); /* USB 使用的中斷 */
void USB_OTG_BSP_TimerIRQ (void);
/* 以下主要是用於 高速模式下的配置,如VBUS的過流檢測等 */
#ifdef USE_HOST_MODE
void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state);
void USB_OTG_BSP_Resume(USB_OTG_CORE_HANDLE *pdev);
void USB_OTG_BSP_Suspend(USB_OTG_CORE_HANDLE *pdev);
#endif /* USE_HOST_MODE */
usbh_usr.c/.h
包含(在USB庫的usbh_usr.h檔案中宣告)來處理來自使用者層(事件訊息)的庫事件的函式實現。需要實現的函式介面(注意:以下是針對MSC的,其他如HID的使用者介面是不同的)見下文:
void USBH_USR_Init(void);
void USBH_USR_DeInit(void);
void USBH_USR_DeviceAttached(void);
void USBH_USR_ResetDevice(void);
void USBH_USR_DeviceDisconnected (void);
void USBH_USR_OverCurrentDetected (void);
void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed);
void USBH_USR_Device_DescAvailable(void *);
void USBH_USR_DeviceAddressAssigned(void);
void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,
USBH_InterfaceDesc_TypeDef *itfDesc,
USBH_EpDesc_TypeDef *epDesc);
void USBH_USR_Manufacturer_String(void *);
void USBH_USR_Product_String(void *);
void USBH_USR_SerialNum_String(void *);
void USBH_USR_EnumerationDone(void);
USBH_USR_Status USBH_USR_UserInput(void);
void USBH_USR_DeviceNotSupported(void);
void USBH_USR_UnrecoveredError(void);
int USBH_USR_MSC_Application(void);
對於MSC,使用以下回調:USBH_USR_MSC_Application()
。 在類初始化結束之後,這個函式被MSC狀態機呼叫,以便向用戶提供檔案系統訪問操作。使用者最終需要在該函式中實現自己的使用者程式碼。在此回撥中,使用者可以使用FAT FS檔案系統API實現對FAT檔案系統的任何訪問(檔案開啟,檔案讀取,檔案寫入…)。 使用者還可以訪問從庫MSC類驅動程式匯出的結構變數:USBH_MSC_Param。
其他介面是這個USB Host 狀態機一步一步執行過程的函式。使用者可以在不同的步驟新增對應的處理。最終,使用型別USBH_Usr_cb_TypeDef
,將所有函式註冊進USB Host驅動。
/* USB Host 使用者介面 型別定義 */
typedef struct _USBH_USR_PROP
{
void (*Init)(void); /* HostLibInitialized */
void (*DeInit)(void); /* HostLibInitialized */
void (*DeviceAttached)(void); /* DeviceAttached */
void (*ResetDevice)(void);
void (*DeviceDisconnected)(void);
void (*OverCurrentDetected)(void);
void (*DeviceSpeedDetected)(uint8_t DeviceSpeed); /* DeviceSpeed */
void (*DeviceDescAvailable)(void *); /* DeviceDescriptor is available */
void (*DeviceAddressAssigned)(void); /* Address is assigned to USB Device */
void (*ConfigurationDescAvailable)(USBH_CfgDesc_TypeDef *,
USBH_InterfaceDesc_TypeDef *,
USBH_EpDesc_TypeDef *);
/* Configuration Descriptor available */
void (*ManufacturerString)(void *); /* ManufacturerString*/
void (*ProductString)(void *); /* ProductString*/
void (*SerialNumString)(void *); /* SerialNubString*/
void (*EnumerationDone)(void); /* Enumeration finished */
USBH_USR_Status (*UserInput)(void);
int (*UserApplication) (void);
void (*DeviceNotSupported)(void); /* Device is not supported*/
void (*UnrecoveredError)(void);
}
USBH_Usr_cb_TypeDef;
/* USB Host 使用者介面 使用示例 */
USBH_Usr_cb_TypeDef USR_cb =
{
USBH_USR_Init,
USBH_USR_DeInit,
USBH_USR_DeviceAttached,
USBH_USR_ResetDevice,
USBH_USR_DeviceDisconnected,
USBH_USR_OverCurrentDetected,
USBH_USR_DeviceSpeedDetected,
USBH_USR_Device_DescAvailable,
USBH_USR_DeviceAddressAssigned,
USBH_USR_Configuration_DescAvailable,
USBH_USR_Manufacturer_String,
USBH_USR_Product_String,
USBH_USR_SerialNum_String,
USBH_USR_EnumerationDone,
USBH_USR_UserInput,
USBH_USR_MSC_Application,
USBH_USR_DeviceNotSupported,
USBH_USR_UnrecoveredError
};
注意事項
- 一旦使用了DMA( 高速模式下),所有結構體必須是四位元組對齊的。
- 如下即可使用 USB Host
/* 定義 USB_OTG_Core */
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_Core __ALIGN_END;
/* 定義 USB_Host */
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN USBH_HOST USB_Host __ALIGN_END;
/****注意:在非啟用到了DMA的高速模式下, 以上兩個定義可直接簡化(不需要對齊處理)如下:
* USB_OTG_CORE_HANDLE USB_OTG_Core;
* USBH_HOST USB_Host;
****/
/* 初始化 USB Host 庫 */
USBH_Init( &USB_OTG_Core,
#ifdef USE_USB_OTG_FS
USB_OTG_FS_CORE_ID,
#else
USB_OTG_HS_CORE_ID,
#endif
&USB_Host,
&USBH_MSC_cb,
&USR_cb );
/* 最後,週期呼叫以下函式即可 */
USBH_Process(&USB_OTG_Core, &USB_Host);
- 還需要在中斷處理檔案中,新增以下中斷(如果使用了其他功能的終端,自行新增):
/**
* @brief OTG_FS_IRQHandler
* This function handles USB-On-The-Go FS global interrupt request.
* requests.
* @param None
* @retval None
*/
#ifdef USE_USB_OTG_FS
void OTG_FS_IRQHandler(void)
#else
void OTG_HS_IRQHandler(void)
#endif
{
USBH_OTG_ISR_Handler(&USB_OTG_Core);
}
Fatfs部分
原始碼移植
目前,FatFS的最新版為R0.13a。從R0.13開始,作者將配置巨集統一為可FF_開頭。目前網上多數文章都是針對之前的,許多配置名與最新新版的原始碼是對不上。
使用FatFs最簡單的只需要關係兩個檔案即可:ff.c/h
和diskio.c/h
。其中,diskio.c/h
是一個模板,使用者需要自行實現與底層磁碟的讀寫。在ST提供的USB Host驅動中,已經實現了該檔案,名為usbh_msc_fatfs.c
。
更進一步,在使用了其他編碼例如中文及長檔名時,則需要將ffunicode.c
包含到自己的專案中。此外,在使用了系統時,還必須將ffsystem.c
包含到專案中,並按照自己的系統,修改該檔案。
原始碼配置
FatFS的配置通過一個名為ffconf.h
的檔案實現。對於每個選項,模板中都有很詳細的說明。同時,為減小FatFs佔用的空間,一般只開啟需要的選項。以下僅對幾個特殊的進行註釋性說明。
/*---------------------------------------------------------------------------/
/ FatFs - Configuration file
/---------------------------------------------------------------------------*/
#define FFCONF_DEF 89352 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
#define FF_FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define FF_FS_MINIMIZE 0
/* This option defines minimization level to remove some basic API functions.
/
/ 0: Basic functions are fully enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define FF_USE_STRFUNC 1
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define FF_USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define FF_USE_FASTSEEK 0
/* This option switches fast seek function. (0:Disable or 1:Enable) */
#define FF_USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define FF_USE_CHMOD 0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
#define FF_USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define FF_USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
/* Code Page,是字元編碼的另一種說法。Code Page包含了一個表,表中的值,用於表示針對某種語言所用的字符集。更簡單點說,就是Code Page中,用一個數字編號,表示了所要採用何種字元編碼,去編解碼相應的值,用於正確顯示出相應的字元。*/
#define FF_CODE_PAGE 932
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect code page setting can cause a file open failure.
/
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
/ 0 - Include all code pages above and configured by f_setcp()
*/
/* 長檔名。這個是微軟的專利!開啟後 必須包含 ffunicode.c */
#define FF_USE_LFN 0
#define FF_MAX_LFN 255
/* The FF_USE_LFN switches the support for LFN (long file name).
/
/ 0: Disable LFN. FF_MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
/ specification.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree() in ffsystem.c, need to be added to the project. */
/* 必須開啟 Unicode支援 */
#define FF_LFN_UNICODE 0
/* This option switches the character encoding on the API when LFN is enabled.
/
/ 0: ANSI/OEM in current CP (TCHAR = char)
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
/ 2: Unicode in UTF-8 (TCHAR = char)
/
/ Also behavior of string I/O functions will be affected by this option.
/ When LFN is not enabled, this option has no effect. */
#define FF_LFN_BUF 255
#define FF_SFN_BUF 12
/* This set of options defines size of file name members in the FILINFO structure
/ which is used to read out directory items. These values should be suffcient for
/ the file names to read. The maximum possible length of the read file name depends
/ on character encoding. When LFN is not enabled, these options have no effect. */
#define FF_STRF_ENCODE 3
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
/ This option selects assumption of character encoding ON THE FILE to be
/ read/written via those functions.
/
/ 0: ANSI/OEM in current CP
/ 1: Unicode in UTF-16LE
/ 2: Unicode in UTF-16BE
/ 3: Unicode in UTF-8
*/
#define FF_FS_RPATH 0
/* This option configures support for relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define FF_VOLUMES 1
/* Number of volumes (logical drives) to be used. (1-10) */
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
/* FF_STR_VOLUME_ID switches string support for volume ID.
/ When FF_STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to FF_VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define FF_MULTI_PARTITION 0
/* This option switches support for multiple volumes on the physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When this function is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ funciton will be available. */
#define FF_MIN_SS 512
#define FF_MAX_SS 512
/* This set of options configures the range of sector size to be supported. (512,
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS,