Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DMA
elm_fatfs_FAT文件系统
SDIO总线
基于cubemx创建的sdio+dma工程移植fatfs_r0.14的过程记录
发布于 2021-12-11 09:41:45 浏览:1688
订阅该版
近期在使用cubemx创建的sdio+dma+fatfs项目中使用fatfs文件管理系统读取中文文件名,得到的文件名编码方式是GBK的,想要输出为utf8编码格式的,尝试了多种转换方式都不成功,最后请教大佬获悉,是cubemx生成的项目中使用的fatfs的版本比较旧,不支持utf8编码方式,需要用新版本的才能支持,在此感谢交流群中提供帮助的大佬“温故而知心”。 于是查找了网上关于如何移植fatfs的贴子,大多年代比较久远,或者是直接就是由cubemx生成的。而我想要移植的比较新版本的fatfs14版本比较少提及,于是自己参考大佬们的贴子,摸索着移植了一遍,成功了,赶紧记录下来。方便后来者参考,也顺便做个记录,哪天自己需要用到了可以拿出来再参考一遍。 首先,是使用cubemx配置一个sdio+dma的项目,并生成代码编译。下面是关于cubemx配置的截图。 关于sdio的配置,需要配置中断+DMA,由于后续需要将此功能移植到rtos上,因此SDIO中断优先级要配置为5,DMA的中断优先级配置成6    关于是时钟树的配置  和SDIO相关的GPIO要配置成上拉,由于我硬件上没有外部上拉电阻,是直接将TF卡引脚和单片机的GPIO相连接的,所以需要这么配置。如果有外部上拉电阻,可以不需要配置内部上拉。  生成代码编译通过没有问题。 接下来是到fatfs官网下载新版本的Fatfs源码 FatFs - Archives http://elm-chan.org/fsw/ff/archives.html 这里我下载的是fatfs r0.14版本  下载得到一个ff14的压缩包,解压出来。  源码都在source的文件夹内  现在将ff14文件夹复制到刚才建立的项目内,并在项目中添加上述源码文件  然后就是开始写SDIO读写的驱动代码,这里我参考了st的代码风格,自己创建了一个驱动文件bsp_driver_sdio.c。其中大部分的代码可以照搬ST官方的。其中主要的函数包括SDIO初始化,状态读取,block读写等等。 bsp_driver_sdio.c文件源码如下: ``` #include "bsp_driver_sdio.h" // 该句柄在sdio.c文件中声明 extern SD_HandleTypeDef hsd; // 用来检测SD卡是否有插入,根据硬件连线, // SD卡插入卡槽,读IO口状态为0,返回1 // SD卡没有插入,读IO口状态为1,返回0 uint8_t BSP_PlatformIsDetected(void) { uint8_t status = SD_PRESENT; /* Check SD card detect pin */ if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_RESET) { status = SD_NOT_PRESENT; } /* USER CODE BEGIN 1 */ /* user code can be inserted here */ /* USER CODE END 1 */ return status; } // SDIO初始化 /** * @brief Initializes the SD card device. * @retval SD status */ __weak uint8_t BSP_SD_Init(void) { uint8_t sd_state = MSD_OK; /* Check if the SD card is plugged in the slot */ if (BSP_SD_IsDetected() != SD_PRESENT) { return MSD_ERROR; } /* HAL SD initialization */ sd_state = HAL_SD_Init(&hsd); /* Configure SD Bus width (4 bits mode selected) */ if (sd_state == MSD_OK) { /* Enable wide operation */ if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK) { sd_state = MSD_ERROR; } } return sd_state; } /* USER CODE BEGIN InterruptMode */ /** * @brief Configures Interrupt mode for SD detection pin. * @retval Returns 0 */ __weak uint8_t BSP_SD_ITConfig(void) { /* Code to be updated by the user or replaced by one from the FW pack (in a stmxxxx_sd.c file) */ return (uint8_t)0; } /** @brief SD detect IT treatment */ __weak void BSP_SD_DetectIT(void) { /* Code to be updated by the user or replaced by one from the FW pack (in a stmxxxx_sd.c file) */ } // SDIO 读BLOCK,普通读操作,没有中断,没有DMA /** * @brief Reads block(s) from a specified address in an SD card, in polling mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param ReadAddr: Address from where data is to be read * @param NumOfBlocks: Number of SD blocks to read * @param Timeout: Timeout for read operation * @retval SD status */ __weak uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout) { uint8_t sd_state = MSD_OK; if (HAL_SD_ReadBlocks(&hsd, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) != HAL_OK) { sd_state = MSD_ERROR; } return sd_state; } // SDIO 写BLOCK,普通写操作,没有中断,没有DMA /** * @brief Writes block(s) to a specified address in an SD card, in polling mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param WriteAddr: Address from where data is to be written * @param NumOfBlocks: Number of SD blocks to write * @param Timeout: Timeout for write operation * @retval SD status */ __weak uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout) { uint8_t sd_state = MSD_OK; if (HAL_SD_WriteBlocks(&hsd, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) != HAL_OK) { sd_state = MSD_ERROR; } return sd_state; } // SDIO,读BLOCK,DMA读操作 /** * @brief Reads block(s) from a specified address in an SD card, in DMA mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param ReadAddr: Address from where data is to be read * @param NumOfBlocks: Number of SD blocks to read * @retval SD status */ __weak uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks) { uint8_t sd_state = MSD_OK; /* Read block(s) in DMA transfer mode */ if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)pData, ReadAddr, NumOfBlocks) != HAL_OK) { sd_state = MSD_ERROR; } return sd_state; } // SDIO,写BLOCK,DMA操作 /** * @brief Writes block(s) to a specified address in an SD card, in DMA mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param WriteAddr: Address from where data is to be written * @param NumOfBlocks: Number of SD blocks to write * @retval SD status */ __weak uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks) { uint8_t sd_state = MSD_OK; /* Write block(s) in DMA transfer mode */ if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)pData, WriteAddr, NumOfBlocks) != HAL_OK) { sd_state = MSD_ERROR; } return sd_state; } // SDIO,擦除操作 /** * @brief Erases the specified memory area of the given SD card. * @param StartAddr: Start byte address * @param EndAddr: End byte address * @retval SD status */ __weak uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr) { uint8_t sd_state = MSD_OK; if (HAL_SD_Erase(&hsd, StartAddr, EndAddr) != HAL_OK) { sd_state = MSD_ERROR; } return sd_state; } /** * @brief Gets the current SD card data status. * @param None * @retval Data transfer state. * This value can be one of the following values: * @arg SD_TRANSFER_OK: No data transfer is acting * @arg SD_TRANSFER_BUSY: Data transfer is acting */ __weak uint8_t BSP_SD_GetCardState(void) { return ((HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER ) ? SD_TRANSFER_OK : SD_TRANSFER_BUSY); } /** * @brief Get SD information about specific SD card. * @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure * @retval None */ __weak void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo) { /* Get SD card Information */ HAL_SD_GetCardInfo(&hsd, CardInfo); } /* USER CODE BEGIN BeforeCallBacksSection */ /* can be used to modify previous code / undefine following code / add code */ /* USER CODE END BeforeCallBacksSection */ /** * @brief SD Abort callbacks * @param hsd: SD handle * @retval None */ void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd) { BSP_SD_AbortCallback(); } /** * @brief Tx Transfer completed callback * @param hsd: SD handle * @retval None */ void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd) { BSP_SD_WriteCpltCallback(); } /** * @brief Rx Transfer completed callback * @param hsd: SD handle * @retval None */ void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd) { BSP_SD_ReadCpltCallback(); } /* USER CODE BEGIN CallBacksSection_C */ /** * @brief BSP SD Abort callback * @retval None * @note empty (up to the user to fill it in or to remove it if useless) */ __weak void BSP_SD_AbortCallback(void) { } /** * @brief BSP Tx Transfer completed callback * @retval None * @note empty (up to the user to fill it in or to remove it if useless) */ __weak void BSP_SD_WriteCpltCallback(void) { } /** * @brief BSP Rx Transfer completed callback * @retval None * @note empty (up to the user to fill it in or to remove it if useless) */ __weak void BSP_SD_ReadCpltCallback(void) { } /** * @brief Detects if SD card is correctly plugged in the memory slot or not. * @param None * @retval Returns if SD is detected or not */ __weak uint8_t BSP_SD_IsDetected(void) { __IO uint8_t status = SD_PRESENT; if (BSP_PlatformIsDetected() == 0x0) { status = SD_NOT_PRESENT; } return status; } ``` bsp_driver_sdio.h文件源码如下: ``` #ifndef __bsp_driver_sd_h #define __bsp_driver_sd_h #ifdef __cplusplus extern "C" { #endif #include "stm32f4xx_hal.h" // 用来监测SD卡是否有插入 #define SD_PRESENT ((uint8_t)0x01) /* also in bsp_driver_sd.h */ #define SD_NOT_PRESENT ((uint8_t)0x00) /* also in bsp_driver_sd.h */ #define SD_DETECT_PIN GPIO_PIN_0 #define SD_DETECT_GPIO_PORT GPIOB uint8_t BSP_PlatformIsDetected(void); // SDIO底层初始化,读写相关的函数 /** * @brief SD Card information structure */ #define BSP_SD_CardInfo HAL_SD_CardInfoTypeDef /** * @brief SD status structure definition */ #define MSD_OK ((uint8_t)0x00) #define MSD_ERROR ((uint8_t)0x01) /** * @brief SD transfer state definition */ #define SD_TRANSFER_OK ((uint8_t)0x00) #define SD_TRANSFER_BUSY ((uint8_t)0x01) #define SD_PRESENT ((uint8_t)0x01) #define SD_NOT_PRESENT ((uint8_t)0x00) #define SD_DATATIMEOUT ((uint32_t)100000000) /* Exported functions --------------------------------------------------------*/ uint8_t BSP_SD_Init(void); uint8_t BSP_SD_ITConfig(void); void BSP_SD_DetectIT(void); void BSP_SD_DetectCallback(void); uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout); uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout); uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks); uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks); uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr); void BSP_SD_IRQHandler(void); void BSP_SD_DMA_Tx_IRQHandler(void); void BSP_SD_DMA_Rx_IRQHandler(void); uint8_t BSP_SD_GetCardState(void); void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypeDef *CardInfo); uint8_t BSP_SD_IsDetected(void); /* These functions can be modified in case the current settings (e.g. DMA stream) need to be changed for specific application needs */ void BSP_SD_AbortCallback(void); void BSP_SD_WriteCpltCallback(void); void BSP_SD_ReadCpltCallback(void); #ifdef __cplusplus } #endif #endif ``` 接下来就是修改diskio.c文件了,目的就是完善磁盘初始化,磁盘读写等函数。由于我的项目中只需要用到sdio一个外设,因此我注释掉其他没有使用到的代码,直接写入对于sdio的读写驱动。 diskio.c文件源码如下: ``` /*-----------------------------------------------------------------------*/ /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2019 */ /*-----------------------------------------------------------------------*/ /* 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 modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ #include "ff.h" /* Obtains integer types */ #include "diskio.h" /* Declarations of disk functions */ /* Definitions of physical drive number for each drive */ //#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ //#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ //#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ // 这里只考虑驱动SDIO的情况,因此注释掉原来的相关内容,替换成和SDIO驱动相关的函数和内容 // 相关函数内容参考的是使用cubemx生成代码中的sd_diskio.c //#include "bsp_driver_sdio.c" #define SD_TIMEOUT 30 * 1000 #define SD_DEFAULT_BLOCK_SIZE 512 static volatile DSTATUS Stat = STA_NOINIT; static volatile UINT WriteStatus = 0, ReadStatus = 0; // 下面会调用到的外部函数引用 extern uint32_t HAL_GetTick(void); extern uint8_t BSP_SD_GetCardState(void); extern uint8_t BSP_SD_Init(void); extern uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks); extern uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks); #define MSD_OK ((uint8_t)0x00) #define MSD_ERROR ((uint8_t)0x01) #define SD_TRANSFER_OK ((uint8_t)0x00) #define SD_TRANSFER_BUSY ((uint8_t)0x01) // 在一段时间内查询SDIO的状态,超时返回 static int SD_CheckStatusWithTimeout(uint32_t timeout) { uint32_t timer = HAL_GetTick(); /* block until SDIO IP is ready again or a timeout occur */ while(HAL_GetTick() - timer < timeout) { if (BSP_SD_GetCardState() == SD_TRANSFER_OK) { return 0; } } return -1; } // 查询SDIO的状态 static DSTATUS SD_CheckStatus(BYTE lun) { Stat = STA_NOINIT; if(BSP_SD_GetCardState() == MSD_OK) { Stat &= ~STA_NOINIT; } return Stat; } /*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { // DSTATUS stat; // int result; // switch (pdrv) { // case DEV_RAM : // result = RAM_disk_status(); // // translate the reslut code here // return stat; // case DEV_MMC : // result = MMC_disk_status(); // // translate the reslut code here // return stat; // case DEV_USB : // result = USB_disk_status(); // // translate the reslut code here // return stat; // } // return STA_NOINIT; // 返回SDIO状态,作为磁盘状态 return SD_CheckStatus(pdrv); } /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { // DSTATUS stat; // int result; // switch (pdrv) { // case DEV_RAM : // result = RAM_disk_initialize(); // // translate the reslut code here // return stat; // case DEV_MMC : // result = MMC_disk_initialize(); // // translate the reslut code here // return stat; // case DEV_USB : // result = USB_disk_initialize(); // // translate the reslut code here // return stat; // } // return STA_NOINIT; // 初始化SDIO,作为磁盘初始化 if(BSP_SD_Init() == MSD_OK) { Stat = SD_CheckStatus(pdrv); } 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 */ LBA_t sector, /* Start sector in LBA */ UINT count /* Number of sectors to read */ ) { // DRESULT res; // int result; // switch (pdrv) { // case DEV_RAM : // // translate the arguments here // result = RAM_disk_read(buff, sector, count); // // translate the reslut code here // return res; // case DEV_MMC : // // translate the arguments here // result = MMC_disk_read(buff, sector, count); // // translate the reslut code here // return res; // case DEV_USB : // // translate the arguments here // result = USB_disk_read(buff, sector, count); // // translate the reslut code here // return res; // } // return RES_PARERR; // SDIO BLOCK DMA READ作为磁盘读操作 DRESULT res = RES_ERROR; uint32_t timeout; // 首先确保之前一次操作已经完成 if (SD_CheckStatusWithTimeout(SD_TIMEOUT) < 0) { return res; } // SDIO READ BLOCK DMA if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,(uint32_t)(sector),count) == MSD_OK){ ReadStatus = 0; /* Wait that the reading process is completed or a timeout occurs */ timeout = HAL_GetTick(); while((ReadStatus == 0)&&((HAL_GetTick()-timeout)
= 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 support for volume ID in arbitrary strings. / When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive / number in the path name. FF_VOLUME_STRS defines the volume ID strings for each / logical drives. Number of items must not be less than FF_VOLUMES. Valid / characters for the volume ID strings are A-Z, a-z and 0-9, however, they are / compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is / not defined, a user defined volume string table needs to be defined as: / / const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... */ #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, FatFs is configured / for variable sector size mode and disk_ioctl() function needs to implement / GET_SECTOR_SIZE command. */ #define FF_LBA64 0 /* This option switches support for 64-bit LBA. (0:Disable or 1:Enable) / To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */ #define FF_MIN_GPT 0x100000000 /* Minimum number of sectors to switch GPT format to create partition in f_mkfs and / f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */ #define FF_USE_TRIM 0 /* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) / To enable Trim function, also CTRL_TRIM command should be implemented to the / disk_ioctl() function. */ /*---------------------------------------------------------------------------/ / System Configurations /---------------------------------------------------------------------------*/ #define FF_FS_TINY 0 /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) / At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. / Instead of private sector buffer eliminated from the file object, common sector / buffer in the filesystem object (FATFS) is used for the file data transfer. */ #define FF_FS_EXFAT 0 /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) / To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) / Note that enabling exFAT discards ANSI C (C89) compatibility. */ #define FF_FS_NORTC 0 #define FF_NORTC_MON 1 #define FF_NORTC_MDAY 1 #define FF_NORTC_YEAR 2019 /* The option FF_FS_NORTC switches timestamp functiton. If the system does not have / any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable / the timestamp function. Every object modified by FatFs will have a fixed timestamp / defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. / To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be / added to the project to read current time form real-time clock. FF_NORTC_MON, / FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. / These options have no effect in read-only configuration (FF_FS_READONLY = 1). */ #define FF_FS_NOFSINFO 0 /* If you need to know correct free space on the FAT32 volume, set bit 0 of this / option, and f_getfree() function at first time after volume mount will force / a full FAT scan. Bit 1 controls the use of last allocated cluster number. / / bit0=0: Use free cluster count in the FSINFO if available. / bit0=1: Do not trust free cluster count in the FSINFO. / bit1=0: Use last allocated cluster number in the FSINFO if available. / bit1=1: Do not trust last allocated cluster number in the FSINFO. */ #define FF_FS_LOCK 2//0 /* The option FF_FS_LOCK switches file lock function to control duplicated file open / and illegal operation to open objects. This option must be 0 when FF_FS_READONLY / is 1. / / 0: Disable file lock function. To avoid volume corruption, application program / should avoid illegal open, remove and rename to the open objects. / >0: Enable file lock function. The value defines how many files/sub-directories / can be opened simultaneously under file lock control. Note that the file / lock control is independent of re-entrancy. */ /* #include
// O/S definitions */ #define FF_FS_REENTRANT 0 #define FF_FS_TIMEOUT 1000 #define FF_SYNC_t HANDLE /* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs / module itself. Note that regardless of this option, file access to different / volume is always re-entrant and volume control functions, f_mount(), f_mkfs() / and f_fdisk() function, are always not re-entrant. Only file/directory access / to the same volume is under control of this function. / / 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. / 1: Enable re-entrancy. Also user provided synchronization handlers, / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() / function, must be added to the project. Samples are available in / option/syscall.c. / / The FF_FS_TIMEOUT defines timeout period in unit of time tick. / The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, / SemaphoreHandle_t and etc. A header file for O/S definitions needs to be / included somewhere in the scope of ff.h. */ /*--- End of configuration options ---*/ ``` 完成上述三个步骤之后,就可以main.c文件中编写挂载,文件读写的测试代码了。    到了这里全部都成功的话,就说明移植已经成功了。
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
adaphoto
这家伙很懒,什么也没写!
文章
25
回答
44
被采纳
5
关注TA
发私信
相关文章
1
代码分享,stm32f407的sdio驱动。
2
求个在STM32F103 RTT上使用SDIO接口的例子
3
是否能增加一个 SDIO AP61xx 的驱动呢
4
sdio和fsmc驱动lcd冲突
5
发现了sdio_unregister_driver里的一个bug
6
用sdio框架驱动过w8801(wifi模块)的坛友请进(已解决)
7
关于rt-thread系统sdio驱动框架使用
8
问题请教,关于在rt-thread中调试RT1052中调试sdio wifi模块
9
【文件系统学习】+海中陆地+RT-Thread文件系统学习挂载SDIO...
10
sdio驱动是怎么使用的?也没有文档和例程啊
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
UART
ESP8266
cubemx
WIZnet_W5500
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
RTT_逍遥
10
个答案
3
次被采纳
xiaorui
3
个答案
2
次被采纳
winfeng
2
个答案
2
次被采纳
三世执戟
8
个答案
1
次被采纳
KunYi
8
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
lizimu
2
篇文章
9
次点赞
swet123
1
篇文章
4
次点赞
Days
1
篇文章
4
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部