(十三)零基础开发小安派-Eyes-S1【外设篇】——FLASH

[复制链接]
查看4167 | 回复22 | 2023-11-6 20:39:25 | 显示全部楼层 |阅读模式

本帖最后由 Ai-Thinker小泽 于 2023-11-6 20:39 编辑

本帖最后由 Ai-Thinker小泽 于 2023-11-6 18:22 编辑

零基础开发小安派-Eyes-S1【外设篇】——FLASH

Flash简称闪存,它的特点是擦除和编程速度快,单片机的程序一般都是存储在一定空间内中进行运行。在C语言中,程序分为代码段,常量区,静态数据区(BSS段,数据段),栈,堆五个部分组成。内部空间就分为ROM和RAM,他们都是可以用来存储内容,区别在于,ROM的存储特性比较稳定,很久以前它不可擦除,所以只可读不可写,FLASH就是一种特殊的ROM,可擦除可读可写,它们在掉电后不丢失。RAM的存储特性较不稳定,但它的读写速度快,掉电后丢失。

他们的差异如下:

数据存储区域 类型 所在存储空间
代码段 宏定义、枚举、字面常量(整数、浮点类型) ROM(也可在RAM)
常量区 只读变量、const修饰的全局变量、常量字符串(char *p=“hi”) ROM
静态数据区BSS段 全局变量和static修饰后的静态变量(未初始化,如int a) RAM
静态数据区数据段 全局变量和static修饰后的静态变量(已初始化,如int a=0) ROM,运行时拷贝到RAM中
局部变量,如函数内临时定义的int b,在函数运行完自动释放 RAM
malloc申请的空间,需要用户手动申请/释放 RAM

总结:FLASH也就是ROM,掉电后不丢失,读写速度较慢,空间大,可以理解未电脑上的硬盘。RAM速度快,掉电后丢失,可以理解未电脑上的内存。

一、了解小安派-Eyes-S1的存储

618FLASH物理上的地址起始地址是0XA0000000。M61-32S的FLASH大小是8M。在数据手册中可以看到所有的模块地址映射,包括外设的地址。

在这之前需要了解分区表的概念,分区表就是划分FLASH的清单,将FLASH划分为多个不同功能区域用于其它功能。在操作FLASH时得看一下分区表,查看哪些地址可以使用。在SDK中有4M的分区表,里面规划了一些分区的命名,起始地址和大小,这个目录下找到。AiPi-Open-Kits/aithinker_Ai-M6X_SDK/bsp/board/bl616dk/config/partition_cfg_4M.toml,在参与编译时会在工程文件夹下的build/build_out中生成partition.bin。我们在flash_prog_cfg.ini中可以看到,常见的有BOOT2固件,filedir:固件路径,address:地址,boot2必须使用0地址。而partition表示分区表固件,address是根据partition_cfg_4M.toml指定。而FW则表示需要烧录的应用固件,FW可以在partition_cfg_4M.toml中看到。 微信截图_20231106163957.png

我们可以添加一样的“分区”,创建属于自己的名字,也可以在分区表中查看已有的分区使用。当然,建议还是使用原厂分配的分区表。

1.bflb_flash_init

说明: flash 初始化,自动识别支持的 flash 并重新配置 flash 的参数。如果返回错误,必须停止运行代码。

int bflb_flash_init(void);
parameter description
return 返回 0 表示成功,其他表示错误,必须停止运行代码

2.bflb_flash_get_jedec_id

说明: 获取 flash jedec id。

uint32_t bflb_flash_get_jedec_id(void);
parameter description
return 返回 flash jedec id

3.bflb_flash_get_cfg

说明: 获取 flash 配置。

void bflb_flash_get_cfg(uint8_t **cfg_addr, uint32_t *len);
parameter description
cfg_addr 保存 flash 配置的地址
len flash 配置的长度

4.bflb_flash_set_iomode

说明: 设置 flash IO 工作模式。

