命令容器介绍与例程展示
简介
在HPM Manufacturing Tool V0.5.0版本中,镜像编辑新增了对命令容器的编辑。命令容器是一种对 ROM 支持的若干命令的打包封装。进一步讲,命令容器就是对ROM API的再封装,通过加头和尾部哈希校验,将一系列ROM API封装在一个容器中,这就是命令容器的本质。
命令容器支持的命令
要生成一个命令容器,首先得知道他能做什么,这里我们对命令容器支持的指令进行简单讲解
configure-memory
该指令支持对XPI总线上的FLASH进行直接配置,在使用指令时,同时传入flash的配置信息,如“0xfcf90002,0x00000007,0x0000000e,0x00000000”,此时MCU访问flash的频率,电压等信息均配置完成,不需要将配置信息先写入ILM再通过ILM配置flash。
该指令仅用于告诉BOOTROM,该使用何种配置去访问flash,不会将配置的信息写入flash的0x400处。
Configure-memory指令的数据块格式如下所示
Write-memory
该指令支持对flash和OTP进行烧写,烧写内容紧跟在指令后,即下图中Data Block处
需要注意的是,对OTP的烧写是不可逆的,对flash进行烧写需要先进行configure-memory
这里补充说明一下为什么write-memory写flash时需要先进行configure-memory:
BOOTROM从flash启动时,在读取地址 0x400 的数据之前,BOOTROM会使用 默认的 SPI 1-1-1 模式 和 最低支持频率(如 10 MHz 以下)进行通信,电压则由系统硬件预设或 Flash 的默认状态决定。读取 0x400 的数据后,BOOTROM根据配置切换到更高效的通信模式或频率,这是镜像启动过程中,BOOTROM配置flash的过程。
但对于write-memory来说,他并不会使用启动过程中获取到的flash配置信息,而是通过自己维护的一套独立的参数来决定以什么样的方式去访问flash,倘若不通过configure-memory写入,则无法与flash进行通信。
Erase-region
该指令用于擦除flash指定地址的指定长度内容,需要注意的是,flash擦除都是以页为单位。以HPMICRO开发板举例,开发板上的flash一个页4096个字节,ROM会计算起始地址+长度所在的内容在那个/哪几个页上,然后把这几个页都删掉
Reset
Reset没啥好说的,注意不要在ISP模式下使用该指令即可
快速上手
接下来通过镜像编辑工具生成一个命令容器,更加直观得展示他的功能
我们这里生成一个RAM镜像,目的是往flash中烧录一个SDK编译出的GPIO例程
Configure-memory配置参数为“0xfcf90002,0x00000007,0x0000000e,0x00000000”
Write-memory指定了写的地址为0x80000400,写的内容是我本地的一个bin文件
配置完成后,点击生成按钮,便得到了一个命令容器镜像
需要注意的是,命令容器要求必须有哈希校验,因此需要在固件信息表中配置一种哈希类型。同时,命令容器存放的位置就是镜像的固件0位置,只不过他从你写的APP变成了ROM API的指令队列。
我们将开发板的boot pin拨到10,然后通过“load-image”指令将该容器通过ISP进行执行
最后会提示
此时容器已经通过ISP执行完毕,我们将boot pin拨回00,查看flash中写入的程序是否能正确启动
从串口中可以看到,镜像启动正常,说明命令容器write-memory写入的镜像完整无误
细节刨析
最后讲讲命令容器的组织结构,命令容器的最小单位叫做块。命令容器头也是以块的形式进行组织的,一个块的结构如下
命令容器数据包按块打包,块的长度为变长,由前一个块的末尾的 next_block_info 字段来指示下一个块的长度。第一个块的固定为命令容器头,长度固定。最后一个块不包含 next_block_info
命令容器头的数据结构如下
以上文生成的命令容器为例,我们用二进制阅读工具查看一下他生成的bin文件
第一行为固件容器头,与寻常的固件是一致的
第二行开始是固件信息表,红色的01表示该固件为命令容器,而非可执行镜像
从0000 0090开始,便是命令容器的内容了
红色方框为命令容器的第一个块,即包含命令容器头的块
在该块中,有命令容器头部分有效数据 + next_block_info + next block hash