@@ -128,7 +128,7 @@ static uint32_t calculate_crc32(uint32_t addr, uint32_t len)
* 形 参: cur_version:当前版本号,new_version:生成的新版本号
* 返 回 值: 0:生成成功,-1:生成失败
* 说 明: 为保持一致,平台通过OTA传输而来的版本号也要保持这样三段式的形式
版本形式为major.minor.patch,如01.02.03
版本形式为major.minor.patch,如0 01.0 02.0 03
*******************************************************************************/
static int create_version ( uint8_t * cur_version , uint8_t * new_version )
{
@@ -739,8 +739,224 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHE
# define FRAME_LEN 2048 //每帧数据的数据包长度
static uint8_t MqttRxbuf [ 3072 ] ;
static uint8_t FrameBuf [ FRAME_LEN ] ;
static OTA_TCB AliOTA ;
static OTA_TCB platform_ota ;
# ifdef XIUOS_PLATFORM
/*******************************************************************************
* 函 数 名: PropertyVersion
* 功能描述: 向服务器上传当前设备版本信息
* 形 参: 无
* 返 回 值: 无
*******************************************************************************/
static void PropertyVersion ( void )
{
uint8_t tempdatabuff [ 128 ] ;
ota_info_t ota_info ;
memset ( & ota_info , 0 , sizeof ( ota_info_t ) ) ;
mcuboot . op_flash_read ( FLAG_FLAH_ADDRESS , ( void * ) & ota_info , sizeof ( ota_info_t ) ) ;
memset ( tempdatabuff , 0 , 128 ) ;
sprintf ( tempdatabuff , " { \" clientId \" : \" %s \" , \" version \" : \" %s \" } " , CLIENTID , ota_info . os . version ) ;
MQTT_PublishDataQs1 ( " xiuosiot/ota/version " , tempdatabuff , strlen ( tempdatabuff ) ) ; //发送等级QS=1的PUBLISH报文
}
/*-------------------------------------------------*/
/*函数名:OTA下载数据 */
/*参 数:size:本次下载量 */
/*参 数:offset:本次下载偏移量 */
/*返回值:无 */
/*-------------------------------------------------*/
static void OTA_Download ( int size , int offset )
{
uint8_t tempdatabuff [ 128 ] ;
memset ( tempdatabuff , 0 , 128 ) ;
sprintf ( tempdatabuff , " { \" clientId \" : \" %s \" , \" fileId \" :%d, \" fileOffset \" :%d, \" size \" :%d} " , Platform_mqtt . ClientID , platform_ota . streamId , offset , size ) ;
MQTT_PublishDataQs0 ( " xiuosiot/ota/files " , tempdatabuff , strlen ( tempdatabuff ) ) ;
}
/*******************************************************************************
* 函 数 名: app_ota_by_platform
* 功能描述: 通过云平台MQTT进行升级
* 形 参: 无
* 返 回 值: 无
*******************************************************************************/
static void app_ota_by_platform ( void * parameter )
{
int datalen ;
int ret = 0 ;
int freecnt = 0 ;
ota_info_t ota_info ;
uint32_t heart_time = 0 ;
uint32_t flashdestination = DOWN_FLAH_ADDRESS ;
uint8_t topicdatabuff [ 2 ] [ 64 ] ;
char * ptr ;
mcuboot . flash_init ( ) ;
memset ( & ota_info , 0 , sizeof ( ota_info_t ) ) ;
mcuboot . op_flash_read ( FLAG_FLAH_ADDRESS , ( void * ) & ota_info , sizeof ( ota_info_t ) ) ;
ota_info . status = OTA_STATUS_DOWNLOADING ;
UpdateOTAFlag ( & ota_info ) ;
memset ( topicdatabuff , 0 , sizeof ( topicdatabuff ) ) ;
sprintf ( topicdatabuff [ 0 ] , " ota/%s/update " , CLIENTID ) ;
sprintf ( topicdatabuff [ 1 ] , " ota/%s/files " , CLIENTID ) ;
reconnect :
if ( ( AdapterNetActive ( ) = = 0 ) & & ( MQTT_Connect ( ) = = 0 ) & & MQTT_SubscribeTopic ( topicdatabuff [ 0 ] ) = = 0 & & MQTT_SubscribeTopic ( topicdatabuff [ 1 ] ) = = 0 )
{
KPrintf ( " Log in to the cloud platform and subscribe to the topic successfully. \n " ) ;
PropertyVersion ( ) ;
}
else
{
KPrintf ( " Log in to the cloud platform failed, retry! \n " ) ;
goto reconnect ;
}
while ( 1 )
{
memset ( MqttRxbuf , 0 , sizeof ( MqttRxbuf ) ) ;
datalen = MQTT_Recv ( MqttRxbuf , sizeof ( MqttRxbuf ) ) ;
if ( datalen < = 0 )
{
freecnt + + ;
}
else if ( MqttRxbuf [ 0 ] = = 0x30 )
{
freecnt = 0 ;
MQTT_DealPublishData ( MqttRxbuf , datalen ) ;
ptr = strstr ( ( char * ) Platform_mqtt . cmdbuff , topicdatabuff [ 0 ] ) ;
if ( ptr ! = NULL )
{
if ( sscanf ( ptr + strlen ( topicdatabuff [ 0 ] ) + 1 , " { \" fileSize \" :%d, \" version \" : \" %11s \" , \" fileId \" :%d, \" md5 \" : \" %*32s \" } " , & platform_ota . size , platform_ota . version , & platform_ota . streamId ) = = 3 )
{
KPrintf ( " ota file size:%d \r \n " , platform_ota . size ) ;
KPrintf ( " ota file id:%d \r \n " , platform_ota . streamId ) ;
KPrintf ( " ota file version:%s \r \n " , platform_ota . version ) ;
if ( mcuboot . op_flash_erase ( DOWN_FLAH_ADDRESS , platform_ota . size ) ! = kStatus_Success )
{
KPrintf ( " Failed to erase target fash! \n " ) ;
ret = - 1 ;
break ;
}
platform_ota . counter = ( platform_ota . size % FRAME_LEN ! = 0 ) ? ( platform_ota . size / FRAME_LEN + 1 ) : ( platform_ota . size / FRAME_LEN ) ;
platform_ota . num = 1 ; //下载次数,初始值为1
platform_ota . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
else
{
KPrintf ( " Failed to get ota information! \n " ) ;
ret = - 1 ;
break ;
}
}
if ( strstr ( ( char * ) Platform_mqtt . cmdbuff , topicdatabuff [ 1 ] ) )
{
memset ( FrameBuf , 0 , sizeof ( FrameBuf ) ) ;
memcpy ( FrameBuf , & MqttRxbuf [ datalen - platform_ota . downlen ] , platform_ota . downlen ) ;
if ( mcuboot . op_flash_write ( flashdestination , FrameBuf , platform_ota . downlen ) ! = kStatus_Success )
{
KPrintf ( " current frame[%d] flash failed. \n " , platform_ota . num - 1 ) ;
ret = - 1 ;
break ;
}
else
{
KPrintf ( " current frame[%d] is written to flash 0x%x address successful. \n " , platform_ota . num - 1 , flashdestination ) ;
KPrintf ( " Current progress is %d/%d \r \n " , platform_ota . num , platform_ota . counter ) ;
flashdestination + = platform_ota . downlen ;
platform_ota . num + + ;
}
if ( platform_ota . num < platform_ota . counter ) //如果小于总下载次数
{
platform_ota . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
else if ( platform_ota . num = = platform_ota . counter ) //如果等于总下载次数,说明是最后一次下载
{
if ( platform_ota . size % FRAME_LEN = = 0 ) //判断固件大小是否是FRAME_LEN的整数倍
{
platform_ota . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
else
{
platform_ota . downlen = platform_ota . size % FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
}
else //下载完毕
{
ret = 0 ;
break ;
}
}
}
else
{
freecnt = 0 ;
continue ;
}
if ( ( freecnt > = 10 ) & & ( CalculateTimeMsFromTick ( CurrentTicksGain ( ) ) - heart_time > = HEART_TIME ) ) //连续10次未收到数据默认为为空闲状态,需每隔一段时间发送需要发送心跳包保活
{
heart_time = CalculateTimeMsFromTick ( CurrentTicksGain ( ) ) ;
if ( MQTT_SendHeart ( ) ! = 0 ) //发送心跳包失败可能连接断开,需要重连
{
KPrintf ( " The connection has been disconnected, reconnecting! \n " ) ;
freecnt = 0 ;
heart_time = 0 ;
goto reconnect ;
}
KPrintf ( " Send heartbeat packet successful! \n " ) ;
}
}
if ( 0 = = ret )
{
ota_info . down . size = platform_ota . size ;
ota_info . down . crc32 = calculate_crc32 ( DOWN_FLAH_ADDRESS , platform_ota . size ) ;
memset ( ota_info . down . version , 0 , sizeof ( ota_info . down . version ) ) ;
strncpy ( ota_info . down . version , platform_ota . version , sizeof ( ota_info . down . version ) ) ;
memset ( ota_info . down . description , 0 , sizeof ( ota_info . down . description ) ) ;
strncpy ( ota_info . down . description , " MQTT OTA bin. " , sizeof ( ota_info . down . description ) ) ;
ota_info . status = OTA_STATUS_READY ;
memset ( ota_info . error_message , 0 , sizeof ( ota_info . error_message ) ) ;
strncpy ( ota_info . error_message , " No error message! " , sizeof ( ota_info . error_message ) ) ;
UpdateOTAFlag ( & ota_info ) ;
}
else
{
ota_info . status = OTA_STATUS_ERROR ;
memset ( ota_info . error_message , 0 , sizeof ( ota_info . error_message ) ) ;
strncpy ( ota_info . error_message , " Failed to download firmware to download partition! " , sizeof ( ota_info . error_message ) ) ;
UpdateOTAFlag ( & ota_info ) ;
}
MQTT_UnSubscribeTopic ( topicdatabuff [ 0 ] ) ;
MQTT_UnSubscribeTopic ( topicdatabuff [ 1 ] ) ;
MQTT_Disconnect ( ) ;
mcuboot . flash_deinit ( ) ;
KPrintf ( " ota file transfer complete,start reboot! \n " ) ;
MdelayKTask ( 2000 ) ;
mcuboot . op_reset ( ) ;
}
# endif
# ifdef ALIBABA_PLATFORM
/*******************************************************************************
* 函 数 名: PropertyVersion
* 功能描述: 向服务器上传当前设备版本信息
@@ -768,11 +984,11 @@ static void PropertyVersion(void)
/*-------------------------------------------------*/
/*函数名:OTA下载数据 */
/*参 数:size: 本次下载量 */
/*参 数:offset: 本次下载偏移量 */
/*参 数:size: 本次下载量 */
/*参 数:offset: 本次下载偏移量 */
/*返回值:无 */
/*-------------------------------------------------*/
void OTA_Download ( int size , int offset )
static void OTA_Download ( int size , int offset )
{
uint8_t topicdatabuff [ 64 ] ;
uint8_t tempdatabuff [ 128 ] ;
@@ -781,7 +997,7 @@ void OTA_Download(int size, int offset)
sprintf ( topicdatabuff , " /sys/%s/%s/thing/file/download " , PLATFORM_PRODUCTKEY , CLIENT_DEVICENAME ) ;
memset ( tempdatabuff , 0 , 128 ) ;
sprintf ( tempdatabuff , " { \" id \" : \" 1 \" , \" params \" : { \" fileInfo \" :{ \" streamId \" :%d, \" fileId \" :1}, \" fileBlock \" :{ \" size \" :%d, \" offset \" :%d}}} " , AliOTA . streamId , size , offset ) ;
sprintf ( tempdatabuff , " { \" id \" : \" 1 \" , \" params \" : { \" fileInfo \" :{ \" streamId \" :%d, \" fileId \" :1}, \" fileBlock \" :{ \" size \" :%d, \" offset \" :%d}}} " , platform_ota . streamId , size , offset ) ;
MQTT_PublishDataQs0 ( topicdatabuff , tempdatabuff , strlen ( tempdatabuff ) ) ;
}
@@ -838,21 +1054,21 @@ reconnect:
ptr = strstr ( ( char * ) Platform_mqtt . cmdbuff , " { \" code \" : \" 1000 \" " ) ;
if ( ptr ! = NULL )
{
if ( sscanf ( ptr , " { \" code \" : \" 1000 \" , \" data \" :{ \" size \" :%d, \" streamId \" :%d, \" sign \" : \" %*32s \" , \" dProtocol \" : \" mqtt \" , \" version \" : \" %11s \" " , & AliOTA . size , & AliOTA . streamId , AliOTA . version ) = = 3 )
if ( sscanf ( ptr , " { \" code \" : \" 1000 \" , \" data \" :{ \" size \" :%d, \" streamId \" :%d, \" sign \" : \" %*32s \" , \" dProtocol \" : \" mqtt \" , \" version \" : \" %11s \" " , & platform_ota . size , & platform_ota . streamId , platform_ota . version ) = = 3 )
{
KPrintf ( " ota file size:%d \r \n " , AliOTA . size ) ;
KPrintf ( " ota file id:%d \r \n " , AliOTA . streamId ) ;
KPrintf ( " ota file version:%s \r \n " , AliOTA . version ) ;
if ( mcuboot . op_flash_erase ( DOWN_FLAH_ADDRESS , AliOTA . size ! = kStatus_Success ) )
KPrintf ( " ota file size:%d \r \n " , platform_ota . size ) ;
KPrintf ( " ota file id:%d \r \n " , platform_ota . streamId ) ;
KPrintf ( " ota file version:%s \r \n " , platform_ota . version ) ;
if ( mcuboot . op_flash_erase ( DOWN_FLAH_ADDRESS , platform_ota . size ) ! = kStatus_Success )
{
KPrintf ( " Failed to erase target fash! \n " ) ;
ret = - 1 ;
break ;
}
AliOTA . counter = ( AliOTA . size % FRAME_LEN ! = 0 ) ? ( AliOTA . size / FRAME_LEN + 1 ) : ( AliOTA . size / FRAME_LEN ) ;
AliOTA . num = 1 ; //下载次数,初始值为1
AliOTA . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( AliOTA . downlen , ( AliOTA . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
platform_ota . counter = ( platform_ota . size % FRAME_LEN ! = 0 ) ? ( platform_ota . size / FRAME_LEN + 1 ) : ( platform_ota . size / FRAME_LEN ) ;
platform_ota . num = 1 ; //下载次数,初始值为1
platform_ota . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
else
{
@@ -865,37 +1081,37 @@ reconnect:
if ( strstr ( ( char * ) Platform_mqtt . cmdbuff , " download_reply " ) )
{
memset ( FrameBuf , 0 , sizeof ( FrameBuf ) ) ;
memcpy ( FrameBuf , & MqttRxbuf [ datalen - AliOTA . downlen - 2 ] , AliOTA . downlen ) ;
if ( mcuboot . op_flash_write ( flashdestination , FrameBuf , AliOTA . downlen ) ! = kStatus_Success )
memcpy ( FrameBuf , & MqttRxbuf [ datalen - platform_ota . downlen - 2 ] , platform_ota . downlen ) ;
if ( mcuboot . op_flash_write ( flashdestination , FrameBuf , platform_ota . downlen ) ! = kStatus_Success )
{
KPrintf ( " current frame[%d] flash failed. \n " , AliOTA . num - 1 ) ;
KPrintf ( " current frame[%d] flash failed. \n " , platform_ota . num - 1 ) ;
ret = - 1 ;
break ;
}
else
{
KPrintf ( " current frame[%d] is written to flash 0x%x address successful. \n " , AliOTA . num - 1 , flashdestination ) ;
KPrintf ( " Current progress is %d/%d \r \n " , AliOTA . num , AliOTA . counter ) ;
flashdestination + = AliOTA . downlen ;
AliOTA . num + + ;
KPrintf ( " current frame[%d] is written to flash 0x%x address successful. \n " , platform_ota . num - 1 , flashdestination ) ;
KPrintf ( " Current progress is %d/%d \r \n " , platform_ota . num , platform_ota . counter ) ;
flashdestination + = platform_ota . downlen ;
platform_ota . num + + ;
}
if ( AliOTA . num < AliOTA . counter ) //如果小于总下载次数
if ( platform_ota . num < platform_ota . counter ) //如果小于总下载次数
{
AliOTA . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( AliOTA . downlen , ( AliOTA . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
platform_ota . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
else if ( AliOTA . num = = AliOTA . counter ) //如果等于总下载次数,说明是最后一次下载
else if ( platform_ota . num = = platform_ota . counter ) //如果等于总下载次数,说明是最后一次下载
{
if ( AliOTA . size % FRAME_LEN = = 0 ) //判断固件大小是否是FRAME_LEN的整数倍
if ( platform_ota . size % FRAME_LEN = = 0 ) //判断固件大小是否是FRAME_LEN的整数倍
{
AliOTA . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( AliOTA . downlen , ( AliOTA . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
platform_ota . downlen = FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
else
{
AliOTA . downlen = AliOTA . size % FRAME_LEN ; //记录本次下载量
OTA_Download ( AliOTA . downlen , ( AliOTA . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
platform_ota . downlen = platform_ota . size % FRAME_LEN ; //记录本次下载量
OTA_Download ( platform_ota . downlen , ( platform_ota . num - 1 ) * FRAME_LEN ) ; //发送要下载的数据信息给服务器
}
}
@@ -929,11 +1145,11 @@ reconnect:
if ( 0 = = ret )
{
ota_info . down . size = AliOTA . size ;
ota_info . down . crc32 = calculate_crc32 ( DOWN_FLAH_ADDRESS , AliOTA . size ) ;
ota_info . down . size = platform_ota . size ;
ota_info . down . crc32 = calculate_crc32 ( DOWN_FLAH_ADDRESS , platform_ota . size ) ;
memset ( ota_info . down . version , 0 , sizeof ( ota_info . down . version ) ) ;
strncpy ( ota_info . down . version , AliOTA . version , sizeof ( ota_info . down . version ) ) ;
strncpy ( ota_info . down . version , platform_ota . version , sizeof ( ota_info . down . version ) ) ;
memset ( ota_info . down . description , 0 , sizeof ( ota_info . down . description ) ) ;
strncpy ( ota_info . down . description , " MQTT OTA bin. " , sizeof ( ota_info . down . description ) ) ;
@@ -959,6 +1175,7 @@ reconnect:
MdelayKTask ( 2000 ) ;
mcuboot . op_reset ( ) ;
}
# endif
int OtaTask ( void )
{