void bflb_flash_set_iomode(uint8_t iomode);
parameter description
iomode flash IO 工作模式

可填入以下几种模式:

#define FLASH_IOMODE_NIO 0
#define FLASH_IOMODE_DO  1
#define FLASH_IOMODE_QO  2
#define FLASH_IOMODE_DIO 3
#define FLASH_IOMODE_QIO 4

5.bflb_flash_get_image_offset

说明: 获取代码 xip 虚拟地址实际所在的 flash 物理地址。

uint32_t bflb_flash_get_image_offset(void);
parameter description
return 返回 flash xip 物理地址

6.bflb_flash_erase

说明: flash 扇区擦除。 len 为擦除的长度,需要为 4096 倍数,假设 addr 为0 , len 为 4096,则擦除范围为 0 ~ 4095。

int bflb_flash_erase(uint32_t addr, uint32_t len);
parameter description
addr 擦除的物理地址
len 擦除长度,需要是 4096 的倍数
return 返回 0 表示成功,其他表示错误

7.bflb_flash_write

说明:获取代码 xip 虚拟地址实际所在的 flash 物理地址。

int bflb_flash_write(uint32_t addr, uint8_t *data, uint32_t len);
parameter description
addr 写入的物理地址
data 写入的数据缓冲区
len 写入长度
return 返回 0 表示成功,其他表示错误

8.bflb_flash_read

说明: 获取代码 xip 虚拟地址实际所在的 flash 物理地址。

int bflb_flash_read(uint32_t addr, uint8_t *data, uint32_t len);
parameter description
addr 读取的物理地址
data 读取的数据缓冲区
len 读取长度
return 返回 0 表示成功,其他表示错误

9.bflb_flash_aes_init

说明: 配置某一段 flash 区域进行硬件 aes 解密,能够通过 xip 直接读取解密后的内容。

void bflb_flash_aes_init(struct bflb_flash_aes_config_s *config);
parameter description
config flash aes配置

10.bflb_flash_aes_enable

说明: 使能 flash aes 解密。

void bflb_flash_aes_enable(void);

11.bflb_flash_aes_disable

说明: 关闭 flash aes 解密。

void bflb_flash_aes_disable(void);

二、简单示例——上电后读取flash内的值并打印

1.首次写入

#include "bflb_flash.h"
#include "board.h"
#include "string.h"
//头文件

#define FLASH_RW_START_ADDR  0x3F3000
//宏定义读写起始地址,查看分区表可以看出这是“DATA”所在分区

static uint8_t write_buf[16];
static uint8_t read_buf[16];
//定义读写缓存数组

int main(void)
{
    uint32_t i;

    board_init();
    //板子初始化,包括了bflb_flash_init

    memset(write_buf, 0, sizeof(write_buf));
    memset(read_buf, 0, sizeof(read_buf));
    //清空缓存数组

    strcpy(write_buf,"HelloWorld!");
  //填写write数组内容

    /* erase flash */
    bflb_flash_erase(FLASH_RW_START_ADDR,sizeof(write_buf));
  //擦除缓存数组大小,从起始地址开始

    /* read flash data */
    bflb_flash_read(FLASH_RW_START_ADDR, read_buf, sizeof(read_buf));
  //读取flash内的内容缓存到read数组里

    for (i = 0; i < sizeof(read_buf); i++) {
            if (read_buf[i] != write_buf[i]) {
                printf("\r\nflash read fail at %d, expect:%d but get %d", i, write_buf[i], read_buf[i]);
            }
    } 
    //for循环校验,当write和read内容不一致时会打印

    /* write flash data */
    bflb_flash_write(FLASH_RW_START_ADDR, write_buf, sizeof(write_buf));
  //将write内容写入flash中

    memset(read_buf, 0, sizeof(read_buf));

    /* read flash data */
    bflb_flash_read(FLASH_RW_START_ADDR, read_buf, sizeof(read_buf));

    printf("\r\n%s",read_buf);

    while (1) {
    }
}

