关于iOS 蓝牙OAD升级

1. OAD升级机制

OAD升级有两个Bin格式文件  Image-A 和 Image-B 

为了防止蓝牙升级

当在升级的时候,为了防止蓝牙升级出错,需要先查询当前蓝牙镜像 是 Image-A 还是 Image-B 

如果当前是 A 就取 B文件去升级,否则 是B 就取 A文件去升级
    FFC1 特征值用来发送查询版本信息  和 发送升级通知的蓝牙信息

分别发送 0  、1 给蓝牙设备
返回设备镜像信息如:    <0204007c 42424242>     

关于OAD运行机制 参考: http://blog.csdn.net/mirkerson/article/details/39007591


2.蓝牙镜像 类型 版本 大小查询

查询镜像信息的特征  Characteristic

#define BT_OAD_IMAGE_NOTIFY@"F000FFC1-0451-4000-B000-000000000000"    

#define BT_OAD_IMAGE_BLOCK_REQUEST @"F000FFC2-0451-4000-B000-000000000000"

    //FFC2 特征值用来传输升级信息

    CBPeripheral *peripheral;

    CBCharacteristic *characteristic_oad_1; 

    CBCharacteristic *characteristic_oad_2;

    //蓝牙设备所以有特征值

    NSDictionary *dic = [[BlueToothManagershareBluetoothManager]connectDic];

    characteristic_oad_1 = [dicobjectForKey:BT_OAD_IMAGE_NOTIFY];

    characteristic_oad_2 = [dicobjectForKey:BT_OAD_IMAGE_BLOCK_REQUEST];

    [peripheralsetNotifyValue:YESforCharacteristic:characteristic_oad_1];

    [peripheralsetNotifyValue:YESforCharacteristic:characteristic_oad_2];

3.发送查询蓝牙设备信息

    Byte byte0[] = {0};

     NSData *data0 = [NSDatadataWithBytes:byte0length:sizeof(byte0)];

   [peripheralwriteValue:data0forCharacteristic:characteristic_oad_1type:CBCharacteristicWriteWithResponse];

   sleep(1);

     Byte byte1[] = {1};

     NSData *data1 = [NSDatadataWithBytes:byte1length:sizeof(byte1)];

 [peripheralwriteValue:data1forCharacteristic:characteristic_oad_1type:CBCharacteristicWriteWithResponse];


可写(01)、监听(返回8bytes数据)。

当写入0时若有8bytes数据返回,则说明当前硬件固件为镜像A,若写入0无返回数据,而写入18bytes数据返回,则说明当前硬件固件为镜像B

Byte 0 和 Byte 1 表示 镜像的编译版本号    高低位要对调   应该为:  0402 =>  4*16*16 + 2  = 1026   

根据嵌入式对应的 应该再除以2  为编译版本号为513   (具体未去探究,知道的朋友告诉我下,暂时没明白。)

Byte 2 和 Byte 3 表示 镜像的大小        高低位要对调计算  应该为 :   7c00 => 7*16*16*16 + 12*16*16 = 31744 B 

        根据几个实际的bin文件 应该是 124KB  。    猜想应该是  31744 * 4 = 126976 B = 124 KB 。(知道的朋友告诉我下,暂时没明白。)

Byte 4 - Byte 7   表示  当前是B镜像    默认情况下,镜像A中这4bytes均为AASCII码(即40x41),而镜像B中均为BASCII码(即40x42)。


4.发送升级信息

根据3可以得知 设备是镜像A还是B 。

选择对应Bin文件 发送升级信息

            NSString *filePathA = [[NSBundlemainBundle]pathForResource:@"IMAGE_A(8)"ofType:@"bin"];    

            oadData = [NSDatadataWithContentsOfFile:filePathA];

            Byte *Dvalue = (Byte *)[oadDatabytes];    

            NSData *data = [oadDatasubdataWithRange:NSMakeRange(4,8)];

            NSData *sendData = [NSDatadataWithBytes:bytelength:sizeof(byte)];

            [peripheralwriteValue:sendDataforCharacteristic:characteristic_oad_1type:CBCharacteristicWriteWithResponse];

这里的截取oadData  4 —— 12    8个字节的信息 实际上是要升级包的包信息  发送给设备

比如要发送   A镜像 -> 发送  <0100007c 41414141> 

在CBPeripheralDelegate

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullableNSError *)error

{

         // 如果是返回的UUIDString 是升级的特征值 表示可以升级

         if ([characteristic.UUID.UUIDStringisEqualToString:BT_OAD_IMAGE_BLOCK_REQUEST])

        {

               //启动定时器发送 升级文件 网上看了一些Demo说是 可以取消对这个特征值的监听 ()

                [peripheralsetNotifyValue:NOforCharacteristic:characteristic];

                [selfstartSendData];

         }

}

5.分包发送升级文件

- (void)startSendData

{

   if (!sendTime &&allowUpdate

   {

       x =0;

// 这里以每秒 20ms 发送一个包  在iOS 20ms 没问题。  在安卓中 大于 50ms, 已经避免蓝牙拥堵造成升级失败。

        sendTime[NSTimerscheduledTimerWithTimeInterval:0.02target:selfselector:@selector(sendData:)userInfo:nilrepeats:YES];

   }

}



- (void)sendData:(NSTimer *)t{

    

        //  把Bin文件 转换成NSData  分包传输  每个包 为18个字节 

        //  前2个字节 表示包的索引  第几个Block    后16个字节表示 内容  。  固定

    Byte *Dvalue = (Byte *)[oadDatabytes];

    Byte byte[18];

    for (int i =0; i < 18; i++) {

        if (i <=1 ) {

            byte[0] =x%256;

            byte[1] =x/256;

        }

        else{

            if (i -2 + x*16 <oadData.length) {

                byte[i] = Dvalue[i -2 + x*16];

            }

            else{

                byte[i] =0xFF;

            }

        }

    }

    

    NSData *sendData = [NSDatadataWithBytes:byte length:sizeof(byte)];

    NSLog(@"\n%ld - \n%@",x,sendData);

    [peripheralwriteValue:sendData forCharacteristic:characteristic_oad_2type:CBCharacteristicWriteWithoutResponse];

    x++;

    

    float sendValue = (float)x*16/(float)oadData.length;

    NSLog(@"升级了 %.2f",x,sendValue);


  // 此时设备蓝牙会断开

    if (x*16 >=oadData.length) {

        [sendTimeinvalidate];

        NSLog(@"升级完毕");

    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值