rt-thread驱动篇(07)---STM32F429单片机SD卡驱动添加
目录
一、SD基础知识
1.1、SD卡分类
1.2、SD卡的物理结构
1.3、SD卡寄存器
1.4、SDIO协议简介
二、SD卡驱动
2.1、CubeMX配置
2.2、ENV配置
2.3、驱动测试
一、SD基础知识
1.1、SD卡分类
STM32F4里,只支持SD 2.0协议,SD和SDHC属于这个范畴,SDXC是4.0协议,所以不支持;另外SDHC卡,有些数据块大小是512,有的是1024,STM32F4只支持读取512大小的,意思是说,SDHC卡的一部分也不支持的。其他相关的技术,可以去SD卡协会网站查看
1.2、SD卡的物理结构
SD卡一般支持SDIO和SPI两种接口,STM32F429x 系列控制器的SDIO是不支持SPI 通信模式的,如果需要用到SPI 通信只能使用SPI 外设。SDIO 不管是从主机控制器向SD 卡传输,还是SD 卡向主机控制器传输都只以CLK 时钟线的上升沿为有效。SD 卡操作过程会使用两种不同频率的时钟同步数据,一个是识别卡阶段时钟频率FOD,最高为400kHz,另外一个是数据传输模式下时钟频率FPP,默认最高为25MHz,如果通过相关寄存器配置使SDIO 工作在高速模式,此时数据传输模式最高频率为50MHz
1.3、SD卡寄存器
1.4、SDIO协议简介
原本SD协议是用在存储上的,后来扩展了一个叫SDIO的协议(全名:Secure Digital Input and Output),这个协议属于外设接口,使得它能连接一些外设,例如:GPS、相机、Wi-Fi、调频广播、以太网、条形码读卡器、蓝牙等,从此跳出存储这个局限
MMC 卡可以说是SD 卡的前身,现阶段已经用得很少
SD I/O 卡本身不是用于存储的卡,它是指利用SDIO 传输协议的一种外设
二、SD卡驱动
为了能满足不同SDIO设备的驱动,比如 SD I/O设备的驱动、SD Card的驱动、MMC的驱动,rtthread提供了SDIO的设备驱动框架,路径为 \rt-thread\components\drivers\sdio,对上通过I/O设备管理层给应用程序提供标准的API接口,对下通过 \libraries\HAL_Drivers\drv_sdio.c/h 驱动完成对STM32 SDIO外设的配置及读写操作,在drv_sdio.c中并没有使用STM32提供的HAL库驱动,而是直接操作的寄存器,但是会调用CubeMX配置生成的SDIO时钟配置及引脚初始化函数 HAL_SD_MspInit,所以在添加SDIO驱动前,需要先通过CubeMX配置SDIO生成HAL_SD_MspInit函数。
2.1、CubeMX配置
2.2、ENV配置
1、硬件驱动使能
/*添加 BSP_USING_SDCARD 宏*/
--->Hardware Drivers Config---> Onboard Periperal Drivers---> Enable SDCARD (sdio)
/*添加 BSP_USING_SDIO宏*/
--->Hardware Drivers Config---> On-chip Periperal Drivers---> Enable SDIO
/*配置 SDIO设备驱动框架 如下图*/
--->RT-Thread Components Configuration---> Device Drivers---> Using SD/MMC device drivers
2、文件系统配置
SD卡一般需要文件系统的支持,有了文件系统的加持,SD卡操作才能更加灵活方便。由于我前面已经在SPI FLASH上创建了一个elm-FAT,并且挂载到了 根目录(/)下,如果要再添加一个文件系统,需要先开启 RomFS文件系统,在根目录下创建2个文件夹,然后再将SPI FLASH和SD卡挂载到这两个文件夹下,因为同一个目录下不能同时挂载2个文件系统!!所以需要在menuconfig中修改 “挂载的文件系统数量”、“支持的文件系统类型数量”,系统中使用了dev、RomFS、elm-FAT3种文件系统, 分别为dev + RomFS + SPI FLASH elm-FAT + SD卡 elm-FAT 共4个
elm-FAT文件系统配置
配置的扇区大小会用于配置FatFs的_MAX_SS,FatFs中_MIN_SS定义最小扇区大小,_MAX_SS定义最大扇区大小。都设置为512可以兼容所有SD卡和硬盘,但是在SPI FLASH上需要更大值。当_MAX_SS > _MIN_SS,FatFs被配置为扇区大小可变的并且必须在函数disk_ioctl中实现GET_SECTOR_SIZE命令。也就是在操作SPI FLSH时扇区大小为4096,而在操作SD卡时会为512
3、注册具体的文件系统到DFS中
1、devfs_init() ---> dfs_register(&_device_fs) /* 如果开启了RT_USING_DFS_DEVFS,则会在dfs_init中完成自动初始化*/
2、elm_init()/dfs_elm.c --> dfs_register(&dfs_elm) /* 初始化elm文件系统 ,已INIT_COMPONENT_EXPORT自动添加,不在需要手动调用*/
3、dfs_romfs_init()/dfs_romfs.c --> dfs_register(&_romfs) /* 初始化romfs文件系统,已INIT_COMPONENT_EXPORT自动添加,不在需要手动调用 */
4、块设备挂载
挂载是指将一个存储设备挂接到一个已存在的路径上。我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的路径上,然后通过这个路径来访问存储设备。这里分别将W25Q12864的"fs"分区挂载到 /w25q 目录下、SD卡挂载到 /sdcard目录下
#if defined(BSP_USING_SPI_FLASH)
static int rt_hw_spi_flash_init(void)
{__HAL_RCC_GPIOG_CLK_ENABLE();rt_soft_spi_device_attach("softspi1", "softspi10", GPIOG, GPIO_PIN_10);if (RT_NULL == rt_sfud_flash_probe("W25Q64", "softspi10")){return -RT_ERROR;}return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
#endif#if defined(PKG_USING_FAL)
int fs_init(void)
{/* partition initialized */fal_init();return 0;
}
INIT_COMPONENT_EXPORT(fs_init);
#endif#if defined(RT_USING_DFS_ELMFAT)
#define FS_PARTITION_NAME "fs"
extern const struct romfs_dirent romfs_root;
int elm_fatfs_init(void)
{/* partition initialized */
// elm_init();//dfs_mkfs("elm", "fs"); /* 在fs块设备上创建elm文件系统*//* Create a block device on the "fs" partition of spi flash */struct rt_device *flash_dev = fal_blk_device_create(FS_PARTITION_NAME);if (flash_dev == NULL) {LOG_D("Can't create a block device on '%s' partition", FS_PARTITION_NAME);} else {LOG_I("Create a block device on the %s partition of flash successful", FS_PARTITION_NAME);}#if defined(RT_USING_DFS_ROMFS)/* mount ROMFS as root directory */if (dfs_mount(RT_NULL, "/", "rom", 0, &(romfs_root)) == 0) {LOG_I("ROMFS filesystem initialized!");} else {LOG_D("ROMFS filesystem initialized Failed!");}/* mount elm file system from "fs" partition of spi flash to /w25q. */if (dfs_mount(FS_PARTITION_NAME, "/w25q", "elm", 0, 0) == 0){LOG_I("FATFS filesystem initialized!");} else {LOG_E("Failed to initialize FATFS filesystem!");LOG_D("You should create a filesystem on the block device first!");}
#elif /* mount elm file system from "fs" partition of spi flash to / */if (dfs_mount(FS_PARTITION_NAME, "/", "elm", 0, 0) == 0) {LOG_I("FATFS filesystem initialized!");} else {LOG_E("Failed to initialize filesystem!");LOG_D("You should create a filesystem on the block device first!");}
#endif //RT_USING_DFS_ROMFSreturn 0;
}
INIT_COMPONENT_EXPORT(elm_fatfs_init);
#endifvoid sd_mount(void *parameter)
{while (1){rt_thread_mdelay(500);if(rt_device_find("sd0") != RT_NULL){if (dfs_mount("sd0", "/sdcard", "elm", 0, 0) == RT_EOK){LOG_I("sd card mount to '/sdcard'");break;}else{LOG_W("sd card mount to '/sdcard' failed!");}}}
}
/w25q目录和/sdcard在挂载RomFS的时候会被自动创建
2.3、驱动测试
测试SD卡的读写速度
rt-thread驱动篇(07)---STM32F429单片机SD卡驱动添加相关推荐
- rt-thread驱动篇(08)---STM32F429单片机NAND FLASH驱动
目录 参考资料 一.NAND FLASH 1.1.特性 1.2.存储单元结构 1.3.NAND FLASH寻址 1.4.坏块管理与磨损均衡 1.5.ECC校验 二.uffs 1.uffs配置相关宏 参 ...
- Linux格式化sd卡博客,linux设备驱动那点事儿之SD卡驱动理论篇
一.SD/MMC卡介绍 1.1.什么是MMC卡 MMC:MMC就是MultiMediaCard的缩写,即多媒体卡.它是一种非易失性存储器件,体积小巧(24mm*32mm*1.4mm),容量大,耗电量低 ...
- linux设备驱动那点事儿之SD卡驱动理论篇
一.SD/MMC卡介绍 1.1.什么是MMC卡 MMC:MMC就是MultiMediaCard的缩写,即多媒体卡.它是一种非易失性存储器件,体积小巧(24mm*32mm*1.4mm),容量大,耗电量低 ...
- wince下SD卡驱动开发
WinCE 5.0下面SD卡驱动的开发.这是我做的第一个项目,当时做这个项目花费了相当的时间和精力,搞的我精疲力尽.几乎可以说当时对WinCE一点都不懂.也不知道从何处下手,就东看西看.东改西改,改的 ...
- STM32F1与STM32CubeIDE快速入门-SD卡驱动-SDIO+FatFs
SD卡驱动-SDIO+FatFs 文章目录 SD卡驱动-SDIO+FatFs 1.SDIO与FatFs简单介绍 2.SDIO与FatFs配置 3.SDIO与FatFs功能测试 4.代码解析 5.STM ...
- Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇
Core层中有两个重要函数 mmc_alloc_host 用于构造host,前面已经学习过,这里不再阐述:另一个就是 mmc_add_host,用于注册host 前面探测函数s3cmci_probe, ...
- rt-thread SDIO驱动框架分析(SD卡驱动\SD Nand驱动)
rt-thread SDIO驱动框架分析之SD卡驱动 文章目录 rt-thread SDIO驱动框架分析之SD卡驱动 1. 前言 2. SDIO通用驱动框架介绍 3. 文件架构分析 4. SDIO设备 ...
- 卡函数or1200基于simple-spi的SD卡驱动
每日一贴,天今的内容关键字为卡函数 这篇blog来说说基于simple-spi这个ipcore编写spi模式的SD Card裸机的驱动程序,植移依附分不清什么SD卡啊,micro SD啊,miniSD ...
- NUC970 SD卡驱动(SDIO)
在读取SD卡的R2长响应折腾了不少时间,原因是必须开启DMA,不开启DMA,R2响应将不会传输到SDIO的FIFO中,将SDIO接口与STM32保持一致,并兼容应用层SDIO_SDCARD驱动. 寄存 ...
- Linux SD卡驱动
二.MMC/SD介绍及SDI主机控制器 首先我们来理清几个概念: MMC:(Multi Media Card)由西门子公司和首推CF的SanDisk于1997年推出的多媒体记忆卡标准. SD:(Sec ...
最新文章
- PowerDesigner教程系列(总)
- [故障公告]14:40-15:00博客站点web服务器雪崩似的CPU 100%
- 【Linux】一步一步学Linux——gdb命令(258)
- Event 事件 - 基础
- #6029. 「雅礼集训 2017 Day1」市场(势能,区间除)
- linux root邮箱地址,linux – 如何将root的电子邮件转发到外部电子邮件地址?
- 深度 | 数据湖分析算力隔离技术剖析
- 程序员败给了一个厨子,读书无用论让我 必须送书了
- 信息学奥赛一本通(1082:求小数的某一位)
- Vue2+VueRouter2+webpack 构建项目实战系列(完整版) - 收录篇
- Java读取json文件,再生产新的json文件
- Python:批量爬取下载中国知网(CNKI)PDF论文
- centos实现证书登录禁止密码登录
- 司空见惯 - 体彩中奖交多少税
- Java面向对象编程及其三大特征
- 各省历年排污费入库金额(2008-2017年)
- CGAL license说明
- html5闪光效果,HTML5 canvas元素背景梦幻小星星闪烁特效
- STP和RSTP的BPDU报文中flag位 对比+分析
- 家电企业如何利用APS生产排产应对市场变化调整生产?
热门文章
- 【IT项目管理】第1章 走进IT项目管理
- Linux下的Scala安装
- 互联网晚报 | 1月17日 星期一 | 飞猪推出买机票送核酸检测券服务;洋码头首个文旅场景免税店开业;2022年春运今日开启...
- 【硬件】贴片电阻的封装尺寸及丝印标注
- i78750h和i58300h对比哪个好
- ABBYY FineReader15老牌ocr文字识别软件
- 中国宽带可调谐飞秒激光器行业市场供需与战略研究报告
- 三角形和矩形傅里叶变换_第3章傅立叶变换.doc
- 【新闻推荐系统】(task3)Scrapy基础及新闻爬取实战
- FFmpeg采集树莓派USB摄像头(UVC摄像头)