本次进行spi flash(w25q128)的文件系统实验(fatfs)。
fatfs是我们常用的文件系统,之后可以用这个操作系统进行设备初始化参数,ini文件的读取实验,.csv报警数据的一个存储,通过tftp远程进行文件导出,或者通过sd卡进行一个文件导出,所以这个实验作为一个基础实验,方便后期项目中进行直接复用。
一.实验环境
开发板 | 微雪电子 Core746I,Open746I-C,及w25q128扩展板 |
IDE | RT-thread studio |
烧写工具 | JTAG |
注:W25Q128 是华邦公司推出的一款 SPI 接口的 NOR Flash 芯片,其存储空间为 128Mbit,相当于 16M 字节。
W25Q128 (128Mbit,16MByte),被组织为65536个可编程的页,每页256bytes。擦除方式分为16页一组(即一个扇区4kbytes),128页一组(即8个扇区32kbytes),256页一组(即16个扇区或1个块64kbytes),或整个芯片擦除。
二.实验步骤
1.创建基础工程,带finsh打印
RT-thread 选择完整版,使用串口1进行信息打印。
弄完这一步先别急,先编译一下工程,然后通过烧写器进行debug一下,通过终端看一下打印信息是否输出,确保硬件环境及调试环境,工程配置正常。
编译通过。
打印调试正常。
不得不承认stdio的方便快捷,但是同样flash占用比较高。接下来开始下一步工作。
2.通过RT-Thread setting图形界面进行组件添加
点击RT-Thread setting在图形界面配置需要的组件和驱动
进入详细配置:
最后一定别忘记点击保存。
3.修改spi驱动
你是知道了是什么芯片了,板卡还不知道呢。
这一步肯定是要修改spi以适应我们的w25q128。我们的芯片通过spi1与芯片相连。
在board.h中打开宏
在stm32f7xx_hal_conf.h中打开下面的宏
4.添加HAL_SPI_MspInit初始化函数
只需要将cubmx生成的HAL_SPI_MspInit的函数拷贝到drv_spi.c的末尾就行。
那么我们只是打开了两个宏,怎么最后调用到了 HAL_SPI_MspInit呢??
INIT_BOARD_EXPORT(rt_hw_spi_init);//自动注册方式
--》
rt_hw_spi_init(void)
--》
rt_hw_spi_bus_init(void)
--》
rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &stm_spi_ops);
--》
stm_spi_ops.configure--》
--》
stm32_spi_init(spi_drv, configuration);
--》
HAL_SPI_Init--》 HAL_SPI_MspInit(hspi);
我们知道了整个的调用过程,其他的驱动也是这么个调用流程,我们只需要做的就是把cubmx生成的MspInit拷贝过来,放到相应的drv_xxx.c的最后面就可以了。
这里我们直接去RT-thread包中去拷贝就可以了。
https://gitee.com/rtthread/rt-thread?_from=gitee_search
下载源码包
找到f746的板卡,但是没有找到spi初始化,找个常用的芯片吧
rtthread-rt-thread-gitee_master\rt-thread\bsp\stm32\stm32f429-atk-apollo\board\CubeMX_Config\Src
打开stm32f4xx_hal_msp.c文件
将void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)函数复制到我们的drv_spi.c中
修改为我们自己的管脚
保存,编译一下,看看有没有报错,下载程序,看一下总线有没有挂接上。
5.添加W25Q128设备
文件--》新建源文件--》
创建好.c文件后,在文件中添加如下代码:
#include "drv_spi.h"
#include "spi_flash_sfud.h"
static int rt_hw_spi_flash_init(void)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
rt_hw_spi_device_attach("spi1", "spi10", GPIOA, GPIO_PIN_4);// spi10 表示挂载在 spi3 总线上的 0 号设备,PA4是片选,这一步就可以将从设备挂在到总线中。
if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi10")) //注册块设备,这一步可以将外部 flash抽象为系统的块设备
{
return -RT_ERROR;
};
return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
保存,进行编译下载,看看设备是否能够挂接成功。
通过查看打印信息,发现设备已经挂接成功了,块设备也已经注册上了。
6.挂接文件系统
在.c中添加代码
#include "dfs_fs.h"
int dfs_mount_init(void)
{
dfs_mkfs("elm","W25Q128");
if(dfs_mount("W25Q128", "/","elm",0,0) == 0) //注册块设备,这一步可以将外部flash抽象为系统的块设备
{
return -RT_ERROR;
}
return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(dfs_mount_init);
可以看到文件系统挂接成功了。
flash的占用还是比较多的,可能是stdio默认加载的库太多了,不过flash足够大,暂时不用考虑优化。