目录
一、开发环境
硬件:野火stm32f407 开发板
系统版本:rt-thread v4.1.1 ,基于stm32f407-atk-explorerbsp包
二、硬件介绍
2.1 SDIO简介
SD卡(Secure Digital Memory Card)在我们生活中已经非常普遍了,控制器对SD卡进行读写通信操作一般有两种通信接口可选,一种是SPI接口,另外一种就是SDIO接口。SDIO全称是安全数字输入/输出接口,多媒体卡(MMC)、SD卡、SD I/O卡都有SDIO接口。STM32F10x系列控制器有一个SDIO主机接口,它可以与MMC卡、SD卡、SD I/O卡以及CE-ATA设备进行数据传输。MMC卡可以说是SD卡的前身,现阶段已经用得很少。SD I/O卡本身不是用于存储的卡,它是指利用SDIO传输协议的一种外设。比如Wi-Fi Card,它主要是提供Wi-Fi功能,有些Wi-Fi模块是使用串口或者SPI接口进行通信的,但Wi-Fi SDIO Card是使用SDIO接口进行通信的。并且一般设计SD I/O卡是可以插入到SD的插槽。CE-ATA是专为轻薄笔记本硬盘设计的硬盘高速通讯接口。
多媒体卡协会网站中提供了有MMCA技术委员会发布的多媒体卡系统规范。
SD卡协会网站 https://www.sdcard.org/ 中提供了SD存储卡和SDIO卡系统规范。
CE-ATA工作组网站 https://www.ce-ata.org/ 中提供了CE_ATA系统规范。
SDIO接口的设备
一张SD卡包括有存储单元、存储单元接口、电源检测、卡及接口控制器 和 接口驱动器 5个部分。存储单元是存储数据部件,存储单元通过存储单元接口与卡控制单元进行数据传输;电源检测单元保证SD卡工作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接口复位;卡及接口控制单元控制SD卡的运行状态,它包括有8个寄存器;接口驱动器控制SD卡引脚的输入输出。
SD卡总共有8个寄存器,用于设定或表示SD卡信息。这些寄存器只能通过对应的命令访问,对SD卡进行控制操作并不是像操作控制器GPIO相关寄存器那样一次读写一个寄存器的,它是通过命令来控制,SDIO定义了64个命令,每个命令都有特殊意义,可以实现某一特定功能,SD卡接收到命令后,根据命令要求对SD卡内部寄存器进行修改,程序控制中只需要发送组合命令就可以实现SD卡的控制以及读写操作。
SD卡总线拓扑,虽然可以共用总线,但不推荐多卡槽共用总线信号,要求一个单独SD总线应该连接一个单独的SD卡。
SD卡使用9-pin接口通信,其中3根电源线、1根时钟线、1根命令线和4根数据线,具体说明如下:
CLK:时钟线,由SDIO主机产生,即由STM32控制器输出;
CMD:命令控制线,SDIO主机通过该线发送命令控制SD卡,如果命令要求SD卡提供应答(响应),SD卡也是通过该线传输应答信息;
D0-3:数据线,传输读写数据;SD卡可将D0拉低表示忙状态;
VDD、VSS1、VSS2:电源和地信号。
SDIO的通信时序简单许多,SDIO不管是从主机控制器 向SD卡传输,还是SD卡向主机控制器传输都只以CLK时钟线的上升沿为有效。SD卡操作过程会使用两种不同频率 的时钟同步数据,一个是识别卡阶段时钟频率FOD,最高为400kHz,另外一个是数据传输模式下时钟频率FPP,默认最高 为25MHz,如果通过相关寄存器配置使SDIO工作在高速模式,此时数据传输模式最高频率为50MHz。
对于STM32控制器只有一个SDIO主机,所以只能连接一个SDIO设备。
总线协议:SD总线通信是基于命令和数据传输的。通讯由一个起始位(“0”),由一个停止位(“1”)终止。SD通信一般是主机发送一个命令(Command),从设备在接收到命令后作出响应(Response),如有需要会有数据(Data)传输参与。
SD总线的基本交互是命令与响应交互。
SD数据是以块(Black)形式传输的,SDHC卡数据块长度一般为512字节,数据可以从主机到卡,也可以是从卡到主机。数据块需要CRC位来 保证数据传输成功。CRC位由SD卡系统硬件生成。STM32控制器可以控制使用单线或4线传输,本开发板设计使用4线传输。
SD数据传输支持单块和多块读写,它们分别对应不同的操作命令,多块写入还需要使用命令来停止整个写入操作。数据写入前需要检测SD卡忙状态,因为SD卡在接收到数据后编程到存储区过程需要一定操作时间。SD卡忙状态通过把D0线拉低表示。
数据块读操作与之类似,只是无需忙状态检测。
2.2 开发板原理图
原理图
三、工程配置
3.1 开启 sdio
3.2 开启 dfs 虚拟文件系统 和 POSIX 接口
注意:
操作SPI Flash建议使用嵌入式文件系统,他们支持掉电保护和擦写均衡。可选择如下:
sd卡已经自带磨损均衡功能了,可直接用fatfs文件系统。
RT-Thread DFS 组件的主要功能特点有:
1、为应用程序提供统一的 POSIX 文件和目录操作接口:read、write、poll/select 等。
2、支持多种类型的文件系统,如 FatFS、RomFS、DevFS 等,并提供普通文件、设备文件、网络文件描述符的管理。
3、支持多种类型的存储设备,如 SD Card、SPI Flash、Nand Flash 等。
一般 Flash 设备可以设置为 4096,常见的 TF 卡和 SD 卡的扇区大小设置为 512。
3.3 开启 RTC
3.4 开启 HAL 库SD的宏定义
3.5 初始化函数
使用 stm32cubemx 生成初始化函数,复制到工程。
四、测试代码
测试代码:
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 SummerGift first version
* 2018-11-19 flybreak add stm32f407-atk-explorer bsp
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <dfs_fs.h>
#include <unistd.h>
/* defined the LED0 pin: PF6 */
#define LED0_PIN GET_PIN(F, 6)
#include <rtdevice.h>
#include <rtthread.h>
#define RTC_NAME "rtc"
static int rtc_test(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
time_t now;
rt_device_t device = RT_NULL;
/*寻找设备*/
device = rt_device_find(RTC_NAME);
if (!device)
{
return RT_ERROR;
}
if(argc != 7)
{
/*初始化RTC设备*/
if(rt_device_open(device, 0) != RT_EOK)
{
return RT_ERROR;
}
/* 设置日期 */
ret = set_date(2024, 9, 10);
if (ret != RT_EOK)
{
rt_kprintf("set RTC date failed\n");
return ret;
}
/* 设置时间 */
ret = set_time(19, 22, 30);
if (ret != RT_EOK)
{
rt_kprintf("set RTC time failed\n");
return ret;
}
}
else
{
/*初始化RTC设备*/
if(rt_device_open(device, 0) != RT_EOK)
{
return RT_ERROR;
}
/* 设置日期 */
ret = set_date(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
if (ret != RT_EOK)
{
rt_kprintf("set RTC date failed\n");
return ret;
}
/* 设置时间 */
ret = set_time(atoi(argv[4]), atoi(argv[5]), atoi(argv[6]));
if (ret != RT_EOK)
{
rt_kprintf("set RTC time failed\n");
return ret;
}
}
/* 延时3秒 */
rt_thread_mdelay(3000);
/* 获取时间 */
now = time(RT_NULL);
rt_kprintf("%s\n", ctime(&now));
return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(rtc_test, rtc test);
int bsp_sdcard_test(void)
{
int fd, size;
char s[] = "hello elmfatfs!", buffer[80];
//----------------------------------------------------
rt_thread_mdelay(100); //等待sd_mount线程挂载文件系统,可使用IPC信号量完成同步,提高实时性
rt_kprintf("Write string %s to test.txt.\n", s);
/* 以创建和读写模式打开 /text.txt 文件,如果该文件不存在则创建该文件 */
fd = open("/text.txt", O_WRONLY | O_CREAT);
if (fd>= 0)
{
write(fd, s, sizeof(s));
close(fd);
rt_kprintf("Write done.\n");
}
/* 以只读模式打开 /text.txt 文件 */
fd = open("/text.txt", O_RDONLY);
if (fd>= 0)
{
size = read(fd, buffer, sizeof(buffer));
close(fd);
rt_kprintf("Read from file test.txt : %s \n", buffer);
if (size < 0)
return -RT_ERROR;
}
return 0;
}
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
//rt_thread_mdelay(5000);
while(rt_device_find("sd0") == RT_NULL)
{
rt_thread_mdelay(1000);
}
if(rt_device_find("sd0") != RT_NULL)
{
if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)//挂载成功
{
rt_kprintf("sd0 mount ok\r\n");
bsp_sdcard_test();
}
else
{
if(dfs_mkfs("elm","sd0") == 0)//挂载前需格式化
{
if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)//挂载成功
{
rt_kprintf("sd0 mount ok\r\n");
bsp_sdcard_test();
}
else
{
rt_kprintf("sd0 mount err\r\n");
}
}
else
{
rt_kprintf("sd0 mkfs err\r\n");
}
}
}
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
错误提示:
implicit declaration of function 'read'
implicit declaration of function 'write'
#223-D: function "write" declared implicitly
read 和 write 是 声明在 unistd.h 头文件的函数,添加 #include <unistd.h> 头文件即可。
#include <unistd.h>
测试结果:
五、工程快捷配置的方式
5.1 配置
kconfig 文件相关
完整内容:
menu "Hardware Drivers Config"
config SOC_STM32F407ZG
bool
select SOC_SERIES_STM32F4
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
config BOARD_STM32F407_ATK_EXPLORER
bool
default y
menu "Onboard Peripheral Drivers"
config BSP_USING_USB_TO_USART
bool "Enable USB TO USART (uart1)"
select BSP_USING_UART
select BSP_USING_UART1
default y
config BSP_USING_COM2
bool "Enable COM2 (uart2 pin conflict with Ethernet and PWM)"
depends on (!BSP_USING_ETH && !BSP_USING_PWM)
select BSP_USING_UART
select BSP_USING_UART2
default n
config BSP_USING_COM3
bool "Enable COM3 (uart3)"
select BSP_USING_UART
select BSP_USING_UART3
default n
config BSP_USING_SRAM
bool "Enable SRAM"
select BSP_USING_EXT_FMC_IO
select BSP_USING_FMC
default n
config BSP_USING_ONBOARD_LCD
bool "Enable ATK LCD"
select BSP_USING_SRAM
default n
if BSP_USING_ONBOARD_LCD
config BSP_USING_ONBOARD_LCD_TEST
bool "Enable lcd fill test"
default y
endif
menuconfig BSP_USING_TOUCH
bool "Use LCD TOUCH (Default Res)"
default n
if BSP_USING_TOUCH
config BSP_USING_TOUCH_CAP
bool "Use LCD TOUCH Capacitance (i2c2)"
select BSP_USING_I2C2
default n
if BSP_USING_TOUCH_CAP
config BSP_TOUCH_INT_PIN
int "Touch interrupt pin, PB1"
default 17
endif
config BSP_USING_TOUCH_RES
bool "Use LCD TOUCH Resistance (sspi1)"
select RT_USING_TOUCH
select RT_TOUCH_PIN_IRQ
select BSP_USING_SOFT_SPI
select BSP_USING_SOFT_SPI1
select BSP_USING_ONBOARD_LCD
default y
if BSP_USING_TOUCH_RES
config BSP_XPT2046_CS_PIN
string "pin name for the chip select pin"
default "PC.13"
config BSP_XPT2046_IRQ_PIN
string "pin name for the irq pin"
default "PB.1"
endif
endif
config BSP_USING_LVGL
bool "Enable LVGL for LCD"
select BSP_USING_ONBOARD_LCD
select BSP_USING_TOUCH
select PKG_USING_LVGL
default n
if BSP_USING_LVGL
config BSP_USING_LVGL_DEMO
bool "Enable LVGL demo"
default y
endif
config BSP_USING_SPI_FLASH
bool "Enable SPI FLASH (W25Q128 spi1)"
select BSP_USING_SPI
select BSP_USING_SPI1
select RT_USING_SFUD
select RT_SFUD_USING_SFDP
default n
config BSP_USING_SOFT_SPI_FLASH
bool "Enable soft SPI FLASH (W25Q128 sspi2)"
select BSP_USING_SOFT_SPI
select BSP_USING_SOFT_SPI2
select RT_USING_SFUD
select RT_SFUD_USING_SFDP
default n
config BSP_USING_EEPROM
bool "Enable I2C EEPROM (i2c1)"
select BSP_USING_I2C1
default n
config BSP_USING_ETH
bool "Enable Ethernet"
default n
select RT_USING_LWIP
select RT_LWIP_USING_HW_CHECKSUM
select RT_USING_POSIX_FS
select RT_USING_POSIX_SOCKET
config PHY_USING_LAN8720A
bool
depends on BSP_USING_ETH
default y
config BSP_USING_MPU6050
bool "Enable MPU6050 (i2c1)"
default n
select BSP_USING_I2C1
select PKG_USING_MPU6XXX
menuconfig BSP_USING_FS
bool "Enable File System"
select RT_USING_DFS
select RT_USING_DFS_ROMFS
default n
if BSP_USING_FS
config BSP_USING_SDCARD_FATFS
bool "Enable SDCARD (FATFS)"
select BSP_USING_SDIO
select RT_USING_DFS_ELMFAT
default n
config BSP_USING_SPI_FLASH_LITTLEFS
bool "Enable SPI-FLASH (LittleFS)"
select RT_USING_MTD_NOR
select BSP_USING_SPI_FLASH
select RT_USING_FAL
select FAL_USING_AUTO_INIT
select FAL_PART_HAS_TABLE_CFG
select PKG_USING_LITTLEFS
default n
endif
endmenu
menu "On-chip Peripheral Drivers"
config BSP_USING_GPIO
bool "Enable GPIO"
select RT_USING_PIN
default y
menuconfig BSP_USING_UART
bool "Enable UART"
default y
select RT_USING_SERIAL
if BSP_USING_UART
config BSP_USING_UART1
bool "Enable UART1"
default y
config BSP_UART1_RX_USING_DMA
bool "Enable UART1 RX DMA"
depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
default n
config BSP_UART1_TX_USING_DMA
bool "Enable UART1 TX DMA"
depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
default n
config BSP_USING_UART2
bool "Enable UART2"
default n
config BSP_UART2_RX_USING_DMA
bool "Enable UART2 RX DMA"
depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA
default n
config BSP_UART2_TX_USING_DMA
bool "Enable UART2 TX DMA"
depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA
default n
config BSP_USING_UART3
bool "Enable UART3"
default n
config BSP_UART3_RX_USING_DMA
bool "Enable UART3 RX DMA"
depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA
default n
config BSP_UART3_TX_USING_DMA
bool "Enable UART3 TX DMA"
depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA
default n
config BSP_USING_UART4
bool "Enable UART4"
default n
config BSP_UART4_RX_USING_DMA
bool "Enable UART4 RX DMA"
depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA
default n
config BSP_UART4_TX_USING_DMA
bool "Enable UART4 TX DMA"
depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA
default n
config BSP_USING_UART5
bool "Enable UART5"
default n
config BSP_UART5_RX_USING_DMA
bool "Enable UART5 RX DMA"
depends on BSP_USING_UART5 && RT_SERIAL_USING_DMA
default n
config BSP_UART5_TX_USING_DMA
bool "Enable UART5 TX DMA"
depends on BSP_USING_UART5 && RT_SERIAL_USING_DMA
default n
config BSP_USING_UART6
bool "Enable UART6"
default n
config BSP_UART6_RX_USING_DMA
bool "Enable UART6 RX DMA"
depends on BSP_USING_UART6 && RT_SERIAL_USING_DMA
default n
config BSP_UART6_TX_USING_DMA
bool "Enable UART6 TX DMA"
depends on BSP_USING_UART6 && RT_SERIAL_USING_DMA
default n
endif
menuconfig BSP_USING_TIM
bool "Enable timer"
default n
select RT_USING_HWTIMER
if BSP_USING_TIM
config BSP_USING_TIM11
bool "Enable TIM11"
default n
config BSP_USING_TIM13
bool "Enable TIM13"
default n
config BSP_USING_TIM14
bool "Enable TIM14"
default n
endif
menuconfig BSP_USING_PWM
bool "Enable PWM"
default n
select RT_USING_PWM
if BSP_USING_PWM
menuconfig BSP_USING_PWM2
bool "Enable timer2 output PWM"
default n
if BSP_USING_PWM2
config BSP_USING_PWM2_CH4
bool "Enable PWM2 channel4"
default n
endif
endif
config BSP_USING_ON_CHIP_FLASH
bool "Enable on-chip FLASH"
default n
menuconfig BSP_USING_SOFT_SPI
bool "Enable soft SPI BUS"
default n
select RT_USING_SPI
select RT_USING_SPI_BITOPS
select RT_USING_PIN
if BSP_USING_SOFT_SPI
menuconfig BSP_USING_SOFT_SPI1
bool "Enable soft SPI1 BUS (software simulation)"
default n
if BSP_USING_SOFT_SPI1
config BSP_S_SPI1_SCK_PIN
int "soft spi1 sck pin number"
range 1 176
default 16
config BSP_S_SPI1_MISO_PIN
int "soft spi1 miso pin number"
range 1 176
default 18
config BSP_S_SPI1_MOSI_PIN
int "soft spi1 mosi pin number"
range 1 176
default 91
endif
menuconfig BSP_USING_SOFT_SPI2
bool "Enable soft SPI2 BUS (software simulation)"
default n
if BSP_USING_SOFT_SPI2
config BSP_S_SPI2_SCK_PIN
int "soft spi2 sck pin number"
range 1 176
default 19
config BSP_S_SPI2_MISO_PIN
int "soft spi2 miso pin number"
range 1 176
default 20
config BSP_S_SPI2_MOSI_PIN
int "soft spi2 mosi pin number"
range 1 176
default 21
endif
endif
menuconfig BSP_USING_SPI
bool "Enable SPI BUS"
default n
select RT_USING_SPI
if BSP_USING_SPI
config BSP_USING_SPI1
bool "Enable SPI1 BUS"
default n
config BSP_SPI1_TX_USING_DMA
bool "Enable SPI1 TX DMA"
depends on BSP_USING_SPI1
default n
config BSP_SPI1_RX_USING_DMA
bool "Enable SPI1 RX DMA"
depends on BSP_USING_SPI1
select BSP_SPI1_TX_USING_DMA
default n
config BSP_USING_SPI2
bool "Enable SPI2 BUS"
default n
config BSP_SPI2_TX_USING_DMA
bool "Enable SPI2 TX DMA"
depends on BSP_USING_SPI2
default n
config BSP_SPI2_RX_USING_DMA
bool "Enable SPI2 RX DMA"
depends on BSP_USING_SPI2
select BSP_SPI2_TX_USING_DMA
default n
endif
menuconfig BSP_USING_ADC
bool "Enable ADC"
default n
select RT_USING_ADC
if BSP_USING_ADC
config BSP_USING_ADC1
bool "Enable ADC1"
default n
endif
menuconfig BSP_USING_I2C1
bool "Enable I2C1 BUS (software simulation)"
default n
select RT_USING_I2C
select RT_USING_I2C_BITOPS
select RT_USING_PIN
if BSP_USING_I2C1
config BSP_I2C1_SCL_PIN
int "i2c1 scl pin number"
range 0 143
default 24
config BSP_I2C1_SDA_PIN
int "I2C1 sda pin number"
range 0 143
default 25
endif
menuconfig BSP_USING_I2C2
bool "Enable LCD Touch BUS (software simulation)"
default n
select RT_USING_I2C
select RT_USING_I2C_BITOPS
select RT_USING_PIN
if BSP_USING_I2C2
config BSP_I2C2_SCL_PIN
int "i2c2 scl pin number, PB0"
range 0 143
default 16
config BSP_I2C2_SDA_PIN
int "I2C2 sda pin number, PF11"
range 0 143
default 91
endif
menuconfig BSP_USING_DAC
bool "Enable DAC"
default n
select RT_USING_DAC
if BSP_USING_DAC
config BSP_USING_DAC1
bool "Enable DAC1"
default n
endif
menuconfig BSP_USING_ONCHIP_RTC
bool "Enable RTC"
select RT_USING_RTC
default n
if BSP_USING_ONCHIP_RTC
choice
prompt "Select clock source"
default BSP_RTC_USING_LSE
config BSP_RTC_USING_LSE
bool "RTC USING LSE"
config BSP_RTC_USING_LSI
bool "RTC USING LSI"
endchoice
endif
config BSP_USING_WDT
bool "Enable Watchdog Timer"
select RT_USING_WDT
default n
config BSP_USING_SDIO
bool "Enable SDIO"
select RT_USING_SDIO
select RT_USING_DFS
default n
config SDIO_MAX_FREQ
int "sdio max freq"
range 0 24000000
depends on BSP_USING_SDIO
default 1000000
config BSP_USING_USBD
bool "Enable USB Device"
select RT_USING_USB_DEVICE
default n
menuconfig BSP_USING_USBH
bool "Enable USB Host"
select RT_USING_USB_HOST
default n
if BSP_USING_USBH
menuconfig RT_USBH_MSTORAGE
bool "Enable Udisk Drivers"
default n
if RT_USBH_MSTORAGE
config UDISK_MOUNTPOINT
string "Udisk mount dir"
default "/"
endif
endif
menuconfig BSP_USING_PULSE_ENCODER
bool "Enable Pulse Encoder"
default n
select RT_USING_PULSE_ENCODER
if BSP_USING_PULSE_ENCODER
config BSP_USING_PULSE_ENCODER4
bool "Enable Pulse Encoder4"
default n
endif
config BSP_USING_EXT_FMC_IO
bool
default n
config BSP_USING_FMC
bool
default n
source "libraries/HAL_Drivers/Kconfig"
endmenu
menu "Board extended module Drivers"
menuconfig BSP_USING_AT_ESP8266
bool "Enable ESP8266(AT Command, COM3)"
default n
select BSP_USING_COM3
select PKG_USING_AT_DEVICE
select AT_DEVICE_USING_ESP8266
select AT_DEVICE_ESP8266_SAMPLE
select AT_DEVICE_ESP8266_SAMPLE_BSP_TAKEOVER
if BSP_USING_AT_ESP8266
config ESP8266_SAMPLE_WIFI_SSID
string "WIFI ssid"
default "rtthread"
config ESP8266_SAMPLE_WIFI_PASSWORD
string "WIFI password"
default "12345678"
config ESP8266_SAMPLE_CLIENT_NAME
string "AT client device name (Must be 'uart3')"
default "uart3"
config ESP8266_SAMPLE_RECV_BUFF_LEN
int "The maximum length of receive line buffer"
default 512
comment "May adjust RT_SERIAL_RB_BUFSZ up to 512 if using the Serial V1 device driver"
endif
endmenu
endmenu
5.2 代码修改
需要修改
报错内容:
[E/app.filesystem] SD card mount to '/sdcard' failed!
测试代码:
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <dfs_fs.h>
#include <unistd.h>
/* defined the LED0 pin: PF6 */
#define LED0_PIN GET_PIN(F, 6)
static char buffer[2048]={0};
int bsp_sdcard_test(void)
{
int fd, size;
char s[] = "hello elmfatfs!";
//----------------------------------------------------
rt_thread_mdelay(100); //等待sd_mount线程挂载文件系统,可使用IPC信号量完成同步,提高实时性
rt_kprintf("Write string %s to test.txt.\n", s);
/* 以创建和追加 读写模式打开 /text.txt 文件,如果该文件不存在则创建该文件 */
fd = open("/sdcard/text.txt", O_WRONLY | O_CREAT | O_APPEND);
if (fd>= 0)
{
write(fd, s, sizeof(s));
close(fd);
rt_kprintf("Write done.\n");
}
/* 以只读模式打开 /text.txt 文件 */
fd = open("/sdcard/text.txt", O_RDONLY);
if (fd>= 0)
{
size = read(fd, buffer, sizeof(buffer));
close(fd);
if (size < 0)
return -RT_ERROR;
//rt_kprintf("Read from file test.txt : %*s \n",size, buffer);
rt_kprintf("Read from file test.txt : \n");
for(int i=0;i<size;i++)
{
rt_kprintf("%c",buffer[i]);
}
rt_kprintf("\n");
}
return 0;
}
int main(void)
{
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
bsp_sdcard_test();
while (1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
有个 rtc 警告,因为 rtc 功能未开启,可以按照上面的开启 rtc 配置功能。
参考:
使用STM32 SDIO接口实现TF卡读写
rt-thread SDIO驱动框架分析之SD卡驱动
关于FatFS在SPI FLASH上无擦写均衡导致问题的疑问
SD卡能挂载littleFS文件系统
RT Thred 文件系统教程-3 W25Q128(SPI flash)和SD卡(SDIO接口)同时使用文件系统
基于stm32单片机使用 RT-Thread 系统的 硬件 RTC