外部存储器¶
FAQ1 Solution支持哪些外部存储?¶
Solution支持NOR、NAND、eMMC、SD/TF卡,具体可参见方案选型 -> 选型原则,以及FLASH分配 -> 不同芯片PSRAM + Flash的典型配置
支持从NAND、eMMC启动
支持双NOR的方案
SD/TF卡需要先从NOR或NAND/eMMC启动后再挂载
FAQ2 怎么调整Flash的分区?¶
参照Flash 分区表(flashmap)制作介绍,新建工程时,配置好
分页 1:FLASH_Config-
保留产品/项目需要的分区。(注意表里面有公式,有些单元格是自动生成的,删除和新增时注意保持
链接和引用的正确性)在
第3列SIZE调整分区的大小(单位是KB),分区大小注意块对齐。确保第12列JUDGE(对齐/超界)为0,确保第一个区域
第10列OFFSET最后一行为0,表明全部分配完成
注意:
NAND/eMMC方案中,code bin 需要搬到PSRAM中执行(可参见方案选型 -> 选型原则),因此为有效的使用PSRAM的容量,需要注意code bin的size定义在合适的尺寸
NAND/eMMC方案中,内置资源采用文件系统与
Builtin_Res的方案,分页 2:FLASH_Map中分区是不一样的,因此注意选择Solution已有的工程模板做参考双NOR Flash的方案,或NOR + SD卡(或NAND/eMMC)中,
分页 2:FLASH_Map中会有两个分区的信息,注意分区放置内容的正确性。
FAQ3 固件里怎么添加新的Flash驱动?¶
Solution通过 Flash ID 自动适配不同型号及规格的 Flash 驱动。分两种情况:
新 Flash 和已支持 Flash 功能一致(仅加 ID)
查 Flash 规格书,搜
9Fh/RDID,获取 3 个 ID:Manufacturer_id(厂商) /Memory_type(扩展) /Memory_density(密度)和mem_size(容量)其中,
mem_size: 16Mb = 0x200000、 32Mb = 0x400000、 256Mb = 0x2000000)
打开
flash_table.c(NOR)/nand_table.c(NAND),找到flash_cmd_id_pool_typX数组(X 为 0-5,选择与新 Flash 功能一致的),按照FLASH_RDID_TYPE_T类型格式新增一行,注意保留末尾{FLASH_INVALID_ID, 0, 0, 0, 0}编译固件测试即可
示例:新增 W25Q32
在规格书中,找到ID 0xEF/0x60/0x16,32Mb=0x400000
在
flash_cmd_id_pool_typ0中加入一行{0xEF, 0x60, 0x16, 1, 0x400000}
新 Flash 和已支持 Flash 功能不一致(新增驱动)
打开
flash_table.c(NOR)/nand_table.c(NAND),在FLASH_CMD_TABLE_ID_T枚举末尾加新类型(如NOR_TYPE6)在
flash_cmd_table_list数组末尾加配置,复制已有的模板,修改Manufacturer_id/Memory_type/Memory_densityID,其余参数保持默认新增
flash_cmd_id_pool_typX数组(X = 新类型序号,如NOR_TYPE6对应flash_cmd_id_pool_typ6),填入 ID 和容量在
flash_cmd_id_pool数组末尾加&flash_cmd_id_pool_typX[0],编译测试。
⚠️ 注意
NOR Flash 修改
flash_table.c,NAND Flash 修改nand_table.cID 数组末尾必须保留
{FLASH_INVALID_ID, 0, 0, 0, 0},不可删除
FAQ4 烧录驱动里怎么添加新的Flash驱动?¶
在UartburnEx工具 里添加对应的 manufacturer_id、memory_type、memory_density、ext_flags、mem_size,生成下载的Flash驱动
FAQ5 用户固件flash驱动单独配置,通过宏配置参与编译¶
新代码在以下路径做了新的flash驱动管理,支持了更多特殊配置。
对应代码路径:
sdk\customer\peripherals\nand
sdk\customer\peripherals\nor
nand加了单独的ecc status(纠错配置项),用来应对nand flash原厂修改了配置后,我们无法及时兼容时,直接通过ext_cfg配置对应纠错配置,以及设置出现可纠错时的数据迁移阈值
NAND_CFG_REGISTER(hyf4gq4utacae) =
{
.id_type = {
.manufacture_id = 0x01, //flash id每颗flash唯一,查flash规格书,搜9Fh
.memory_type = 0x35, //flash id每颗flash唯一,查flash规格书,搜9Fh
.memory_density = 0x01, //flash id每颗flash唯一,查flash规格书,搜9Fh
.ext_flags = 0x70, //平台对不同flash兼容时要求配置的flags项,注意看配置说明,每个二进制位代表不同含义
/*
ext_flags: 8bit的意义,目前nand flash只用了bit 1 – bit7
bit 0:Nand flash,该bit无意义,该bit 需要设置为0,
bit 1:nand flash plane 标志位,1:两个plane;0:无双plane(常见)
bit 2:nand flash page(页)大小标识位, 0:为常见默认的每个page为2048;1:为每个page为4096
bit 3:NAND flash block(块)大小标识位, 0:为常见的每个block(块)为 64 pages(页);1:为每个每个block(块)为 128 pages(页)
bit 4 - 7:for NAND ECC status mode as NAND_ECC_MODE_T, 为ECC标识位
*/
.mem_size = 0x20000000 //flash大小,从flash规格书确认
},
.cmd_tbl_type = NAND_TYPE3, //平台对不同flash兼容时要求配置的type项,注意看配置说明,每个type对应的flash cmd命令有区别
.ext_cfg = {
.ecc_err_mask = 0x8,
// ecc status value 3 means uncorrectable error
/*这里为什么配置0x8,按照原厂说明,他们最新规格书,两个状态位。没有任何不可纠正错误。所以这里填了一个不可能读到的值。
11=5-6 errors(Rewrite recommended)也可纠正
10=3-4 errors corrected
01=1-2 errors corrected
00=Normal*/
/*单独管理的nand flash ecc纠错走的是这里的配置,而不是ext_flags bit 4 -7的配置
例如:有4位状态位, 只有超过1000b后无法纠正。这里按照提示就是1111b无法纠正,是0xF。而且只有一个无法纠正位
那ecc_err_mask = (1 << 15), //如果有多个无法纠正的值,把值`|`上再赋值给`ecc_err_mask`就行
ecc_err_mask = 0x8000,
0000b = No bit errors were detected during the previous read algorithm.
0001b = bit errors were detected and corrected, error bit number = 1.
0010b = bit errors were detected and corrected, error bit number = 2.
0011b = bit errors were detected and corrected, error bit number = 3.
0100b = bit errors were detected and corrected, error bit number = 4.
0101b = bit errors were detected and corrected, error bit number = 5.
0110b = bit errors were detected and corrected, error bit number = 6.
0111b = bit errors were detected and corrected, error bit number = 7.
1000b = bit errors were detected and corrected, error bit number = 8.
1111b = Bit errors greater than ECC capability(8 bits) and not corrected.
*/
.ecc_rewrite_mask = 0x2
// ecc status value 2 trigger dhara copy
/* 对于可纠错的ecc 错误,配置一个阈值。 到了多少bit可纠正错误后,读出nand里的数据做下数据迁移。原块擦除,提升nand使用寿命。
例如前面的4个状态位,只有超过8bit无法纠错。
你可以配置1bit ~ 7bit任意一个值作为阈值。值越小,迁移越频繁,对功耗影响越大,也会影响flash使用寿命。
nand读,写,擦是有使用寿命的,注意按需配置。
*/
}
};
nor flash增加了对不同otp规格的偏移地址配置,通过ext_cfg.otp_base配置:
NOR_CFG_REGISTER(en25qx128a) =
{
.id_type = {
.manufacture_id = 0x1C, //flash id每颗flash唯一,查flash规格书,搜9Fh
.memory_type = 0x71, //flash id每颗flash唯一,查flash规格书,搜9Fh
.memory_density = 0x18, //flash id每颗flash唯一,查flash规格书,搜9Fh
.ext_flags = 0x0, //bit 0: 用来标识otp地址是否要修改为otp_base的值。配置0走默认的0x0000的otp地址
.mem_size = 0x1000000 //flash大小,从flash规格书确认
},
.cmd_tbl_type = NOR_TYPE0, //平台对不同flash兼容时要求配置的type项,注意看配置说明,每个type对应的flash cmd命令有区别
.ext_cfg = {
.otp_base = 0xFFC000 //从flash规格书确认otp地址参数,一般42h,44h,48h会有介绍otp地址是多少
}
};
FAQ6 FLASH 分区表里的几个 sheet 分别什么时候需要改?¶
客户调整 Flash 空间时,可以先按修改目的定位到对应 sheet:
换 Flash、改 Flash 总大小或对齐方式时,修改
FLASH_CONFIG;新增/删除分区、调整分区大小或文件系统挂载路径时,修改
FLASH_MAP;需要把图片、字体、外置应用等资源放到指定文件系统路径时,修改
FS_RES_PATH;需要重定义二级 bootloader、ftable 等地址宏时,修改
MEM_Map_Customize。
修改后建议重新编译,并检查生成的 flash_map.h、打包日志和烧录文件是否符合预期。详细字段说明请参考 FLASH分区,分区增删请参考 如何进行分区的添加/删除。