泰凌微的SDK中已经实现了OTA功能,具体的处理已经被封装到库中,开发可以在不修改代码的情况下通过官方的APP来完成升级功能
如有异议,欢迎留言指正
0x00000~0x1FFFF与0x20000~0x3FFFF
进行交替升级0x00000~3FFFF与0x40000~7FFFF
进行交替升级未使用到的地址均可被用作用户自定义信息存储
0x20000地址划分
bls_ota_set_fwSize_and_fwBootAddr
//设置最大的firmware size 为 252K
bls_ota_set_fwSize_and_fwBootAddr(200, 0x40000);//200k, 4byte对齐
app连接上设备获取到指定的服务后,会下发OTA_start命令通知设备加入OTA升级模式
app将固件信息持续不断下发给设备
固件传输完成后,app会继续发送一个OTA_end命令
设备收到OTA_end命令后,进行固件更新与指定标识的擦写,并重启系统跳转到新固件运行
过程中如果出现接收超时、丢包、错包,设备slave会主动断开连接并重启
在app_att.c中定义了ota的服务与读写属性,这里是泰凌微私有的,不用修改
static const attribute_t my_Attributes[] = {
// OTA /
// 002e - 0031
{4,ATT_PERMISSIONS_READ, 2,16,(u8*)(&my_primaryServiceUUID), (u8*)(&my_OtaServiceUUID), 0},
{0,ATT_PERMISSIONS_READ, 2, sizeof(my_OtaCharVal),(u8*)(&my_characterUUID), (u8*)(my_OtaCharVal), 0}, //prop
{0,ATT_PERMISSIONS_RDWR,16,sizeof(my_OtaData),(u8*)(&my_OtaUUID), (&my_OtaData), &otaWrite, &otaRead}, //value
{0,ATT_PERMISSIONS_READ, 2,sizeof (my_OtaName),(u8*)(&userdesc_UUID), (u8*)(my_OtaName), 0},
}
泰凌微SDK中OTA的UUID固定
{0x12,0x2B,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00}
Att_value中数据定义为通信命令和固件数据的格式,20字节的数据划分为如下
// OTA init
bls_ota_clearNewFwDataArea(); //must
bls_ota_registerStartCmdCb(entry_ota_mode);//注册ota_start回调
bls_ota_registerResultIndicateCb(show_ota_result);//注册ota结果回调
void entry_ota_mode(void)//启动ota回调
{
bls_ota_setTimeout(15 * 1000 * 1000); //设置升级超时15秒 set OTA timeout 15 seconds
#if(BLT_APP_LED_ENABLE)
gpio_set_output_en(GPIO_LED, 1); //output enable
gpio_write(GPIO_LED, 1); //打开LED显示 LED on for indicate OTA mode
#endif
}
void show_ota_result(int result)
{
#if(1 && BLT_APP_LED_ENABLE)
gpio_set_output_en(GPIO_LED, 1);
if(result == OTA_SUCCESS){ //OTA 升级成功
gpio_write(GPIO_LED, 1);
sleep_us(500000);
gpio_write(GPIO_LED, 0);
sleep_us(500000);
gpio_write(GPIO_LED, 1);
sleep_us(500000);
gpio_write(GPIO_LED, 0);
sleep_us(500000);
}
else{ //OTA 升级失败,result为失败状态
#if 0 //this is only for debug, can not use this in application code
irq_disable();
WATCHDOG_DISABLE;
while(1){
gpio_write(GPIO_LED, 1);
sleep_us(200000);
gpio_write(GPIO_LED, 0);
sleep_us(200000);
}
#endif
}
gpio_set_output_en(GPIO_LED, 0);
#endif
}
enum{
OTA_SUCCESS = 0, //success
OTA_PACKET_LOSS, //lost one or more OTA PDU
OTA_DATA_CRC_ERR, //data CRC err
OTA_WRITE_FLASH_ERR, //write OTA data to flash ERR
OTA_DATA_UNCOMPLETE, //lost last one or more OTA PDU
OTA_TIMEOUT, //
OTA_FW_CHECK_ERR,
};