第一次运行程序效果:在擦除了后读出来的ASCII码为255 FirstWrite.png

2.二次读取,查看上电打印信息

#include "bflb_flash.h"
#include "board.h"
#include "string.h"


#define FLASH_RW_START_ADDR  0x3F3000

static uint8_t write_buf[16];
static uint8_t read_buf[16];

int main(void)
{
    uint32_t i;

    board_init();

    memset(write_buf, 0, sizeof(write_buf));
    memset(read_buf, 0, sizeof(read_buf));

    strcpy(write_buf,"HelloWorld!");

    /* read flash data */
    bflb_flash_read(FLASH_RW_START_ADDR, read_buf, sizeof(read_buf));

    for (i = 0; i < sizeof(read_buf); i++) {
            if (read_buf[i] != write_buf[i]) {
                printf("\r\nflash read fail at %d, expect:%d but get %d", i, write_buf[i], read_buf[i]);
            }
    }

    printf("\r\n%s",read_buf);

    while (1) {
    }
}

二次读取后的运行效果:校验成功,只读取出hellowold SecondRead.png

三、使用easyflash库,匹配字段

在AiPi-SCP_SmartCtrl工程中的components下,有easy_flash库,使用easy_flash更加方便快捷,只需要定义字段,第一个参数填入字段,第二个参数填入值,即可通过匹配字段的方式将值与字段匹配上。 添加库的方式如下:

1.将easy_flash的文件夹复制下来,放到模板工程中,这里使用Project_basic的模板工程,记得修改工程名。 微信截图_20231106201403.png

2.在CMakeLists.txt下的添加easyflash的库文件。 image.png

3.在proj.conf下打开easyflash控件。 微信截图_20231106201712.png

4.使用方法,只需要在调用flash_erase_set时填入两个参数,第一个参数为匹配的字段,一般由宏定义的字符串常量。第二个参数为值,也就是需要存储的值。这样在flash中就是由常驻的字段+值组成,在获取值时可以通过“字段‘来寻找相应的值。通过flash_get_data的方式,传入查找的字段和长度,得到存储的值。 image.png image.png image.png

5.easyflash使用的“PSM”分区,大小是32K,起始地址是0X3E9000。在这里面我们可以存放一些标志位,或者是类似wifi名称密码、AP名称密码等关键信息,使用起来也方便,通过匹配字段的方式将关键信息填入所需任务。如在AT指令中将SSID和PASS通过第三个参数0或1选择是否存入flash中。方便实现开机自动连接wifi且可通过指令修改wifi等操作。 image.png

[/i][/i][/i][/i][/i][/i][/i][/i]

本帖被以下淘专辑推荐:

回复

使用道具 举报

WangChong | 2023-11-6 21:38:25 | 显示全部楼层
晚会验证下
回复 支持 反对

使用道具 举报

jkernet | 2023-11-6 21:42:46 | 显示全部楼层
学习
回复

使用道具 举报

18350766600@139 | 2023-11-6 21:49:00 | 显示全部楼层
学习一下,本周没有板子,下周再来试验
回复 支持 反对

使用道具 举报

bzhou830 | 2023-11-7 08:28:03 | 显示全部楼层
打卡学习
选择去发光,而不是被照亮
回复

使用道具 举报

爱笑 | 2023-11-7 08:36:36 | 显示全部楼层
打卡学习!
用心做好保姆工作
回复

使用道具 举报

每天八杯水 | 2023-11-7 16:34:50 | 显示全部楼层
打卡学习!
回复

使用道具 举报

干簧管 | 2023-11-11 11:10:19 | 显示全部楼层
打卡学习!
回复

使用道具 举报

干簧管 | 2023-11-24 20:20:10 | 显示全部楼层
回复

使用道具 举报

干簧管 | 2023-11-25 07:53:05 | 显示全部楼层
学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则