/*******************************************************************************
|
* File Name : OTA.c
|
* Description :
|
* Created on : 2020Äê9ÔÂ13ÈÕ
|
* Author : www.hido-studio.com
|
*******************************************************************************/
|
|
/*******************************************************************************
|
* Include Files *
|
*******************************************************************************/
|
#include "string.h"
|
#include "HIDO_TypeDef.h"
|
#include "HIDO_Timer.h"
|
#include "OTA.h"
|
#include "HIDO_Debug.h"
|
#include "HIDO_Timer.h"
|
#include "HIDO_Util.h"
|
#include "HTTPClient.h"
|
#include "Internet.h"
|
#include "mk_flash.h"
|
#include "mk_trace.h"
|
#include <global_param.h>
|
#include <serial_at_cmd_app.h>
|
/*******************************************************************************
|
* Macro *
|
*******************************************************************************/
|
#define MAX_REQUEST_SIZE (5 * 1024)
|
#define APP2_ADRESS 0x0402f000
|
#define APP_SIZE 0x04080000-APP2_ADRESS
|
|
/*******************************************************************************
|
* Type Definition *
|
*******************************************************************************/
|
typedef enum
|
{
|
OTA_STATE_IDLE,
|
OTA_STATE_HTTP_REQUEST_FILE_LEN,
|
OTA_STATE_HTTP_REQUEST_DATA,
|
OTA_STATE_WAIT_HTTP_RESPONSE,
|
}E_OTAState;
|
|
/*******************************************************************************
|
* Local Variable *
|
*******************************************************************************/
|
static HIDO_CHAR l_acOTAUrl[256];
|
static HIDO_UINT32 l_u32OTATimerID = 0;
|
static volatile E_OTAState l_eOTAState = OTA_STATE_IDLE;
|
static HIDO_UINT32 l_u32OTARetryCnt = 0;
|
static HIDO_UINT32 l_u32OTAFileRecvLen = 0;
|
static HIDO_UINT32 l_u32OTAFileSize = 0;
|
|
/*******************************************************************************
|
* Local Function Declaration *
|
*******************************************************************************/
|
static HIDO_VOID OTA_TimerCallBack(HIDO_VOID *_pArg);
|
static HIDO_INT32 OTA_HTTPGetFileCallBack(HIDO_UINT32 _u32RespCode, ST_HTTPGetFileResponse *_pstResponse,
|
HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len, HIDO_VOID *_pArg);
|
|
/*******************************************************************************
|
* Local Function *
|
*******************************************************************************/
|
|
/*******************************************************************************
|
* Function Name : OTA_RequestFileLen
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 OTA_RequestFileLen(HIDO_VOID)
|
{
|
ST_HTTPGetFileOpt stFileOpt;
|
|
memset(&stFileOpt, 0, sizeof(stFileOpt));
|
|
stFileOpt.m_u32RangeBegin = 0;
|
stFileOpt.m_u32RangeEnd = 0;
|
|
if (HTTPClient_GetFile(l_acOTAUrl, OTA_HTTPGetFileCallBack, &stFileOpt, HIDO_NULL) != HIDO_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : OTA_RequestFileData
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 OTA_RequestFileData(HIDO_UINT32 _u32Offset)
|
{
|
ST_HTTPGetFileOpt stFileOpt;
|
|
memset(&stFileOpt, 0, sizeof(stFileOpt));
|
|
stFileOpt.m_u32RangeBegin = _u32Offset;
|
if ((l_u32OTAFileSize - l_u32OTAFileRecvLen) < MAX_REQUEST_SIZE)
|
{
|
stFileOpt.m_u32RangeEnd = _u32Offset + l_u32OTAFileSize - l_u32OTAFileRecvLen - 1;
|
}
|
else
|
{
|
stFileOpt.m_u32RangeEnd = _u32Offset + MAX_REQUEST_SIZE - 1;
|
}
|
|
if(HTTPClient_GetFile(l_acOTAUrl, OTA_HTTPGetFileCallBack, &stFileOpt, HIDO_NULL) != HIDO_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : OTA_HTTPGetFileCallBack
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 OTA_HTTPGetFileCallBack(HIDO_UINT32 _u32RespCode, ST_HTTPGetFileResponse *_pstResponse,
|
HIDO_UINT8 *_pu8Data, HIDO_UINT32 _u32Len, HIDO_VOID *_pArg)
|
{
|
if (200 == _u32RespCode)
|
{
|
LOG_INFO(TRACE_MODULE_APP,"HTTPGetFileCallBack:200\r\n");
|
}
|
else if (206 == _u32RespCode)
|
{
|
switch (l_eOTAState)
|
{
|
case OTA_STATE_HTTP_REQUEST_FILE_LEN:
|
{
|
l_u32OTAFileRecvLen = 0;
|
l_u32OTAFileSize = _pstResponse->m_u32RangeTotal;
|
if(0 == l_u32OTAFileSize)
|
{
|
LOG_INFO(TRACE_MODULE_APP,"OTAFileSize error\r\n");
|
}
|
|
LOG_INFO(TRACE_MODULE_APP,"OTAFileSize %u\r\n", l_u32OTAFileSize);
|
|
l_eOTAState = OTA_STATE_HTTP_REQUEST_DATA;
|
OTA_RequestFileData(l_u32OTAFileRecvLen);
|
HIDO_TimerStart(l_u32OTATimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), OTA_TimerCallBack, HIDO_NULL);
|
break;
|
}
|
case OTA_STATE_HTTP_REQUEST_DATA:
|
{
|
if(_pstResponse->m_u32RangeBegin != l_u32OTAFileRecvLen)
|
{
|
break;
|
}
|
|
/* дÈëÎļþ */
|
#if 0
|
SPIFlash_Write(SPI_FLASH_ID_0, APP_CONFIG_APP_DOWN_LOAD_SPIFLASH_ADDRESS + l_u32OTAFileRecvLen, _pu8Data, _u32Len);
|
#else
|
flash_write_nbytes(FLASH_ID0, APP2_ADRESS + l_u32OTAFileRecvLen, _pu8Data, _u32Len);
|
#endif
|
l_u32OTAFileRecvLen += _u32Len;
|
LOG_INFO(TRACE_MODULE_APP,"OTAFileDownload %u/%u\r\n", l_u32OTAFileRecvLen, l_u32OTAFileSize);
|
|
/* Îļþ½ÓÊÕÍê³É */
|
if (l_u32OTAFileRecvLen == l_u32OTAFileSize)
|
{
|
l_eOTAState = OTA_STATE_IDLE;
|
HIDO_TimerCancel(l_u32OTATimerID);
|
|
// Ö´Ðе½ÕâÀÒѾÍê³ÉÎļþµÄÏÂÔØ£¬¿ÉÒÔÖ´ÐÐÏÂÒ»²½´¦ÀíÁË
|
//#if 0
|
// HIDO_UINT16 tmp = 0xBBBB,result;
|
// SPIFlash_Erase(SPI_FLASH_ID_0, APP_CONFIG_IAPFLAG_MAP,2, SPI_FLASH_SECTOR_ERASE_MODE_4K);
|
// SPIFlash_Write(SPI_FLASH_ID_0, APP_CONFIG_IAPFLAG_MAP, (HIDO_UINT8*)&tmp, sizeof(tmp));
|
//#endif
|
// HAL_Delay(10);
|
// Reboot(0);
|
uint32_t result = 0;
|
uint16_t tmp = 0xCCCC;
|
__disable_irq();
|
result = flash_open(FLASH_ID0,NULL);
|
if(!result)//´ò¿ª³É¹¦
|
flash_erase(FLASH_ID0,APP_CONFIG_IAPFLAG_SECTOR_ADDR,FLASH_SECTOR_SIZE);
|
result = flash_write_nbytes(FLASH_ID0,APP_CONFIG_IAPFLAG_MAP,(uint8_t*)&tmp,2);
|
__enable_irq();
|
Serial0PutString("½øÈëÉý¼¶Ä£Ê½\r\n");
|
g_com_map[CNT_UPDATE]=0;
|
save_com_map_to_flash();
|
delay_us(100000);
|
NVIC_SystemReset(); //Èí¸´Î»»Øµ½bootloader
|
break;
|
}
|
|
OTA_RequestFileData(l_u32OTAFileRecvLen);
|
HIDO_TimerStart(l_u32OTATimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), OTA_TimerCallBack, HIDO_NULL);
|
break;
|
}
|
default:
|
{
|
break;
|
}
|
}
|
}
|
else
|
{
|
// l_eOTAState = OTA_STATE_IDLE;
|
/* ÇëÇóʧ°Ü */
|
}
|
|
return HIDO_OK;
|
}
|
/*******************************************************************************
|
* Function Name : OTA_Failed
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
static HIDO_INT32 OTA_Failed(void)
|
{
|
/* Éý¼¶²ÎÊýÓÐÎó£¬È¡ÏûÉý¼¶ */
|
HIDO_UINT16 tmp = 0xFFFF;
|
|
// HIDO_Debug("goto app application\r\n");
|
|
// Ö´Ðе½ÕâÀ˵Ã÷ÎļþÏÂÔØÊ§°ÜÁË£¬ÐèÒª½øÒ»²½´¦Àí
|
#if 0
|
SPIFlash_Erase(SPI_FLASH_ID_0, APP_CONFIG_IAPFLAG_MAP, 2, SPI_FLASH_SECTOR_ERASE_MODE_4K);
|
SPIFlash_Write(SPI_FLASH_ID_0, APP_CONFIG_IAPFLAG_MAP, (HIDO_UINT8*)&tmp, sizeof(tmp));
|
SPIFlash_Erase(SPI_FLASH_ID_0, APP_CONFIG_IAP_PARAM_MAP, 256, SPI_FLASH_SECTOR_ERASE_MODE_4K);
|
#endif
|
// g_com_map[OTA_FLAG]=0;
|
// save_com_map_to_flash();
|
// delay_us(100000);
|
NVIC_SystemReset(); //Èí¸´Î»»Øµ½bootloader
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : OTA_TimerCallBack
|
* Description : OTA¶¨Ê±Æ÷³¬Ê±»Øµ÷
|
* Input : ¶¨Ê±Æ÷²ÎÊý
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
static HIDO_VOID OTA_TimerCallBack(HIDO_VOID *_pArg)
|
{
|
LOG_INFO(TRACE_MODULE_APP,"l_eOTAState = %u @%s\r\n", l_eOTAState, __FUNCTION__);
|
|
switch (l_eOTAState)
|
{
|
case OTA_STATE_HTTP_REQUEST_FILE_LEN:
|
{
|
l_u32OTARetryCnt++;
|
if(l_u32OTARetryCnt >= 3)
|
{
|
OTA_Failed();
|
}
|
|
OTA_RequestFileLen();
|
HIDO_TimerStart(l_u32OTATimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), OTA_TimerCallBack, HIDO_NULL);
|
break;
|
}
|
case OTA_STATE_HTTP_REQUEST_DATA:
|
{
|
l_u32OTARetryCnt++;
|
if(l_u32OTARetryCnt >= 3)
|
{
|
OTA_Failed();
|
}
|
|
OTA_RequestFileData(l_u32OTAFileRecvLen);
|
HIDO_TimerStart(l_u32OTATimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), OTA_TimerCallBack, HIDO_NULL);
|
break;
|
}
|
default:
|
{
|
break;
|
}
|
}
|
}
|
|
/*******************************************************************************
|
* Global Function *
|
*******************************************************************************/
|
|
/*******************************************************************************
|
* Function Name : OTA_SetUp
|
* Description : OTAÆô¶¯
|
* Input : _pcUrl OTAÉý¼¶Îļþ·¾¶
|
* Output : None
|
* Return : HIDO_OK ³É¹¦,HIDO_ERR ʧ°Ü
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 OTA_SetUp(HIDO_CHAR *_pcUrl)
|
{
|
if(HIDO_NULL == _pcUrl)
|
{
|
return HIDO_ERR;
|
}
|
|
if(l_eOTAState != OTA_STATE_IDLE)
|
{
|
return HIDO_ERR;
|
}
|
|
/* ³õʼ»¯²ÎÊý */
|
l_u32OTARetryCnt = 0;
|
l_u32OTAFileSize = 0;
|
l_u32OTAFileRecvLen = 0;
|
HIDO_UtilSnprintf(l_acOTAUrl, sizeof(l_acOTAUrl), _pcUrl);
|
|
/* ²Á³ýOTAÎļþ»º´æ´æ´¢¿Õ¼ä */
|
#if 0
|
SPIFlash_Erase(SPI_FLASH_ID_0, APP_CONFIG_APP_DOWN_LOAD_SPIFLASH_ADDRESS,
|
APP_CONFIG_APP_DOWN_LOAD_SPIFLASH_SIZE, SPI_FLASH_SECTOR_ERASE_MODE_64K);
|
#else
|
flash_erase(FLASH_ID0,APP2_ADRESS,APP_SIZE);
|
#endif
|
/* ÇëÇóÉý¼¶Îļþ³¤¶È */
|
if(OTA_RequestFileLen() != HIDO_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
l_eOTAState = OTA_STATE_HTTP_REQUEST_FILE_LEN;
|
HIDO_TimerStart(l_u32OTATimerID, HIDO_TIMER_TYPE_ONCE, HIDO_TIMER_TICK_S(30), OTA_TimerCallBack, HIDO_NULL);
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : OTA_Cancel
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 OTA_Cancel(HIDO_VOID)
|
{
|
HIDO_TimerCancel(l_u32OTATimerID);
|
l_eOTAState = OTA_STATE_IDLE;
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : OTA_Poll
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 OTA_Poll(void)
|
{
|
if(Internet_IsIPReady() != HIDO_TRUE)
|
{
|
return HIDO_ERR;
|
}
|
|
if(l_eOTAState == OTA_STATE_IDLE)
|
{
|
OTA_SetUp(l_acOTAUrl);
|
}
|
|
return HIDO_OK;
|
}
|
|
/*******************************************************************************
|
* Function Name : OTA_Start
|
* Description :
|
* Input :
|
* Output :
|
* Return :
|
* Author : www.hido-studio.com
|
* Modified Date: : 2020Äê9ÔÂ13ÈÕ
|
*******************************************************************************/
|
HIDO_INT32 OTA_Start(HIDO_CHAR *_pcUrl)
|
{
|
l_eOTAState = OTA_STATE_IDLE;
|
HIDO_TimerCreate(&l_u32OTATimerID);
|
|
OTA_SetUp(_pcUrl);
|
|
return HIDO_OK;
|
}
|