2.8 rt-thread spi flash挂载w25q128 littliefs补充
1.按照官方文档得知,需要参考这三个文件,进行新增修改处理。

2.我的是STM32L496,所以我新增了这三个文件,分别到fal/inc下和fal/src下,fal目录下的SConscipt脚本中,注释掉了这两句话,因为已经将src和inc下的文件添加到工程中了,后面的语句



3.修改fal_cfg.h,分区定义成我想要的,首先片上的定义了1MB,一个分区。片外的spi flash定义了两个分区,一个15MB,一个1MB。

4、修改fal_flash_sfud_port.c,此文件时对片外的flash进行定义,他使用了sfud框架,这种串行方式是兼容几乎所有的片外flash的无敌操作方式。所以里面的函数基本不用改,只需要改定义的大小,我的spi flash 是16MB,所以修改为16MB大小。

5、修改fal_flash_stm32l4_port.c文件,此文件是对片上的flash操作的方式方法定义
1)头文件包含自己的hal库文件。

2)因为我的bsp包中hal库文件,有对片上flash的读写接口,所以我将此文件中的读写接口调用我们hal接口即可









修改片上flash大小为我要用的1MB大小

6、之后编译报错,同时上述几个函数找不到,原因是我应该包含HAL_Drivers下的druvers里drv_flash中的drv_flash.h文件,不是hal的头文件。


修改后编译报错,提示此文件找不到

是因为libraries下的HAL_Drivers驱动中的drivers中的SConscript脚本中,因BSP_USING_ON_CHIP_FLAS宏没有打开,头文件路径没再环境中


所以要改下此目录下的Kconfg,让menuconfig配置时,将BSP_USING_ON_CHIP_FLASH可打开

修改后menuconfig,将宏打开后,保存退出menuconfig

重新scons --target=iar生成工程,编译报错,因为我将stm32f2_onchip变量改成了l4,但没全改完,改成l4后,和fal_flash_stm32l4_port.c中定义的一样后,编译通过



主函数调用这个代码

烧录运行报错,提示片外的flash没找到

定位到是在此文件报错,将不符合的值打出来看下什么

打印后此值为45,应该是块设备的值才对,说明这个变量赋值没赋值好。


不应该强制更改rt_spi_device->parent.type这个值,要找到原因,原因是sfud驱动的rt_sfud_flash_probe_ex函数去注册这个设备为块类型

增加drv_qspi_flash驱动文件,文件里增加加此代码,让menuconfig时,可配置,系统起来时自动运行此函数,让其注册W25Q128设备,使用SFUD探测qspi0从这个flash设备,注册该设备为块类型。rt_spi_bus_attach_device_cspin,SPI 驱动会注册 SPI 总线,SPI 设备需要挂载到已经注册好的 SPI 总线上,此函数用于挂载一个 SPI 设备到指定的 SPI 总线,并向内核注册 SPI 设备。并且可以依赖RT-Thread的PIN框架来绑定SPI的片选引脚(cs_pin),避免了不同bsp的上层应用对片选引脚操作不统一的问题。一般 SPI 总线命名原则为 spix, SPI 设备命名原则为 spixy ,如 spi10 表示挂载在 spi1 总线上的 0 号设备。cs_pin可以通过PIN框架rt_pin_get函数来获取,也可以使用BSP级提供的GET_PIN宏定义来获取。user_data 在用户使用不到的情况下可以设置为RT_NULL。

Kconfig

Sconscript脚本

之后编译运行报错

原因是虽然添加了drv_qspi.c文件,但是该文件的宏没打开,导致qspi总线没有注册上


利用kconfig,将BSP_USING_QSPI宏打开,


重新menuconfig配置后,生成工程,编译烧录运行,提示数据长度配置不对

是因为挂载 SPI 设备到 SPI 总线后没有配置 SPI 设备的传输参数。
rt_err_t rt_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)




可以参考spi_flash_sfud.c中的默认配置

增加如下代码


编译烧录后,测试正常


但是后来主函数崩了

定位崩溃原因是因为,qspi总线注册时,关于enter_qspi_mode这个函数指针指向了非法地址处,这个是切换qspi总线模式的,我先给他赋值为NULL

编译烧录后,fal初始化时提示片外的flash没找到,应该是块设备,但不知道为什么到了这值变成了230多,应该是1

查问题找到原因,因为我使用sfud框架的spi探测spi设备时,将flash注册的设备名字注册为W25Q128,但fal_init初始化去查找flash设备时,用的名字是norflash0,所以导致没有成功找到flash设备



将探测并注册flash设备的名称改为norflash0后正常,编译烧录测试正常,至此基于STM32L496,使用rt-thread5.1.0源码自动生成的工程,就将spi flash(w25q128)+liffies文件系统挂载好了。

/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-5-22 Rain Park first version * 2023-12-03 Meco Man support nano version */ #include <board.h> #include <rtthread.h> #include <drv_gpio.h> #ifndef RT_USING_NANO #include <rtdevice.h> #endif /* RT_USING_NANO */ #define DBG_TAG "main" #define DBG_LVL DBG_LOG #include <rtdbg.h> #include <fal.h> #include <dfs_fs.h> /* 当需要使用文件操作时,需要包含这个头文件 */ #include <unistd.h> #define FS_PARTITION_NAME "filesystem" #define LED0_PIN GET_PIN(E, 9) void filesystem_init(void) { struct rt_device *mtd_dev = RT_NULL; /* 初始化 fal */ fal_init(); /* 生成 mtd 设备 */ mtd_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME); if (!mtd_dev) { LOG_E("Can't create a mtd device on '%s' partition.", FS_PARTITION_NAME); } else { /* 挂载 littlefs */ if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == 0) { LOG_I("Filesystem initialized!"); } else { /* 格式化文件系统 */ dfs_mkfs("lfs", FS_PARTITION_NAME); /* 挂载 littlefs */ if (dfs_mount("filesystem", "/", "lfs", 0, 0) == 0) { LOG_I("Filesystem initialized!"); } else { LOG_E("Failed to initialize filesystem!"); } } } } void file_read_write_test(void) { int fd, size; char s[] = "RT-Thread Programmer!", buffer[80]; 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 ; } } int main(void) { int count = 1; /* set LED0 pin mode to output */ rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT); filesystem_init(); file_read_write_test(); while (count++) { rt_pin_write(LED0_PIN, PIN_HIGH); rt_thread_mdelay(500); rt_pin_write(LED0_PIN, PIN_LOW); rt_thread_mdelay(500); } return RT_EOK; }


浙公网安备 33010602011771号