[关闭]
@kezhen 2015-08-19T03:33:05.000000Z 字数 4210 阅读 1879

SUOTA流程

蓝牙升级流程

P1


1. 发起者往外围设备特征SPOTA_MEM_DEV_UUID写值来设置内存类型(memoryType)

  1. // Step 1: Set memory type
  2. step = 0;
  3. expectedValue = 0x10;
  4. nextStep = 2;
  5. int _memDevData = (self.memoryType << 24) | (self.memoryBank & 0xFF);
  6. [self debug:[NSString stringWithFormat:@"Sending data: %#10x", _memDevData]];
  7. NSData *memDevData = [NSData dataWithBytes:&_memDevData length:sizeof(int)];
  8. // 往特征写值成功后将回调两个方法
  9. [manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID]
  10. characteristicUUID:[CBUUID UUIDWithString:SPOTA_MEM_DEV_UUID]
  11. p:manager.device data:memDevData];

2. 发起者往外围设备特征SPOTA_GPIO_MAP_UUID写值设置存储器参数

  1. int _memInfoData
  2. if (self.memoryType == MEM_TYPE_SUOTA_SPI) {
  3. _memInfoData = (self.spiMISOAddress << 24) | (self.spiMOSIAddress << 16) | (self.spiCSAddress << 8) | self.spiSCKAddress;
  4. } else if (self.memoryType == MEM_TYPE_SUOTA_I2C) {
  5. _memInfoData = (self.i2cAddress << 16) | (self.i2cSCLAddress << 8) | self.i2cSDAAddress;
  6. }
  1. [manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_GPIO_MAP_UUID] p:manager.device data:memInfoData];

3. 加载镜像数据,进行循环冗余码校验(CRC)并设置每次发送的数据大小(chunkSize)以及镜像的起始字节(blockStartByte)。

  1. [self debug:[NSString stringWithFormat:@"Loading data from %@", [storage.file_url absoluteString]]];
  2. fileData = [[NSData dataWithContentsOfURL:storage.file_url] mutableCopy];
  1. [self appendChecksum];
  1. chunkSize = 20;
  2. blockStartByte = 0;

4. 发起者往外围设备特征SPOTA_PATCH_LEN写值来指定块长度,以此来告诉接收者镜像的数据块长度。

  1. NSData *patchLengthData = [NSData dataWithBytes:&blockSize length:sizeof(UInt16)];
  2. [manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_PATCH_LEN_UUID] p:manager.device data:patchLengthData];

blockSize是发送镜像的数据块大小,默认是240字节。


p2

5. 发起者往外围设备特征SPOTA_PATCH_DATA发送镜像数据(以blockSize(240kb)为一个单位),重复发送镜像数据每次发送chunkSize字节(20kb)。

  1. - (void) didUpdateValueForCharacteristic: (NSNotification*)notification {
  2. CBCharacteristic *characteristic = (CBCharacteristic*) notification.object;
  3. if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:SPOTA_SERV_STATUS_UUID]]) {
  4. char value;
  5. [characteristic.value getBytes:&value length:sizeof(char)];
  6. NSString *message = [self getErrorMessage:value];
  7. [self debug:message];
  8. // 通过第五步骤跳转到此方法,expectedValue = 0x02
  9. if (expectedValue != 0) {
  10. // Check if value equals the expected value
  11. if (value == expectedValue) { // 得到期望值
  12. // If so, continue with the next step
  13. step = nextStep; // 通过第五步骤跳转到此方法,nextStep = 5
  14. expectedValue = 0; // Reset
  15. [self doStep];
  16. } else { // 出现错误
  17. // Else display an error message
  18. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
  19. [alertView show];
  20. expectedValue = 0; // Reset
  21. [autoscrollTimer invalidate]; // 关闭刷新textView的大小
  22. }
  23. }
  24. }
  25. }
  1. // On to the chunk
  2. chunkStartByte += chunkSize;
  3. // Check if we are passing the current block
  4. if (chunkStartByte >= blockSize) {
  5. // Prepare for next block
  6. blockStartByte += blockSize;
  7. int bytesRemaining = dataLength - blockStartByte;
  8. if (bytesRemaining == 0) {
  9. nextStep = 6;
  10. } else if (bytesRemaining < blockSize) {
  11. blockSize = bytesRemaining;
  12. nextStep = 4; // Back to step 4, setting the patch length
  13. }
  14. }

6. 发起者往外围设备特征SPOTA_MEM_DEV_UUID发送结束指令,并跳转到第七步。

  1. // Send SUOTA END command
  2. step = 0;
  3. expectedValue = 0x02;
  4. nextStep = 7;
  5. int suotaEnd = 0xFE000000;
  6. [self debug:[NSString stringWithFormat:@"Sending data: %#10x", suotaEnd]];
  7. NSData *suotaEndData = [NSData dataWithBytes:&suotaEnd length:sizeof(int)];
  8. [manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_MEM_DEV_UUID] p:manager.device data:suotaEndData];

p3

7. 弹框让用户选择是否重启外围设备,如果选择重启则向外围设备特征SPOTA_MEM_DEV_UUID发送重启指令。

  1. if (buttonIndex != alertView.cancelButtonIndex) {
  2. // Send reboot signal to device
  3. step = 8; // 返回到扫描设备的界面
  4. int suotaEnd = 0xFD000000;
  5. [self debug:[NSString stringWithFormat:@"Sending data: %#10x", suotaEnd]];
  6. NSData *suotaEndData = [NSData dataWithBytes:&suotaEnd length:sizeof(int)];
  7. [manager writeValue:[manager IntToCBUUID:SPOTA_SERVICE_UUID] characteristicUUID:[CBUUID UUIDWithString:SPOTA_MEM_DEV_UUID] p:manager.device data:suotaEndData];
  8. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注