美文网首页
iOS蓝牙开发 OAD升级

iOS蓝牙开发 OAD升级

作者: 静谧无际 | 来源:发表于2017-03-17 19:26 被阅读1174次

    在做蓝牙开发的时候,基本上都需要对蓝牙设备进行升级。当时蓝牙模块应用的是CC2640,查阅了许多空中升级的相关资料。在查阅的过程中,发现关于iOS蓝牙开发空中升级的材料非常少(也可能是我没找到),TI公司也没有提供iOS空中升级的源码,只提供了Android的源码git。于是参考了Android的OAD源码,并结合《CC2640 BLE OAD User's Guide》,最终实现了OAD升级。

    • OAD升级涉及到的服务及特征值
      • OAD Service: F000FFC0-0451-4000-B000-000000000000
        1. FFC1 F000FFC1-0451-4000-B000-000000000000
        2. FFC2 F000FFC2-0451-4000-B000-000000000000

    Off-Chip OAD升级大致过程

    升级前准备:下载蓝牙设备待升级的Bin文件,称之为Image

    1. 开启OAD相关特征值的通知。
    2. App向蓝牙设备发送Image的Metadata
    3. App得到响应后,开始发送一块Image block信息
    4. 得到响应后继续发送下一块信息
    5. 直到所有的Image Block信息发送成功,蓝牙设备升级也就完成了。

    Off-Chip OAD升级详解

    • 开启OAD相关特征值的通知。

        为了能够得到蓝牙设备的响应信息开启FFC1,FFC2的通知
      
    -(void)configWithPeripheral:(CBPeripheral *)peripheral characteristics:(CBCharacteristic *)characteristic{
        if([characteristic.service.UUID.UUIDString isEqualToString:OADService]){
            if([characteristic.UUID.UUIDString isEqualToString:OADFFC1]){
                if(!characteristic.isNotifying){
                    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                }
            }
            
            if([characteristic.UUID.UUIDString isEqualToString:OADFFC2]){
                if(!characteristic.isNotifying){
                    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                }
            }
            
            if([characteristic.UUID.UUIDString isEqualToString:OADConfigNotifyCharacter]){
                if(!characteristic.isNotifying){
                    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                }
            }
    
        }
    }
    
    • App向蓝牙设备发送Image的Metadata

        (1)写入到哪里?
        FFC1负责接收Metadata,将Metadata写入FFC1特征。
        (2)如何得到Metadata?
        需要根据Metadata数据格式自己生成。
        CRC的生成方法是在Android源码中找到的
        Length为Image大小的1/4
      
      Paste_Image.png
      - (Image_header)imageHeader{
        Image_header image_header;
        image_header.crc0 = [self calcImageCRC:0];
        image_header.crc1 = 0xffff;
        image_header.ver = 0;
        image_header.len = self.data.length / 4;
        image_header.uid[0] = image_header.uid[1] = image_header.uid[2] = image_header.uid[3] = 'E';
        image_header.address = 0x1000 / 4;
        image_header.imgType = 1;
        image_header.state = 0xff;
        return image_header;
      

    }

    * 写入成功后,蓝牙设备会响应第一个要写入的Image Block块数,一般为0
    
          (1)何为Image Block?
              一个Block被规定为16个字节
              比如:Image文件的大小为115k
              115k*1024/16 = 7360块
              0就代表Image的前16个字节
          (2)从哪里得到响应信息?
              因为OADService服务下已经开启了FFC2的通知,Block信息会从FFC2特征值响应
          (3)得到0后该如何做?
              从Image提取第一块Block,写入FFC2特征。
          (4)写入Block的数据格式是什么?
              2Byte + 16Bye = 18Byte
              前两个字节代表第几个Block后16个字节表示Block内容
       
          
    

    requestData[0] = LO_UINT16(self.iBlocks);
    requestData[1] = HI_UINT16(self.iBlocks);
    memcpy(&requestData[2], &imageFileData[self.iBytes], OAD_BLOCK_SIZE);
    [SPBLE writeNoResponseCharacteristic:currentPeripheral sCBUUID:self.oadServiceUUID cCBUUID:self.oadWriteUUID data:[NSData dataWithBytes:requestData length:(2 + OAD_BLOCK_SIZE)]];

    * 得到响应后继续发送下一块信息
           
           写入成功后会得到响应1,从Image提取下一块信息,写入        FFC2特征……直到所有的Block都写入成功,升级结束。
    (5)如何判断升级成功?
           
           升级完成后,蓝牙设备会断开连接,说明升级已成功了。
           
    通过代理可监测升级进度
    
    

    @protocol SPBLEOADUpdaterDelegate <NSObject>
    -(NSData *)updatedImage;
    -(CBPeripheral *)updatedPeripheral;
    -(void)updater:(SPBLEOADUpdater *)updater progress:(CGFloat)progress;
    @end

            
    
    ![Paste_Image.png](https://img.haomeiwen.com/i2286896/6e5be036a09cfdc1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    [源码地址](https://github.com/somson/BLEOAD)

    相关文章

      网友评论

          本文标题:iOS蓝牙开发 OAD升级

          本文链接:https://www.haomeiwen.com/subject/rrgenttx.html