公司需要做一个蓝牙模块的升级程序, 需要做成一个android apk, 主要使用 java 和 C(jni) 来实现;
准备
- 首先就是要先熟悉固件的升级文档, 按照流程来做, 一开始没有熟悉文档, 出了一些问题;
- 其次我这个模块升级模式和指令模式时的串口配置是不同的, 升级时需要开启偶校验, 串口配置需要注意;
技术实现
模块的升级, 说白了也就是把将升级文件替换模块里已存在的文件, 也是数据的收发, 只不过在发文件前需要一些准备工作, 每一步按照文档就好了;
文件的读取我使用了RandomAccessFile这个java类, 再借助 MappedByteBuffer 的 get 方法获取字节, 每次读取一个发送包需要的字节数量, 这样的话, 读文件就没有什么问题了;
不过有时候读取的字节是比较奇怪的值, 之后了解到每一个读取到的字节都需要 & 0xff , 毕竟都是二进制;
在蓝牙固件的升级的过程中也涉及到了许多的位运算;
发送的数据都是字节来做的, 在java层不太好做, 也许全部用 C 实现会好做一些, 可是我的C毕竟水平也就一般;
优化
由于在发送接收过程中, 需要对一些字符做替换和分析, 所以我选择将数据在int数组,string,string数组之间转换, 毕竟在java层使用String操作起来比较方便;
第一版的升级成功率比较低, 检查发现一部分原因是 GC 太多, 占用了太多时间, 延误了我发送数据包, 模块接收失败;
降低GC, 需要减少内存占用, 我采用的方法是减少局部变量, 尽可能的把变量设为全局变量; 其次就是减少使用String, String拼接的时候自动生成临时变量, 是很占内存的, 因为我的程序不是多线程的, 所以使用StringBuilder替代String;
代码片段
1 2 3 4 5 6 7 8 9 10 11 12 |
String Integer.toHexString(int) 把数字转换成十六进制的String // 读文件 private FileChannel fc; private MappedByteBuffer out; fc = new RandomAccessFile(pathString, "r").getChannel(); out = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); int fileLength = fc.size(); |
0 Comments