#创作者激励# 记一次失败的探索经历,失败不可怕,过程有价值 原创 精华
【本文正在参加2023年第一期优质创作者激励计划】
1.前言
熟悉我的朋友会知道,我是一个追求新奇而且做事情比较极致的人,我所追求的不是完美,而是探索过程那一种酣畅淋漓的快感,沉迷于那种思维的锻炼,比如前面这篇:由一个编译参数引发的gn构建依赖图谱查询,这次我又碰到一个感兴趣的东西了,然后一发不可收拾,等研究结束一天就那么过去了.
那么这次又是碰到什么让我值得探索的东西,且看后文
2.Hi3861的Flash读写
众所周知,在Hi3861芯片里面是支持flash读写的,相应的api长这样:
"file://base/iothardware/peripheral/interfaces/inner_api/iot_flash.h"
unsigned int IoTFlashRead(unsigned int flashOffset, unsigned int size, unsigned char *ramData);
unsigned int IoTFlashWrite(unsigned int flashOffset, unsigned int size,
const unsigned char *ramData, unsigned char doErase);
那么使用这样的接口很容易就做出来一个简单的存取flash的demo,比如这样:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_flash.h"
#include "iot_errno.h"
/**************测试flash读写**************/
static void in_flash_test(void)
{
uint8_t w_buf[] = {0x01,0x02,0x03,0x04,0x05};
uint8_t r_buf[100] = {0};
//写入数据
IoTFlashWrite(0x1fb000, 5, (uint8_t *)buf, TRUE);
//读取数据
IoTFlashRead(0x1fb000, 100, (uint8_t *)r_buf);
for(int i=0;i<100;i++)
{
printf("%02x ",r_buf[i]);
}
}
APP_FEATURE_INIT(in_flash_test);
这样的程序就能实现写入flash和读取flash内容,那么此时问题就出现了
- 这样写入的数据重新烧录固件就不见了,在平时调试的时候,或者假如产品返厂维修的时候就会丢失数据,这显然是不行的
- 在产品生产的时候,往往要些一些数据进行产测或者置入一些SN码等等内容,或者单纯就是有一份内容想要提前写到flash里让系统一开机就读取应该怎么办?
现在首先来解决这样两个问题
3.尝试利用Hiburn烧录工具解决第一个问题
打开Hiburn软件,仔细观察Hiburn的界面,会发现这样一些内容:
想起来有一个HiBurn软件的使用手册,结果在电脑里面翻箱倒柜的真的被我找出来到了,马上查阅数据手册(手册放在下载附件内):
Burn Size就是管控擦除的flash长度的,所以一个问题的解决办法就是:每次烧录的自己指定一个BurnSize比如可以跟固件的FileSize一致,如下:
但是实际效果发现此种方法却不行,及时手动改了BurnSize,最后在烧录的时候还会被强制恢复成:2097152,这个值其实就是Hi3861的Flash大小(2M),所以此方法失败
最后经过一番摸索,也没找到有什么办法,所以第一个问题暂时就先放一边吧
4.尝试利用Hiburn烧录工具解决第二个问题
设想如下一个场景:我的设备开机的时候,需要读取一传SN码,然后利用SN码去物联网平台去注册或者登录设备.
那么要实现这样的功能,有一种方法就是提前在产线烧录阶段将SN等信息烧录到芯片内部,这里我们再次使用官方的HiBurn工具,在手册中有这样一句话:
这里的参数文件暂时还不知道是什么意思,根据以往个嵌入式开发经验,这里我暂且理解成一个文本文件吧,所以这里制作一个测试文件:
将这样的文件跟固件文件一起放在Biburn软件里,固件端的代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_flash.h"
#include "iot_errno.h"
/**************测试flash读写**************/
static void in_flash_test(void)
{
uint8_t r_buf[100] = {0};
//读取数据
int ret =IoTFlashRead(0x1fb000, 100, (uint8_t *)r_buf);
printf("==>read ret = %d",ret);
for(int i=0;i<100;i++)
{
printf("%02x ",r_buf[i]);
}
}
APP_FEATURE_INIT(in_flash_test);
然后需要设置test.txt文件烧录地址和大小,另外设置烧录文件类型为2,如下(注意此种方法需要两次点击Select File按钮):
这样执行烧录的时候最后可以看到这样的日志:
这样就完成了,串口日志看一下:
因为是按%02x方式打印的,所以是ascii的二进制形式,对比一下源文件就可以知道读出的就是刚刚写入的内容.
到这里第二个问题算是解决成功.
5.事情并没有完结
这里如果只想解决第二个问题,问题就已经完事了,然而这里我又产生了新的思考:用这样的方式烧录固件太繁琐,有没有一种自动化的方式呢?
这里我就回想起来,Devco Tools可以使用命令行的方式来下载固件,看一看是怎么实现的,然后下载了新版的Devco Tools,按照以往经验不去执行安装,直接解压出来,却没有发现HiBurn.exe软件,然后没有思考为何没有HiBurn软件了,直接去下载旧版的Devco Tools,找到了那个Birun的脚本文件,大概这样:
这里是用命令行执行Hiburn.exe,然后这里有一些参数,查看文档:
这里,用一个Demo的指令下载一次固件看看,结果不出意外的成功了.
但是有一个问题,这样确实可以自动化下载固件,但是额外的文件呢?
可以看到Hiburn.exe文档里面没有说有烧录额外的文件的说明,此时有一种想法:有没有可能是软件里面实现了但是没在文档里写出来呢
6.查看Hiburn的"源码"
因为Hiburn软件是直接发布的一个exe文件,所以我们是没有源码的,但是用一些技术手段可以看到源码,那就是用16进制编辑器查看,比如我用的Sublime Txt 4
安装Hex Viewer
,把HiBurn.exe文件导入进来,是这样的界面:
这东西看起来没有用啊?
那只是你的误解,在我这里,哪怕是一个逗号,一个字母都是有用的.根据手册得知,指令用了com
.bin
等这样的字段,那么搜索到这个地方就可以查看到是不是有相关提示,一样还真搜到了:
结果比较失望,发现竟然没有额外的指令支持了,所以这种方失败
.
8.新版的Devco Tools为什么没有Hiburn软件了
回到前面那里,在新版的Devco Tools并没有发现HiBurn.exe这个程序了,但是依然能够实现下载Hi3861的固件烧录,这是怎么回事了,一起来探索这件事.
一番探索,结果发现,新版的Devco Tools使用一个新的方式来下载固件,就是这个hiburn.jar:
点击了这个连接之后,下载得到一个压缩包,经过层层解压,终于得到hiburn.jar文件,然后找到一个文档:
jar文件需要一个java环境才能执行,所幸的是压缩包内自带了一个jre环境,所以制作一个这样的指令就可以烧录固件了:
7.使用Hiburn.jar如何下载附加的文件?
使用hiburn.jar --help查看一下所支持的指令:
看了一下,还是没有找到如何下载额外flash文件的方式,这时候突然想到,会不会仍然是文档和手册没写,而实际上产品实现了呢,看了这里你可能会想,再用16进制编辑器看内容呗,哈哈,错啦
因为我们这次是用的jar文件,我们就需要反编译jar文件,这里教大家一个简单的方式,把jar文件用解压软件解压,然后再用vscode来打开文件夹,安装Decompile扩展:
在打开的.class文件上右键,选择decompile,就可以出现反编译的java文件了:
打开这个文件一看,有一个指令写了:
看来是支持按地址下载的方式的,看起来好像跟之前的hiburn.exe里面下载文件的方式比较像,就试试看:
直接就成功了,这肯定有问题,然后一边查看源码,一边又试了很多方法:
可以看到,这种方式都不行.
所以,结论就是这种方式也是失败.
9.总结
写了这么多,总结起来就是:一次失败的探索经历,但是经过这次失败的经历我想到了几点:
- 都说要国产芯片崛起,真正要国产崛起不只是把芯片做出来,而是也要用心做出好用的脚手架和上下游工具,包括要设想到各种量产啊,测试的场景
- 根据之前的探索Hi3861芯片只能做一点无状态的产品,或者当一个无线网络使用,这样的flash管理做不了什么高级的产品了.
- 希望官方看到这个帖子之后能够思考一下看能否把我的这几个需求解决掉:可以选择性烧录固件的地址和提供额外烧录flash文件的自动化方式.
好了,今天的分享就到这里,希望能对大家有用.
虽然都失败了,但这些方法很值得学习
很喜欢这种探索之后的故事