iOS蓝⽛开发(三):iOS中蓝⽛模块OTA升级(YModem协议
上⼀篇简单介绍了蓝⽛4.0的iOS实现代码,详细的东西⼤家可以去github上搜babyBluetooth,⾥⾯有⼀些学习资料,接下来分享的是OTA升级的东西,我们假定看这篇⽂章的时候,关于iOS和外设间的蓝⽛收发数据已经掌握的很6
OTA详解
OTA(Over-the-Air)空中传输,⼀般⽤于固件升级。其实和数据传输⼀样,很简单,发送指令,接受指令,发送bin数据包,结束指令。。。只是蓝⽛传输的数据⼤⼩使得这⼀步骤稍显复杂。
⾸先,⽂件传输,其实也是传输的数据,即 NSData,和普通的 peripheral 写⼊没什么区别。固件升级的⽂件⼀般是 .bin ⽂件,也有 .zip 的。不过这些⽂件,都是数据,所以⾸先将⽂件转为 NSData
张柏芝黑白大片曝光
需要注意的是:data ⼀般很长,毕竟是⽂件。直接通过 writeValue:forCharacteristic:type: 写⼊的话,不会有任何回调。哪怕是错误的回调,都没有。这是因为蓝⽛单次传输的数据⼤⼩是有限制的。
我们⼀般使⽤20bytes作为标准,即将bin⽂件转为NSData,然后截成每个20bytes的包发送;这些步骤需要和刷firmware的⼯程师协商,指定⼀个协议,接下来以公司的YModem协议举例
YModem协议
YModem协议是由XModem协议演变⽽来的,是⼀种发送并等待的协议,即发送⽅发送⼀个数据包以后,都 要等待接收⽅的确认。
如果是 ACK 信号,则可以发送新的包。如果是 NAK 信号, 则重发或者错误退出。
每包数据可以达到1024字节,是⼀个⾮常⾼效的⽂件传输协议
所⽤到的符号
#define MODEM_SOH 0x01  //数据块起始字符
#define MODEM_STX 0x02  //1028字节开始
#define MODEM_EOT 0x04  //⽂件传输结束
#define MODEM_ACK 0x06  //确认应答
#define MODEM_NAK 0x15  //出现错误
#define MODEM_CAN 0x18  //取消传输
#define MODEM_C 0x43    //⼤写字母C
数据格式⽰意
工程进度款
⽂件传输过程
开启是由接收⽅开启传输,它发⼀个⼤写字母 C(0x43) 开启传输。然后进⼊ 等待 SOH(0x01))状态,如果没有回应,就会超时退出。
蜗居主要演员发送⽅开始时处于等待过程中,等待 C。收到 C 以后,发送(SOH)数 据包开始信号,发送序号(00),补码(FF),“⽂件
名”,“\0”“⽂件⼤⼩” “除去序号外,补满 128 字节”,16位CRC 校验两个字节,⾼字节在前,低字节在后。进⼊等待(ACK)状态。
- 内容⽰例: SOH 00 FF Foo.bin NUL[123] CRC CRC
接收⽅收到以后,CRC 校验满⾜,则发送 ACK。发送⽅接收到 ACK,⼜ 进⼊等待“⽂件传输开启”信号,即重新进⼊等待“C”的状态。中学生社会调查报告
前⾯接收⽅只是收到了⼀个⽂件名,现在正式开启⽂件传输,Ymodem ⽀持 128 字节和 1024 字节⼀个数据包。128 字节以(SOH)开始,1024 字节以(STX)开始。接收⽅⼜发出⼀个“C”信号,开始准备接收⽂件。进⼊等待“SOH”或者“STX”状态。
发送接收到“C”以后,发送第⼀个数据包,(SOH)(01序号)(F E补码)(128位数据)(CRC校验),或者(STX)(01序号)(F E补码) (1024位数据)(CRC校验),不满128或者1024,⽤0x00补齐,等待接收⽅“ACK”。
- 内容⽰例:STX 01 FE data[1024] CRC CRC
⽂件发送完以后,发送⽅发出⼀个“EOT”信号,接收⽅也以“A CK”回应。然后接收⽅会再次发出“C”开启另⼀次传输,若接着发送⽅会发出⼀个“全0数据包”,接收⽅“ACK”以后,本次通信正式结束。
当然Ymodem相对于Xmodem改进的地⽅就在于传输再次 开启以后,⼜可以发送另外⼀个⽂件,即⼀次传输允许发送多个⽂件,但这个 特性我还没有⽤过,暂且不提。
最后CRC两字节:这⾥需要注意,只有数据部分128或者1024参与了效CRC验,不包括头和编码部分。
CRC校验的计算⽅法
/**
* @brief  Update CRC16 for input byte
* @param  crc_in input value
* @param  input byte
放肆* @retval None
*/
uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte)
{
uint32_t crc = crc_in;
uint32_t in = byte | 0x100;
do
{
crc <<= 1;
in <<= 1;
if(in & 0x100)
++crc;
if(crc & 0x10000)
crc ^= 0x1021;
}
while(!(in & 0x10000));
return crc & 0xffffu;
}
/**
* @brief  Cal CRC16 for YModem Packet
* @param  data
* @param  length
* @retval None
*/
uint16_t Cccal_CRC16(const uint8_t* p_data, uint32_t size)
{
uint32_t crc = 0;
const uint8_t* dataEnd = p_data+size;
while(p_data < dataEnd)无法恋爱的理智派
crc = UpdateCRC16(crc, *p_data++);
crc = UpdateCRC16(crc, 0);
crc = UpdateCRC16(crc, 0);
return crc&0xffffu;
}
以上就是YModem协议进⾏OTA升级的概述
YModem协议以及OTA部分源码