SYDTEK OTA 蓝牙升级功能实现 附带Demo

本文讲述盛芯微公司的蓝牙芯片进行升级OTA操作

一、简介

SYD8801 设备端使用 A、B 区的方式储存代码,即当前程序是在存储在 A 区,OTA 将新程序写入 B 区,然后重启系统,程序从 B 区开始执行,故中途断开连接或者中断 OTA 不会造成设备“变砖”。A、B 区随着 OTA 的次数相互切换。

二、OTA 升级需要条件

1、设备端实现 OTA 接收协议
2、APP 端实现了 OTA 的发送协议
3、设备端蓝牙的 Profile 含有服务 0xFF00,和该服务下有一个可读写的特性 0xFF01

三、OTA 过程

1.发送擦除命令
2.计算总包的CRC
3.ota bin文件按5120字节拆分成若干段,每段按20字节拆分成若干包。
先发送当前段的CRC校验数据,然后循环发送当前段的数据
4.最后发送升级指令

具体算法思路

1.读取bin文件转成二进制流 byte[]

2.计算出这个二进制流的CRC码 算法如下 其中ReadData为二进制字节流数组

for(i=0;i<ReadData.length;i++)
{
    int CC = ReadData[i];
    CC &= 0x000000FF;
    CRC += CC;
    CRC = CRC & 0x0000FFFF;
}

3.发送擦除指令

byte [] WriteData = new byte[2];
WriteData[0] = 0x16;
WriteData[1] = 0x00;

4.收到写入成功 计算总包数 总长度/每包大小 有余数多加一包
SendPacketAllNum = ReadData.length/MAX_TRANS_COUNT_V30 //MAX_TRANS_COUNT_V30为20 即每包大小是20字节

  if (ReadData.length % MAX_TRANS_COUNT_V30 != 0)
            SendPacketAllNum += 1;  

5.计算出每段的CRC SECTION_CRC 算法如下 CRC就是将要发送包段的每个字节相与0x000000FF计算再求和
不是最后一包 其中SendSectionID为当前发送的段序号

for(int i=0;i<20;i++)
{
int CC = ReadData[SendSectionID*20+i];
CC &= 0x000000FF;
SECTION_CRC += CC;
}

最后一包 比如最后一包10字节

for(int i=0;i<10;i++)
{
    int CC = ReadData[SendSectionID*MAX_TRANS_SECTIONALL_COUNT+i];
    CC &= 0x000000FF;
    SECTION_CRC += CC;
}

6.按段落发包Demo限定5120为一段,每发完一段去读取设备的校验和,成功继续发送下一段,失败重发当前段,读这个步骤可以省略

整体代码思路
发送完擦写包后 延迟3秒开始写入 每段数据最大 5120/20 = 256包

7.发送每段数据之前先发送当前段的校验和CRC check 为当前段的CRC size为当前段的大小 SendSectionID为当前包段序号

    byte[] WriteData = new byte[10];
    int Address = SendSectionID * 5120;

    WriteData[0] = CMD_FW_WRITE_START;
    WriteData[1] = 0x13;
    WriteData[2] = (byte) (Address & 0x000000FF);
    WriteData[3] = (byte) ((Address & 0x0000FF00) >> 8);
    WriteData[4] = (byte) ((Address & 0x00FF0000) >> 16);
    WriteData[5] = (byte) ((Address & 0xFF000000) >> 24);
    WriteData[6] = (byte) (size & 0x000000FF);
    WriteData[7] = (byte) ((size & 0x0000FF00) >> 8);
    WriteData[8] = (byte) (check & 0x000000FF);
    WriteData[9] = (byte) ((check & 0x0000FF00) >> 8);

发完段序号开始循环发送该段中的包 每包20字节 256个包完成后 去读取设备的校验和 如果设备读出的校验和不等于当前包段的校验和重发当前包
int check = ((data[7] & 0xff) << 8) | (data[6] & 0xff);

       //error check and resend
        if ((check & 0x0000ffff) != (SECTION_CRC & 0x0000ffff)) {
            SendSectionID -= 1; //段序号-1
            SendPacketID = MAX_TRANS_SECTIONALL_PACKET_COUNT * SendSectionID; //重置当前发送的包位置
   
        }

8.直到所有包段都发送完成 发送结束包

    byte[] WriteData = new byte[8];
    WriteData[0] = 0x15;
    WriteData[1] = 0x04;
    WriteData[2] = (byte) (Size & 0x000000FF);
    WriteData[3] = (byte) ((Size & 0x0000FF00) >> 8);
    WriteData[4] = (byte) ((Size & 0x00FF0000) >> 16);
    WriteData[5] = (byte) ((Size & 0xFF000000) >> 24);
    WriteData[6] = (byte) (CRC & 0x000000FF);
    WriteData[7] = (byte) ((CRC & 0x0000FF00) >> 8);

附上demo
demo演示了搜索蓝牙设备,连接蓝牙设备 用的第三方库

 implementation 'com.clj.fastble:FastBleLib:2.3.4'

读者关注V30TestActivity里面的实现即可扫描蓝牙部分根据实际过滤

 BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
                addLog("搜索完成...");
                for (BleDevice bleDevice : scanResultList) {
                    if (!TextUtils.isEmpty(bleDevice.getName()) && (bleDevice.getName().startsWith("BAT001") || bleDevice.getName().startsWith("mtm"))) {
                        Map<String, String> listem = new HashMap<String, String>();
                        listem.put("name", bleDevice.getName());
                        listem.put("mac", bleDevice.getMac());
                        deviceList.add(listem);
                        resultBle.add(bleDevice);
                    }

                }
                myBleDeviceAdapter.notifyDataSetChanged();

            }

            @Override
            public void onScanStarted(boolean success) {
                addLog("扫描中...");
                deviceList.clear();
                resultBle.clear();

            }

            @Override
            public void onScanning(BleDevice bleDevice) {

            }
        });

最后附上demo连接
https://gitee.com/FIUI/SYD_OTA

不懂得联系我

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值