文章目录
- 1.新建工程
- 2.配置CubeMX Settings,启用SPI3
- 3.打开SFUD功能并添加FAL和EasyFlash软件包
- 4.修改FAL接口文件并初始化SFUD和FAL
- 5.调整FAL分区结构
- 6.修改EasyFlash接口文件并初始化EasyFlash
- 7.编译下载程序并调试功能
1.新建工程
打开RT-Thread Studio,文件-新建-RT-Thread项目,选择好芯片型号,我这里用的是STM32F405RG,设置控制台串口并命名工程后点击完成,自动生成工程。
2.配置CubeMX Settings,启用SPI3
双击工程中的CubeMX Settings,配置PA13 PA14位SWD下载引脚,并打开SWD功能,否则会导致以后下载不了程序
SPI Flash接的SPI3接口,所以把PB3 PB4 PB5配置为SPI模式。
配置SPI3的工作模式为全双工主机模式,关闭硬件NSS功能,点击MXCube软件右上角GENERATE CODE,软件关闭后会自动更新工程。
在工程的drivers-board.h中启用SPI3,即将BSP_USING_SPI3取消注释。
3.打开SFUD功能并添加FAL和EasyFlash软件包
双击RT-Thread Settings,打开SFUD功能并添加FAL和EasyFlash软件包,右击FAL,点击详细配置,勾选“FAL使用SFUD驱动程序”,设备名称为默认norflash0。点击保存,软件会自动下载软件包并更新到工程。
4.修改FAL接口文件并初始化SFUD和FAL
SFUD功能可以自动识别SPI FLASH的型号和容量,并通过初始化时注册的SPI设备读写FLASH。而FAL软件包可以将FLASH虚拟分区,相当于模拟出来多个虚拟FLASH,方便读写和管理。
将packages/fal-v0.5.0/samples/porting文件夹中的fal_flash_sfud_ports.c和fal_cfg.h文件剪切并粘贴到application文件夹中。
打开fal_flash_sfud_ports.c,添加#include "drv_spi.h"头文件,在文件末尾添加如下代码
int rt_hw_spi_flash_init(void)
{
#define FLASH_CS GET_PIN(B, 8)
rt_pin_mode(FLASH_CS, PIN_MODE_OUTPUT);
rt_err_t res;
res = rt_hw_spi_device_attach("spi3", "spi30", GPIOB, GPIO_PIN_8);
if (res != RT_EOK)
{
rt_kprintf("[flash] Failed to attach device %s\n", "spi30");
return res;
}
if (RT_NULL == rt_sfud_flash_probe(FAL_USING_NOR_FLASH_DEV_NAME, "spi30"))
{
return -RT_ERROR;
};
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_spi_flash_init);//初始化sfud,定义spi30设备并将设备命名为FAL_USING_NOR_FLASH_DEV_NAME(即norflash0)。
INIT_COMPONENT_EXPORT(fal_init);//初始化fal
此处注意要先初始化sfud再初始化fal。
此处用了自动初始化功能,底层是用预编译指令实现的,详细讲解见文章,这里引用文章中的启动顺序表。可见,初始化时INIT_DEVICE_EXPORT()先执行然后再执行INIT_COMPONENT_EXPORT()。
5.调整FAL分区结构
我用的FLASH型号是W25Q64,有8M字节空间。打开fal_cfg.h,修改如下代码
#ifndef _FAL_CFG_H_
#define _FAL_CFG_H_
#include <rtconfig.h>
#include <board.h>
#define NOR_FLASH_DEV_NAME "norflash0"
/* ===================== Flash device Configuration ========================= */
//extern const struct fal_flash_dev stm32f2_onchip_flash;
extern struct fal_flash_dev nor_flash0;
/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&nor_flash0, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WORD, "easyflash", NOR_FLASH_DEV_NAME, 0, 4*1024*1024, 0}, \
{FAL_PART_MAGIC_WORD, "download", NOR_FLASH_DEV_NAME, 4*1024*1024, 4*1024*1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
其中给easyflash分区分配分区起始地址0,大小4M字节;给download分区分配起始地址为4M字节处,大小为4M字节。
6.修改EasyFlash接口文件并初始化EasyFlash
右键点击packages\EasyFlash-v4.1.0,选择“打开资源所在目录”。移植参考文件位于 ports/ef_fal_port.c。先将该文件拷贝至项目中的applications文件夹,并修改如下代码。这里的"easyflash"要和前面FAL定义的分区名称一致。
#define FAL_EF_PART_NAME "easyflash"
打开packages\EasyFlash-v4.1.0\inc\ef_cfg.h文件,并修改如下代码。
#define ENV_AREA_SIZE (EF_ERASE_MIN_SIZE * 1000) /* default is the double erase min size */
EasyFlash默认存储环境变量的大小只有两倍的最小擦除单元,4096 * 2,即8k字节,我们修改为4096 * 1024,即4M字节,充分利用分配给EasyFlash的分区大小。
在mian.c中引入"easyflash.h"头文件,并初始化easyflash。
#include <rtthread.h>
#include "rtdevice.h"
#include "board.h"
#include "easyflash.h"
int main(void)
{
easyflash_init();//初始化easyflash
while (1)
{
// LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}
return RT_EOK;
}
7.编译下载程序并调试功能
编译程序,下载程序到芯片中,打开串口控制台,第一次运行EasyFlash会初始化所有扇区,可能比较慢,耐心等待一段时间后显示初始化成功串口,结果如下。
\ | /
- RT - Thread Operating System
/ | \ 4.0.3 build Nov 19 2021
2006 - 2020 Copyright by rt-thread team
[I/SFUD] Find a Winbond flash chip. Size is 8388608 bytes.
[I/SFUD] norflash0 flash device is initialize success.
[I/SFUD] Probe SPI flash norflash0 by SPI device spi30 success.
[D/FAL] (fal_flash_init:63) Flash device | norflash0 | addr: 0x00000000 | len: 0x00800000 | blk_size: 0x00001000 |initialized finish.
[I/FAL] ==================== FAL partition table ====================
[I/FAL] | name | flash_dev | offset | length |
[I/FAL] -------------------------------------------------------------
[I/FAL] | easyflash | norflash0 | 0x00000000 | 0x00400000 |
[I/FAL] | download | norflash0 | 0x00400000 | 0x00400000 |
[I/FAL] =============================================================
[I/FAL] RT-Thread Flash Abstraction Layer (V0.5.0) initialize success.
[Flash] (../packages/EasyFlash-v4.1.0/src/ef_env.c:1818) ENV start address is 0x00000000, size is 4194304 bytes.
[Flash] EasyFlash V4.1.0 is initialize success.
[Flash] You can get the latest version on https://github.com/armink/EasyFlash .
然后按下TAB键可查看支持的命令。
msh >
RT-Thread shell commands:
clear - clear the terminal screen
version - show RT-Thread version information
list_thread - list thread
list_sem - list semaphore in system
list_event - list event in system
list_mutex - list mutex in system
list_mailbox - list mail box in system
list_msgqueue - list message queue in system
list_mempool - list memory pool in system
list_timer - list timer in system
list_device - list device in system
help - RT-Thread shell help.
ps - List threads in the system.
free - Show the memory usage in the system.
sf - SPI Flash operate.
fal - FAL (Flash Abstraction Layer) operate.
setenv - Set an envrionment variable.
printenv - Print all envrionment variables.
saveenv - Save all envrionment variables to flash.
getvalue - Get an envrionment variable by name.
resetenv - Reset all envrionment variable to default.
reboot - Reboot System
输入setenv temp 123 回车
保存变量名称为temp的变量,数值为123
输入reboot命令重启系统。
输入getvalue temp 回车,显示如下
The temp value is 123.
表示刚才存储成功。