FLASH 开发指导_Rev1.3
修订记录
版本 |
日期 |
作者 |
修订内容 |
|---|---|---|---|
Rev1.0 |
23-09-11 |
TL |
创建文档 |
Rev1.1 |
24-03-25 |
sxx |
更改文档名称 |
Rev1.2 |
24-05-07 |
YMX |
优化文档结构,调整部分文字描述 |
Rev1.3 |
25-04-18 |
ZH |
增加系列常见问题 |
1 引言
本文档介绍 LTE-EC71X FLASH 接口 API 情况, API 接口位于 components/kernel/lierda_api/liot_flash/liot_flash.h 文件声明中。
新增
如下图为flash区域分区参考图,不同版本SDK FLASH分区会有所不同:
/*
flash layout, toatl 4MB
flash raw address: 0x00000000---0x00400000
flash xip address(from both ap/cp view): 0x00800000---0x00c00000
0x00000000 |---------------------------------|
| header1 4KB |
0x00001000 |---------------------------------|
| header2 4KB |
0x00002000 |---------------------------------|
| fuse mirror 4KB |
0x00003000 |---------------------------------|
| bl 72KB |
0x00015000 |---------------------------------|
| rel data(factory)20KB |
0x0001a000 |---------------------------------|
| cp img 400KB |
0x0007e000 |---------------------------------|
| app img 3116KB |
0x00389000 |---------------------------------|
| hib backup 96KB |
0x003a1000 |---------------------------------|
| lfs 48KB |
0x003ad000 |---------------------------------|
| fota 272KB |
0x003f1000 |---------------------------------|
| rel data 52KB |
0x003fe000 |---------------------------------|
| plat config 8KB |
0x00400000 |---------------------------------|
*/
#define FLASH_RESERVE_USER_REGION_START (0x3ad000)
#define FLASH_RESERVE_USER_REGION_END (0x3ac000)
#define FLASH_RESERVE_USER_REGION_SIZE (FLASH_RESERVE_USER_REGION_END-FLASH_RESERVE_USER_REGION_START) // 4KB
上述分区图
2 API 函数概览
函数 |
说明 |
|---|---|
|
擦除 flash 中的数据。 |
|
从 flash 中读取数据。 |
|
向 flash 中写入数据。 |
3 API 函数详解
API 仅限对预留的 4KB 区域(0x3ad000~0x3ac000)进行操作,API频繁调用减少falsh寿命(10W次),建议频繁操作时使用文件系统相关API。
3.1 liot_flash_erase
该函数用于擦除 flash 中的数据。
声明
uint32_t liot_flash_erase(uint32_t SectorAddress, uint32_t size);
参数
SectorAddress:[In] 清除区域起始地址。它必须是 0x1000 的倍数,并且位于用户 FLASH 中。
size:[In] 要擦除的长度。
返回值
0:成功。
other: 失败。
3.2 liot_flash_read
该函数用于从 flash 中读取数据。
声明
uint32_t liot_flash_read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size);
参数
pData:[Out] 存储从 flash 中读取数据的地址。
ReadAddr:[In] 读取数据的起始地址。
Size:[In] 要读取的长度。
返回值
0:成功。
other: 失败。
3.3 liot_flash_write
该函数用于向 flash 中写入数据。
声明
uint32_t liot_flash_write(uint8_t *pData, uint32_t WriteAddr, uint32_t Size);
参数
pData:[In] 存储向 flash 中写入数据的地址。。
WriteAddr:[In] 写入数据的起始地址。
Size:[In] 要写入数据的长度。
返回值
0:成功。
other: 失败。
4 代码示例
示例代码参考 examples/demo/src/demo_flash.c 文件。
#include "lierda_app_main.h"
#include "liot_flash.h"
#include "liot_os.h"
#include "liot_type.h"
#include "mem_map.h"
/*
This project demonstrates the use of user area flash.
In this case, we will erase a user area, write data to it, and then read the written data for printing.
Non-user areas, such as the LIOT_BEFORE_APP_ADDR and LIOT_AFTER_APP_ADDR areas, cannot be erased, written, or read.
*/
#define FLASH_RESERVE_USER_REGION_START (0x3e4000)
#define FLASH_RESERVE_USER_REGION_END (0x3e5000)
#define FLASH_RESERVE_USER_REGION_SIZE (FLASH_RESERVE_USER_REGION_END-FLASH_RESERVE_USER_REGION_START) // 4KB
void liot_flash_demo_task(void *argv)
{
char app_data[] = "BBBBBBBBBB";
char app_buff[11] = {0};
liot_rtos_task_sleep_ms(2000);
liot_trace("========== flash demo start ==========");
liot_trace("=== Print erase flash address ====", LIOT_APP_ADDR_START, LIOT_APP_ADDR_END);
liot_trace("=== erase before app address, ret(%d) ====", liot_flash_erase(LIOT_APP_ADDR_START, LIOT_APP_ADDR_SIZE));
liot_rtos_task_sleep_ms(100);
liot_trace("=== Write data to flash ====");
liot_trace("=== write data on before app address, ret(%d) ====",
liot_flash_write((uint8_t *)app_data, LIOT_APP_ADDR_START, 10));
liot_rtos_task_sleep_ms(100);
liot_trace("=== Read data from flash ====");
liot_trace("=== read data on app address, ret(%d) ====",
liot_flash_read((uint8_t *)(&app_buff\[0\]), LIOT_APP_ADDR_START, 10));
liot_rtos_task_sleep_ms(100);
liot_trace("=== Print the read data ===");
liot_trace("=== app_buff(%s) ===", app_buff);
liot_trace("========== flash demo end ==========");
liot_rtos_task_delete(NULL); // kill itself
}
运行结果:
如上图所示,对比读写前后的两组数据,liot_flash_write()写入成功,liot_flash_read()读取到数据 BBBBBBBBBB,与写入数据一致,表明 flash 读写成功。
5 常见问题
5.1 如何确认FLASH的地址范围
示例代码中的地址范围如下:
#define FLASH_RESERVE_USER_REGION_START (0x3e4000) |
|---|
不同模组的地址范围不同,具体查看"mem_map_71x.h"中的宏定义,如716s中地址定义如下:
5.2 Flash写入之前需要先擦除吗
建议擦除。
如果不擦除,比如Flash中已经写入"hello world",再次写入"12345",则读出的数据为"12345 world"
5.3 Flash擦写次数是多少
10W次。
5.4 重新烧录固件后写入的Flash是否会被擦除
会被擦除。
5.5 EC718 是否支持外挂 flash?
可以,通过普通的 4 线 SPI 接口就可以实现外挂 flash,注意外挂 flash 只能存放一些数据,片外 flash 不支持代码执行。

