登录发现更多内容
首页
分类
发帖
账号
自动登录
找回密码
密码
登录
立即注册
立即登录
立即注册
其他登录
QQ
微信
首页
Portal
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
产品教程
BBS
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
开发资料
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
样品购买
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
IoT云平台
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
GitHub
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
技术博客
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
搜索
搜索
热搜:
LoRa
ESP8266
安信可
本版
帖子
用户
请
登录
后使用快捷导航
没有账号?
立即注册
每日签到
任务
广播
导读
排行榜
设置
我的收藏
退出
24
3
1
首页
小安派&M61零基础开发教程(官方)
›
(十三)零基础开发小安派-Eyes-S1【外设篇】——FLASH ...
1
2
3
/ 3 页
下一页
返回列表
(十三)零基础开发小安派-Eyes-S1【外设篇】——FLASH
[ 复制链接 ]
发布帖子
Ai-Thinker小泽
论坛元老
38
主题
537
回帖
6810
积分
论坛元老
论坛元老, 积分 6810, 距离下一级还需 9993189 积分
论坛元老, 积分 6810, 距离下一级还需 9993189 积分
积分
6810
私信
24人留言
楼主
小安派&M61零基础开发教程(官方)
7831
24
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中看到。  我们可以添加一样的“分区”,创建属于自己的名字,也可以在分区表中查看已有的分区使用。当然,建议还是使用原厂分配的分区表。 ### 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  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  ## 三、使用easyflash库,匹配字段 在AiPi-SCP_SmartCtrl工程中的components下,有easy_flash库,使用easy_flash更加方便快捷,只需要定义字段,第一个参数填入字段,第二个参数填入值,即可通过匹配字段的方式将值与字段匹配上。 添加库的方式如下: 1.将easy_flash的文件夹复制下来,放到模板工程中,这里使用Project_basic的模板工程,记得修改工程名。  2.在CMakeLists.txt下的添加easyflash的库文件。  3.在proj.conf下打开easyflash控件。  4.使用方法,只需要在调用flash_erase_set时填入两个参数,第一个参数为匹配的字段,一般由宏定义的字符串常量。第二个参数为值,也就是需要存储的值。这样在flash中就是由常驻的字段+值组成,在获取值时可以通过“字段‘来寻找相应的值。通过flash_get_data的方式,传入查找的字段和长度,得到存储的值。    5.easyflash使用的“PSM”分区,大小是32K,起始地址是0X3E9000。在这里面我们可以存放一些标志位,或者是类似wifi名称密码、AP名称密码等关键信息,使用起来也方便,通过匹配字段的方式将关键信息填入所需任务。如在AT指令中将SSID和PASS通过第三个参数0或1选择是否存入flash中。方便实现开机自动连接wifi且可通过指令修改wifi等操作。  [/i][/i][/i][/i][/i][/i][/i][/i]
点赞
3
收藏
1
淘帖
2
────
3
人觉得很赞
────
本帖被以下淘专辑推荐:
·
小安派S1&M61教程合集
|
主题: 19, 订阅: 5
·
小安派&M61零基础教程
|
主题: 19, 订阅: 5
回复
使用道具
举报
24 回复
电梯直达
正序浏览
倒序浏览
正序浏览
沙发
WangChong
回复
使用道具
举报
2023-11-6 21:38:25
晚会验证下
回复
评论
使用道具
举报
板凳
jkernet
回复
使用道具
举报
2023-11-6 21:42:46
学习
回复
评论
使用道具
举报
地板
18350766600@139
回复
使用道具
举报
2023-11-6 21:49:00
学习一下,本周没有板子,下周再来试验
回复
评论
使用道具
举报
5
#
bzhou830
回复
使用道具
举报
2023-11-7 08:28:03
打卡学习
回复
评论
使用道具
举报
选择去发光,而不是被照亮
6
#
爱笑
回复
使用道具
举报
2023-11-7 08:36:36
打卡学习!
回复
评论
使用道具
举报
用心做好保姆工作
7
#
每天八杯水
回复
使用道具
举报
2023-11-7 16:34:50
打卡学习!
回复
评论
使用道具
举报
8
#
干簧管
回复
使用道具
举报
2023-11-11 11:10:19
打卡学习!
回复
评论
使用道具
举报
9
#
干簧管
回复
使用道具
举报
2023-11-24 20:20:10
顶
回复
评论
使用道具
举报
10
#
干簧管
回复
使用道具
举报
2023-11-25 07:53:05
学习
回复
评论
使用道具
举报
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
立即登录
手机登录
点评
高级模式
本版积分规则
回帖并转播
回帖后跳转到最后一页
下一页 »
1
2
3
/ 3 页
下一页
今日推荐
针对WB2-12S固件合成烧录的补充说明(已解决)
【BW20-12F开发板评测】6、Zephyr初步
【安信可BW20-12F-Kit测评】“高级” 点灯
【电子DIY作品】默语智家-AI智能机器狗(立创地文星开发板+安信
【BW20-12F开发板评测】5、NTP时钟
【安信可BW20-12F-Kit测评】环境搭建
【安信可BW20-12F-Kit测评】环境搭建
【BW20-12F 】开发板 WiFi LED 状态指示项目开发教程
求助,Ai-WB2-05W烧录模式一直发送0xff
【BW20-12F开发板评测】4、虚拟文件系统
热帖排行
针对WB2-12S固件合成烧录的补充说明(已解决)
Ai-WB2的AT指令发送https请求,如何设置header
热力图贡献
UWB 跟随小车 BU04 可以用esp32s3来控制汽车吗?
【BW20-12F开发板评测】6、Zephyr初步
AI-M62-13U 启动蓝牙从机失败,请帮忙查看是什么情况,多谢
【安信可BW20-12F-Kit测评】“高级” 点灯
【电子DIY作品】默语智家-AI智能机器狗(立创地文星开发板+安信
统计信息
会员数: 30228 个
话题数: 44442 篇
首页
分类
我的