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

不懂得聯繫我

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章