mirror of
https://github.com/pvvx/RTL00MP3.git
synced 2025-01-26 11:05:18 +00:00
update
This commit is contained in:
parent
5cd34b0c9f
commit
fd4c492ea4
6 changed files with 1001 additions and 5 deletions
|
@ -6,10 +6,15 @@
|
|||
******************************************************************************/
|
||||
#include <platform_opts.h>
|
||||
#include "main.h"
|
||||
#include "freertos_pmu.h"
|
||||
|
||||
#if ATCMD_VER == ATVER_2
|
||||
#include "flash_api.h"
|
||||
#include "device_lock.h"
|
||||
#ifdef USE_FLASH_EEP
|
||||
#include "flash_eep.h"
|
||||
#include "feep_config.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_MDNS
|
||||
|
@ -189,15 +194,19 @@
|
|||
*/
|
||||
void pre_example_entry(void)
|
||||
{
|
||||
#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT
|
||||
#if ATCMD_VER == ATVER_2
|
||||
flash_t flash;
|
||||
struct wlan_fast_reconnect read_data = {0};
|
||||
#ifdef USE_FLASH_EEP
|
||||
flash_read_cfg(data, FEEP_ID_WIFI_CFG, sizeof(struct wlan_fast_reconnect));
|
||||
#else
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data);
|
||||
flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(read_data), (u8 *) &read_data);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT
|
||||
#if ATCMD_VER == ATVER_2
|
||||
if(read_data.enable == 1)
|
||||
#endif
|
||||
|
|
|
@ -117,5 +117,7 @@ void set_pll_reserved(unsigned char reserve);
|
|||
#define pmu_release_wakelock release_wakelock
|
||||
#define pmu_acquire_wakelock acquire_wakelock
|
||||
#define pmu_get_wakelock_status get_wakelock_status
|
||||
#define pmu_set_pll_reserved set_pll_reserved
|
||||
#define pmu_enable_wakelock_stats
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
*
|
||||
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This module is a confidential and proprietary property of RealTek and
|
||||
* possession or use of this module requires written permission of RealTek.
|
||||
*/
|
||||
#ifndef _HAL_API_H_
|
||||
#define _HAL_API_H_
|
||||
|
@ -32,7 +30,7 @@
|
|||
#define HAL_WRITE8(base, addr, value) \
|
||||
((*((volatile u8*)(base + addr))) = value)
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
// These "extern _LONG_CALL_" function declaration are for RAM code building only
|
||||
// For ROM code building, thses code should be marked off
|
||||
extern _LONG_CALL_ u8
|
||||
|
@ -86,6 +84,49 @@ extern _LONG_CALL_ VOID
|
|||
VectorIrqDisRtl8195A(
|
||||
IN PIRQ_HANDLE pIrqHandle
|
||||
);
|
||||
|
||||
extern _LONG_CALL_ int HalUart0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalUart1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalUart2PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSPI0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSPI1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSPI2PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSPI0MCSPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalI2C0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalI2C1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalI2C2PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalI2C3PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalI2S0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalI2S1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalPCM0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalPCM1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSDIODPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSDIOHPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalMIIPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalWLLEDPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalWLANT0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalWLANT1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalWLBTCOEXPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalWLBTCMDPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalNFCPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalPWM0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalPWM1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalPWM2PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalPWM3PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalETE0PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalETE1PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalETE2PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalETE3PinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalEGTIMPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSPIFlashPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSDRPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalJTAGPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalTRACEPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalLOGUartPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalLOGUartIRPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalSICPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalEEPROMPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
extern _LONG_CALL_ int HalDEBUGPinCtrlRtl8195A(IN u32 PinLocation, IN BOOL Operation);
|
||||
#endif
|
||||
|
||||
extern BOOLEAN SpicFlashInitRtl8195A(u8 SpicBitMode);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/**************************************************
|
||||
* malloc/free/realloc wrap for gcc compiler
|
||||
*
|
||||
**************************************************/
|
||||
#if defined(__GNUC__)
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
void* __wrap_malloc( size_t size )
|
||||
{
|
||||
return pvPortMalloc(size);
|
||||
}
|
||||
|
||||
void* __wrap_realloc( void *p, size_t size )
|
||||
{
|
||||
return pvPortReAalloc(p, size);
|
||||
}
|
||||
|
||||
void __wrap_free( void *p )
|
||||
{
|
||||
vPortFree(p);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,825 @@
|
|||
#include <sys.h>
|
||||
#include <device_lock.h>
|
||||
#include "ota_8195a.h"
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
sys_thread_t TaskOTA = NULL;
|
||||
#define STACK_SIZE 1024
|
||||
#define TASK_PRIORITY tskIDLE_PRIORITY + 1
|
||||
#if SWAP_UPDATE
|
||||
static uint32_t OldImg2Addr;
|
||||
#endif
|
||||
static flash_t flash_ota;
|
||||
|
||||
#if CONFIG_CUSTOM_SIGNATURE
|
||||
/* ---------------------------------------------------
|
||||
* Customized Signature
|
||||
* ---------------------------------------------------*/
|
||||
// This signature can be used to verify the correctness of the image
|
||||
// It will be located in fixed location in application image
|
||||
#include "section_config.h"
|
||||
SECTION(".custom.validate.rodata")
|
||||
const unsigned char cus_sig_demo[32] = "Customer Signature-modelxxx";
|
||||
#endif
|
||||
|
||||
void* update_malloc(unsigned int size){
|
||||
return pvPortMalloc(size);
|
||||
}
|
||||
|
||||
void update_free(void *buf){
|
||||
vPortFree(buf);
|
||||
}
|
||||
|
||||
void ota_platform_reset(void){
|
||||
// Set processor clock to default before system reset
|
||||
HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021);
|
||||
osDelay(100);
|
||||
|
||||
// Cortex-M3 SCB->AIRCR
|
||||
HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY
|
||||
(HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP
|
||||
(1 << 2)); // SYSRESETREQ
|
||||
while(1) osDelay(1000);
|
||||
}
|
||||
|
||||
#if WRITE_OTA_ADDR
|
||||
int write_ota_addr_to_system_data(flash_t *flash, uint32_t ota_addr)
|
||||
{
|
||||
uint32_t data, i = 0;
|
||||
//Get upgraded image 2 addr from offset
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_read_word(flash, OFFSET_DATA, &data);
|
||||
printf("\n\r[%s] data 0x%x ota_addr 0x%x", __FUNCTION__, data, ota_addr);
|
||||
if(~0x0 == data){
|
||||
flash_write_word(flash, OFFSET_DATA, ota_addr);
|
||||
}
|
||||
else{
|
||||
//erase backup sector
|
||||
flash_erase_sector(flash, BACKUP_SECTOR);
|
||||
//backup system data to backup sector
|
||||
for(i = 0; i < 0x1000; i+= 4){
|
||||
flash_read_word(flash, OFFSET_DATA + i, &data);
|
||||
if(0 == i)
|
||||
data = ota_addr;
|
||||
flash_write_word(flash, BACKUP_SECTOR + i,data);
|
||||
}
|
||||
//erase system data
|
||||
flash_erase_sector(flash, OFFSET_DATA);
|
||||
//write data back to system data
|
||||
for(i = 0; i < 0x1000; i+= 4){
|
||||
flash_read_word(flash, BACKUP_SECTOR + i, &data);
|
||||
flash_write_word(flash, OFFSET_DATA + i,data);
|
||||
}
|
||||
//erase backup sector
|
||||
flash_erase_sector(flash, BACKUP_SECTOR);
|
||||
}
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int update_ota_connect_server(int server_socket, update_cfg_local_t *cfg){
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(server_socket < 0){
|
||||
printf("\n\r[%s] Create socket failed", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = cfg->ip_addr;
|
||||
server_addr.sin_port = cfg->port;
|
||||
|
||||
if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){
|
||||
printf("\n\r[%s] Socket connect failed", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
uint32_t update_ota_prepare_addr(void){
|
||||
|
||||
uint32_t Img2Len = 0;
|
||||
uint32_t IMAGE_x = 0, ImgxLen = 0, ImgxAddr = 0;
|
||||
uint32_t NewImg2Addr = 0;
|
||||
#if WRITE_OTA_ADDR
|
||||
uint32_t ota_addr = 0x80000;
|
||||
#endif
|
||||
|
||||
DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_);
|
||||
// The upgraded image2 pointer must 4K aligned and should not overlap with Default Image2
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_read_word(&flash_ota, IMAGE_2, &Img2Len);
|
||||
IMAGE_x = IMAGE_2 + Img2Len + 0x10;
|
||||
flash_read_word(&flash_ota, IMAGE_x, &ImgxLen);
|
||||
flash_read_word(&flash_ota, IMAGE_x+4, &ImgxAddr);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
|
||||
if(0x30000000 == ImgxAddr){
|
||||
printf("\n\r[%s] IMAGE_3 0x%x Img3Len 0x%x", __FUNCTION__, IMAGE_x, ImgxLen);
|
||||
}
|
||||
else{
|
||||
printf("\n\r[%s] There is no IMAGE_3", __FUNCTION__);
|
||||
IMAGE_x = IMAGE_2;
|
||||
ImgxLen = Img2Len;
|
||||
}
|
||||
#if WRITE_OTA_ADDR
|
||||
if((ota_addr > IMAGE_x) && ((ota_addr < (IMAGE_x+ImgxLen))) || (ota_addr < IMAGE_x) ||
|
||||
((ota_addr & 0xfff) != 0) || (ota_addr == ~0x0)){
|
||||
printf("\n\r[%s] illegal ota addr 0x%x", __FUNCTION__, ota_addr);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
write_ota_addr_to_system_data(&flash_ota, ota_addr);
|
||||
#endif
|
||||
|
||||
//Get upgraded image 2 addr from offset
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_read_word(&flash_ota, OFFSET_DATA, &NewImg2Addr);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
if((NewImg2Addr > IMAGE_x) && ((NewImg2Addr < (IMAGE_x+ImgxLen))) || (NewImg2Addr < IMAGE_x) ||
|
||||
((NewImg2Addr & 0xfff) != 0) || (NewImg2Addr == ~0x0)){
|
||||
printf("\n\r[%s] Invalid OTA Address 0x%x", __FUNCTION__, NewImg2Addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return NewImg2Addr;
|
||||
}
|
||||
|
||||
#if SWAP_UPDATE
|
||||
uint32_t update_ota_swap_addr(uint32_t img_len, uint32_t NewImg2Addr){
|
||||
uint32_t SigImage0,SigImage1;
|
||||
uint32_t Part1Addr=0xFFFFFFFF, Part2Addr=0xFFFFFFFF;
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_read_word(&flash_ota, 0x18, &Part1Addr);
|
||||
Part1Addr = (Part1Addr&0xFFFF)*1024; //PART1 : 0x0000B000
|
||||
Part2Addr = NewImg2Addr; //PART2 : 0x00080000
|
||||
|
||||
// read Part1 signature
|
||||
flash_read_word(&flash_ota, Part1Addr+8, &SigImage0);
|
||||
flash_read_word(&flash_ota, Part1Addr+12, &SigImage1);
|
||||
printf("\n\r[%s] Part1 Sig %x", __FUNCTION__, SigImage0);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
if(SigImage0==0x35393138 && SigImage1==0x31313738)//Part1 is the new one with signature "81958711"
|
||||
OldImg2Addr = Part1Addr; //Change Part1 to older version
|
||||
else{
|
||||
// read Part2 signature
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_read_word(&flash_ota, Part2Addr+8, &SigImage0);
|
||||
flash_read_word(&flash_ota, Part2Addr+12, &SigImage1);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
printf("\n\r[%s] Part2 Sig %x", __FUNCTION__, SigImage0);
|
||||
if(SigImage0==0x30303030 && SigImage1==0x30303030){// ATSC signature "00000000"
|
||||
OldImg2Addr = Part1Addr; //Store the new version to Part2
|
||||
}
|
||||
else if(SigImage0==0x35393138 && SigImage1==0x31313738){//Part2 is the new one with signature "81958711"
|
||||
OldImg2Addr = Part2Addr; //Change Part2 to older version
|
||||
NewImg2Addr = Part1Addr;
|
||||
if( img_len > (Part2Addr-Part1Addr) ){ // firmware size too large
|
||||
printf("\n\r[%s] Part1 size < OTA size", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
NewImg2Addr = Part2Addr;
|
||||
}
|
||||
|
||||
printf("\n\r[%s] New %x, Old %x", __FUNCTION__, NewImg2Addr, OldImg2Addr);
|
||||
return NewImg2Addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
int update_ota_erase_upg_region(uint32_t img_len, uint32_t NewImg2Len, uint32_t NewImg2Addr){
|
||||
uint32_t NewImg2BlkSize = 0;
|
||||
|
||||
if(NewImg2Len == 0){
|
||||
NewImg2Len = img_len;
|
||||
printf("\n\r[%s] NewImg2Len %d ", __FUNCTION__, NewImg2Len);
|
||||
if((int)NewImg2Len > 0){
|
||||
NewImg2BlkSize = ((NewImg2Len - 1)/4096) + 1;
|
||||
printf("\n\r[%s] NewImg2BlkSize %d 0x%8x", __FUNCTION__, NewImg2BlkSize, NewImg2BlkSize);
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
for(int i = 0; i < NewImg2BlkSize; i++)
|
||||
flash_erase_sector(&flash_ota, NewImg2Addr + i * 4096);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
}else{
|
||||
printf("\n\r[%s] Size INVALID", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n\r[%s] NewImg2Addr 0x%x", __FUNCTION__, NewImg2Addr);
|
||||
return NewImg2Len;
|
||||
}
|
||||
|
||||
int update_ota_checksum(_file_checksum *file_checksum, uint32_t flash_checksum, uint32_t NewImg2Addr){
|
||||
|
||||
#if CONFIG_CUSTOM_SIGNATURE
|
||||
char custom_sig[32] = "Customer Signature-modelxxx";
|
||||
uint32_t read_custom_sig[8];
|
||||
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
for(int i = 0; i < 8; i ++){
|
||||
flash_read_word(&flash_ota, NewImg2Addr + 0x28 + i *4, read_custom_sig + i);
|
||||
}
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
printf("\n\r[%s] read_custom_sig %s", __FUNCTION__ , (char*)read_custom_sig);
|
||||
#endif
|
||||
|
||||
printf("\n\rflash checksum 0x%8x attached checksum 0x%8x", flash_checksum, file_checksum->u);
|
||||
|
||||
// compare checksum with received checksum
|
||||
if( (file_checksum->u == flash_checksum)
|
||||
#if CONFIG_CUSTOM_SIGNATURE
|
||||
&& !strcmp((char*)read_custom_sig,custom_sig)
|
||||
#endif
|
||||
){
|
||||
//Set signature in New Image 2 addr + 8 and + 12
|
||||
uint32_t sig_readback0,sig_readback1;
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_write_word(&flash_ota,NewImg2Addr + 8, 0x35393138);
|
||||
flash_write_word(&flash_ota,NewImg2Addr + 12, 0x31313738);
|
||||
flash_read_word(&flash_ota, NewImg2Addr + 8, &sig_readback0);
|
||||
flash_read_word(&flash_ota, NewImg2Addr + 12, &sig_readback1);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
printf("\n\r[%s] signature %x,%x", __FUNCTION__ , sig_readback0, sig_readback1);
|
||||
#if SWAP_UPDATE
|
||||
if(OldImg2Addr != ~0x0){
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_write_word(&flash_ota,OldImg2Addr + 8, 0x35393130);
|
||||
flash_write_word(&flash_ota,OldImg2Addr + 12, 0x31313738);
|
||||
flash_read_word(&flash_ota, OldImg2Addr + 8, &sig_readback0);
|
||||
flash_read_word(&flash_ota, OldImg2Addr + 12, &sig_readback1);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
printf("\n\r[%s] old signature %x,%x", __FUNCTION__ , sig_readback0, sig_readback1);
|
||||
}
|
||||
#endif
|
||||
printf("\n\r[%s] Update OTA success!", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void update_ota_local_task(void *param)
|
||||
{
|
||||
int server_socket;
|
||||
unsigned char *buf, *alloc;
|
||||
_file_checksum *file_checksum;
|
||||
int read_bytes = 0, size = 0, i = 0;
|
||||
update_cfg_local_t *cfg = (update_cfg_local_t *)param;
|
||||
uint32_t address, flash_checksum=0;
|
||||
uint32_t NewImg2Len = 0, NewImg2Addr = 0, file_info[3];
|
||||
int ret = -1 ;
|
||||
|
||||
printf("\n\r[%s] Update task start", __FUNCTION__);
|
||||
alloc = update_malloc(BUF_SIZE+4);
|
||||
if(!alloc){
|
||||
printf("\n\r[%s] Alloc buffer failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
buf = &alloc[4];
|
||||
file_checksum = (void*)alloc;
|
||||
|
||||
// Connect server
|
||||
server_socket = update_ota_connect_server(server_socket, cfg);
|
||||
if(server_socket == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
NewImg2Addr = update_ota_prepare_addr();
|
||||
if(NewImg2Addr == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
//Clear file_info
|
||||
memset(file_info, 0, sizeof(file_info));
|
||||
|
||||
if(file_info[0] == 0){
|
||||
printf("\n\r[%s] Read info first", __FUNCTION__);
|
||||
read_bytes = read(server_socket, file_info, sizeof(file_info));
|
||||
// !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X
|
||||
// !W checksum !W padding 0 !W file size !W
|
||||
// !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X
|
||||
printf("\n\r[%s] info %d bytes", __FUNCTION__, read_bytes);
|
||||
printf("\n\r[%s] tx chechsum 0x%x, file size 0x%x", __FUNCTION__, file_info[0],file_info[2]);
|
||||
if(file_info[2] == 0){
|
||||
printf("\n\r[%s] No checksum and file size", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
}
|
||||
|
||||
#if SWAP_UPDATE
|
||||
NewImg2Addr = update_ota_swap_addr(file_info[2], NewImg2Addr);
|
||||
if(NewImg2Addr == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
NewImg2Len = update_ota_erase_upg_region(file_info[2], NewImg2Len, NewImg2Addr);
|
||||
if(NewImg2Len == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
// reset
|
||||
file_checksum->u = 0;
|
||||
// Write New Image 2 sector
|
||||
if(NewImg2Addr != ~0x0){
|
||||
address = NewImg2Addr;
|
||||
printf("\n\rStart to read data %d bytes\r\n", NewImg2Len);
|
||||
while(1){
|
||||
memset(buf, 0, BUF_SIZE);
|
||||
read_bytes = read(server_socket, buf, BUF_SIZE);
|
||||
if(read_bytes == 0)
|
||||
break; // Read end
|
||||
if(read_bytes < 0){
|
||||
printf("\n\r[%s] Read socket failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
if(read_bytes<4)
|
||||
printf("\n\r[%s] Recv small packet", __FUNCTION__);
|
||||
printf(".");
|
||||
|
||||
if((size+read_bytes)>NewImg2Len){
|
||||
printf("\n\r[%s] Redundant bytes received", __FUNCTION__);
|
||||
read_bytes = NewImg2Len-size;
|
||||
}
|
||||
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
if(flash_stream_write(&flash_ota, address + size, read_bytes, buf) < 0){
|
||||
printf("\n\r[%s] Write stream failed", __FUNCTION__);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
size += read_bytes;
|
||||
|
||||
file_checksum->c[0] = alloc[4+read_bytes-4]; // checksum attached at file end
|
||||
file_checksum->c[1] = alloc[4+read_bytes-3];
|
||||
file_checksum->c[2] = alloc[4+read_bytes-2];
|
||||
file_checksum->c[3] = alloc[4+read_bytes-1];
|
||||
|
||||
if(size == NewImg2Len)
|
||||
break;
|
||||
}
|
||||
printf("\n\rRead data finished\r\n");
|
||||
|
||||
// read flash data back and calculate checksum
|
||||
for(i = 0; i < size-4; i += BUF_SIZE){
|
||||
int k;
|
||||
int rlen = (size-4-i) > BUF_SIZE ? BUF_SIZE : (size-4-i);
|
||||
flash_stream_read(&flash_ota, NewImg2Addr+i, rlen, buf);
|
||||
for(k = 0; k < rlen; k++)
|
||||
flash_checksum+=buf[k];
|
||||
}
|
||||
|
||||
ret = update_ota_checksum(file_checksum, flash_checksum, NewImg2Addr);
|
||||
if(ret == -1){
|
||||
printf("\r\nThe checksume is wrong!\r\n");
|
||||
goto update_ota_exit;
|
||||
}
|
||||
}
|
||||
update_ota_exit:
|
||||
if(alloc)
|
||||
update_free(alloc);
|
||||
if(server_socket >= 0)
|
||||
close(server_socket);
|
||||
if(param)
|
||||
update_free(param);
|
||||
TaskOTA = NULL;
|
||||
printf("\n\r[%s] Update task exit", __FUNCTION__);
|
||||
if(!ret){
|
||||
printf("\n\r[%s] Ready to reboot", __FUNCTION__);
|
||||
ota_platform_reset();
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
int update_ota_local(char *ip, int port){
|
||||
update_cfg_local_t *pUpdateCfg;
|
||||
|
||||
if(TaskOTA){
|
||||
printf("\n\r[%s] Update task has created.", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
pUpdateCfg = update_malloc(sizeof(update_cfg_local_t));
|
||||
if(pUpdateCfg == NULL){
|
||||
printf("\n\r[%s] Alloc update cfg failed", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
pUpdateCfg->ip_addr = inet_addr(ip);
|
||||
pUpdateCfg->port = ntohs(port);
|
||||
|
||||
if(xTaskCreate(update_ota_local_task, "OTA_server", STACK_SIZE, pUpdateCfg, TASK_PRIORITY, &TaskOTA) != pdPASS){
|
||||
update_free(pUpdateCfg);
|
||||
printf("\n\r[%s] Create update task failed", __FUNCTION__);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cmd_update(int argc, char **argv){
|
||||
int port;
|
||||
if(argc != 3){
|
||||
printf("\n\r[%s] Usage: update IP PORT", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
port = atoi(argv[2]);
|
||||
update_ota_local(argv[1], port);
|
||||
}
|
||||
|
||||
void cmd_ota_image(bool cmd){
|
||||
flash_t flash;
|
||||
uint32_t Part1Addr = 0xFFFFFFFF,Part2Addr = 0xFFFFFFFF;
|
||||
uint8_t *pbuf = NULL;
|
||||
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_read_word(&flash, 0x18, &Part1Addr);
|
||||
Part1Addr = (Part1Addr&0xFFFF)*1024; // first partition
|
||||
flash_read_word(&flash, OFFSET_DATA, &Part2Addr);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
|
||||
if(Part2Addr == ~0x0)
|
||||
return;
|
||||
|
||||
pbuf = update_malloc(FLASH_SECTOR_SIZE);
|
||||
if(!pbuf) return;
|
||||
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_stream_read(&flash, Part2Addr, FLASH_SECTOR_SIZE, pbuf);
|
||||
if (cmd == 1)
|
||||
memcpy((char*)pbuf+8, "81958711", 8);
|
||||
else
|
||||
memcpy((char*)pbuf+8, "01958711", 8);
|
||||
|
||||
flash_erase_sector(&flash, Part2Addr);
|
||||
flash_stream_write(&flash, Part2Addr, FLASH_SECTOR_SIZE, pbuf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
|
||||
#if SWAP_UPDATE
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_stream_read(&flash, Part1Addr, FLASH_SECTOR_SIZE, pbuf);
|
||||
if (cmd == 1)
|
||||
memcpy((char*)pbuf+8, "01958711", 8);
|
||||
else
|
||||
memcpy((char*)pbuf+8, "81958711", 8);
|
||||
|
||||
flash_erase_sector(&flash, Part1Addr);
|
||||
flash_stream_write(&flash, Part1Addr, FLASH_SECTOR_SIZE, pbuf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
#endif
|
||||
update_free(pbuf);
|
||||
}
|
||||
|
||||
#ifdef HTTP_OTA_UPDATE
|
||||
/******************************************************************************************************************
|
||||
** Function Name : update_ota_http_connect_server
|
||||
** Description : connect to the OTA server
|
||||
** Input : server_socket: the socket used
|
||||
** host: host address of the OTA server
|
||||
** port: port of the OTA server
|
||||
** Return : connect ok: socket value
|
||||
** Failed: -1
|
||||
*******************************************************************************************************************/
|
||||
int update_ota_http_connect_server(int server_socket, char *host, int port){
|
||||
struct sockaddr_in server_addr;
|
||||
struct hostent *server;
|
||||
|
||||
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(server_socket < 0){
|
||||
printf("\n\r[%s] Create socket failed", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
server = gethostbyname(host);
|
||||
if(server == NULL){
|
||||
printf("[ERROR] Get host ip failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&server_addr,0,sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(port);
|
||||
memcpy(&server_addr.sin_addr.s_addr,server->h_addr,server->h_length);
|
||||
|
||||
if (connect(server_socket,(struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){
|
||||
printf("\n\r[%s] Socket connect failed", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
/******************************************************************************************************************
|
||||
** Function Name : parse_http_response
|
||||
** Description : Parse the http response to get some useful parameters
|
||||
** Input : response : The http response got from server
|
||||
** response_len: The length of http response
|
||||
** result : The struct that store the usful infor about the http response
|
||||
** Return : Parse OK: 1 -> Only got the status code
|
||||
** 3 -> Got the status code and content_length, but didn't get the full header
|
||||
** 4 -> Got all the information needed
|
||||
** Failed: -1
|
||||
*******************************************************************************************************************/
|
||||
int parse_http_response(uint8_t *response, uint32_t response_len, http_response_result_t *result) {
|
||||
uint32_t i, p, q, m;
|
||||
uint32_t header_end = 0;
|
||||
|
||||
//Get status code
|
||||
if(0 == result->parse_status){//didn't get the http response
|
||||
uint8_t status[4] = {0};
|
||||
i = p = q = m = 0;
|
||||
for (; i < response_len; ++i) {
|
||||
if (' ' == response[i]) {
|
||||
++m;
|
||||
if (1 == m) {//after HTTP/1.1
|
||||
p = i;
|
||||
}
|
||||
else if (2 == m) {//after status code
|
||||
q = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!p || !q || q-p != 4) {//Didn't get the status code
|
||||
return -1;
|
||||
}
|
||||
memcpy(status, response+p+1, 3);//get the status code
|
||||
result->status_code = atoi((char const *)status);
|
||||
if(result->status_code == 200)
|
||||
result->parse_status = 1;
|
||||
else{
|
||||
printf("\n\r[%s] The http response status code is %d", __FUNCTION__, result->status_code);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//if didn't receive the full http header
|
||||
if(3 == result->parse_status){//didn't get the http response
|
||||
p = q = 0;
|
||||
for (i = 0; i < response_len; ++i) {
|
||||
if (response[i] == '\r' && response[i+1] == '\n' &&
|
||||
response[i+2] == '\r' && response[i+3] == '\n') {//the end of header
|
||||
header_end = i+4;
|
||||
result->parse_status = 4;
|
||||
result->header_len = header_end;
|
||||
result->body = response + header_end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (3 == result->parse_status) {//Still didn't receive the full header
|
||||
result->header_bak = update_malloc(HEADER_BAK_LEN + 1);
|
||||
memset(result->header_bak, 0, strlen(result->header_bak));
|
||||
memcpy(result->header_bak, response + response_len - HEADER_BAK_LEN, HEADER_BAK_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
//Get Content-Length
|
||||
if(1 == result->parse_status){//didn't get the content length
|
||||
uint32_t content_length = 0;
|
||||
const uint8_t *content_length_buf1 = "CONTENT-LENGTH";
|
||||
const uint8_t *content_length_buf2 = "Content-Length";
|
||||
const uint32_t content_length_buf_len = strlen(content_length_buf1);
|
||||
p = q = 0;
|
||||
|
||||
for (i = 0; i < response_len; ++i) {
|
||||
if (response[i] == '\r' && response[i+1] == '\n') {
|
||||
q = i;//the end of the line
|
||||
if (!memcmp(response+p, content_length_buf1, content_length_buf_len) ||
|
||||
!memcmp(response+p, content_length_buf2, content_length_buf_len)) {//get the content length
|
||||
int j1 = p+content_length_buf_len, j2 = q-1;
|
||||
while ( j1 < q && (*(response+j1) == ':' || *(response+j1) == ' ') ) ++j1;
|
||||
while ( j2 > j1 && *(response+j2) == ' ') --j2;
|
||||
uint8_t len_buf[12] = {0};
|
||||
memcpy(len_buf, response+j1, j2-j1+1);
|
||||
result->body_len = atoi((char const *)len_buf);
|
||||
result->parse_status = 2;
|
||||
}
|
||||
p = i+2;
|
||||
}
|
||||
if (response[i] == '\r' && response[i+1] == '\n' &&
|
||||
response[i+2] == '\r' && response[i+3] == '\n') {//Get the end of header
|
||||
header_end = i+4;//p is the start of the body
|
||||
if(result->parse_status == 2){//get the full header and the content length
|
||||
result->parse_status = 4;
|
||||
result->header_len = header_end;
|
||||
result->body = response + header_end;
|
||||
}
|
||||
else {//there are no content length in header
|
||||
printf("\n\r[%s] No Content-Length in header", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == result->parse_status) {//didn't get the content length and the full header
|
||||
result->header_bak = update_malloc(HEADER_BAK_LEN + 1);
|
||||
memset(result->header_bak, 0, strlen(result->header_bak));
|
||||
memcpy(result->header_bak, response + response_len - HEADER_BAK_LEN, HEADER_BAK_LEN);
|
||||
}
|
||||
else if (2 == result->parse_status) {//didn't get the full header but get the content length
|
||||
result->parse_status = 3;
|
||||
result->header_bak = update_malloc(HEADER_BAK_LEN + 1);
|
||||
memset(result->header_bak, 0, strlen(result->header_bak));
|
||||
memcpy(result->header_bak, response + response_len - HEADER_BAK_LEN, HEADER_BAK_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
return result->parse_status;
|
||||
}
|
||||
|
||||
int http_update_ota(char *host, int port, char *resource)
|
||||
{
|
||||
int server_socket;
|
||||
unsigned char *buf, *alloc, *request;
|
||||
_file_checksum *file_checksum;
|
||||
int read_bytes = 0, i = 0;
|
||||
uint32_t address, flash_checksum = 0;
|
||||
uint32_t NewImg2Len = 0, NewImg2Addr = 0;
|
||||
int ret = -1;
|
||||
http_response_result_t rsp_result = {0};
|
||||
|
||||
alloc = update_malloc(BUF_SIZE + 4);
|
||||
if(!alloc){
|
||||
printf("\n\r[%s] Alloc buffer failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
buf = &alloc[4];
|
||||
file_checksum = (void*)alloc;
|
||||
|
||||
// Connect server
|
||||
server_socket = update_ota_http_connect_server(server_socket, host, port);
|
||||
if(server_socket == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
NewImg2Addr = update_ota_prepare_addr();
|
||||
if(NewImg2Addr == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
// reset
|
||||
file_checksum->u = 0;
|
||||
|
||||
// Write New Image 2 sector
|
||||
if(NewImg2Addr != ~0x0){
|
||||
uint32_t idx = 0;
|
||||
int data_len = 0;
|
||||
printf("\n\r");
|
||||
|
||||
//send http request
|
||||
request = (unsigned char *) update_malloc(strlen("GET /") + strlen(resource) + strlen(" HTTP/1.1\r\nHost: ")
|
||||
+ strlen(host) + strlen("\r\n\r\n") + 1);
|
||||
sprintf(request, "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", resource, host);
|
||||
|
||||
ret = write(server_socket, request, strlen(request));
|
||||
if(ret < 0){
|
||||
printf("\n\r[%s] Send HTTP request failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
while (3 >= rsp_result.parse_status){//still read header
|
||||
if(0 == rsp_result.parse_status){//didn't get the http response
|
||||
memset(buf, 0, BUF_SIZE);
|
||||
read_bytes = read(server_socket, buf, BUF_SIZE);
|
||||
if(read_bytes == 0)
|
||||
continue;
|
||||
if(read_bytes < 0){
|
||||
printf("\n\r[%s] Read socket failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
idx = read_bytes;
|
||||
memset(&rsp_result, 0, sizeof(rsp_result));
|
||||
if(parse_http_response(buf, idx, &rsp_result) == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
}
|
||||
else if((1 == rsp_result.parse_status) || (3 == rsp_result.parse_status)){//just get the status code
|
||||
memset(buf, 0, BUF_SIZE);
|
||||
memcpy(buf, rsp_result.header_bak, HEADER_BAK_LEN);
|
||||
update_free(rsp_result.header_bak);
|
||||
rsp_result.header_bak = NULL;
|
||||
read_bytes = read(server_socket, buf+ HEADER_BAK_LEN, (BUF_SIZE - HEADER_BAK_LEN));
|
||||
if(read_bytes == 0)
|
||||
continue;
|
||||
if(read_bytes < 0){
|
||||
printf("\n\r[%s] Read socket failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
idx = read_bytes + HEADER_BAK_LEN;
|
||||
|
||||
if(parse_http_response(buf, read_bytes + HEADER_BAK_LEN, &rsp_result) == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
}
|
||||
else if(3 == rsp_result.parse_status){
|
||||
printf("\n\r[%s] Get the content_length failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == rsp_result.body_len){
|
||||
printf("\n\r[%s] New firmware size = 0 !", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
else
|
||||
printf("\n\r[%s] Download new firmware begin, total size : %d\n\r", __FUNCTION__, rsp_result.body_len);
|
||||
|
||||
#if SWAP_UPDATE
|
||||
NewImg2Addr = update_ota_swap_addr(rsp_result.body_len, NewImg2Addr);
|
||||
if(NewImg2Addr == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
#endif
|
||||
address = NewImg2Addr;
|
||||
NewImg2Len = update_ota_erase_upg_region(rsp_result.body_len, NewImg2Len, NewImg2Addr);
|
||||
if(NewImg2Len == -1){
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
//Write the body of http response into flash
|
||||
data_len = idx - rsp_result.header_len;
|
||||
if(data_len > 0){
|
||||
file_checksum->c[0] = alloc[4+data_len-4]; // checksum attached at file end
|
||||
file_checksum->c[1] = alloc[4+data_len-3];
|
||||
file_checksum->c[2] = alloc[4+data_len-2];
|
||||
file_checksum->c[3] = alloc[4+data_len-1];
|
||||
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
if(flash_stream_write(&flash_ota, address, data_len, (buf+rsp_result.header_len)) < 0){
|
||||
printf("\n\r[%s] Write sector failed", __FUNCTION__);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
idx += data_len;
|
||||
while (idx < NewImg2Len){
|
||||
printf(".");
|
||||
data_len = NewImg2Len - idx;
|
||||
if(data_len > BUF_SIZE)
|
||||
data_len = BUF_SIZE;
|
||||
|
||||
memset(buf, 0, BUF_SIZE);
|
||||
read_bytes = read(server_socket, buf, data_len);
|
||||
if(read_bytes == 0)
|
||||
continue;
|
||||
if(read_bytes < 0){
|
||||
printf("\n\r[%s] Read socket failed", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
|
||||
if(read_bytes<4)
|
||||
printf("\n\r[%s] Recv small packet", __FUNCTION__);
|
||||
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
if(flash_stream_write(&flash_ota, address + idx, read_bytes, buf) < 0){
|
||||
printf("\n\r[%s] Write sector failed", __FUNCTION__);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
|
||||
file_checksum->c[0] = alloc[4+read_bytes-4]; // checksum attached at file end
|
||||
file_checksum->c[1] = alloc[4+read_bytes-3];
|
||||
file_checksum->c[2] = alloc[4+read_bytes-2];
|
||||
file_checksum->c[3] = alloc[4+read_bytes-1];
|
||||
|
||||
idx += read_bytes;
|
||||
}
|
||||
printf("\n\r[%s] Download new firmware %d bytes completed\n\r", __FUNCTION__, idx);
|
||||
|
||||
// read flash data back and calculate checksum
|
||||
for(i = 0; i < idx-4; i += BUF_SIZE){
|
||||
int k;
|
||||
int rlen = (idx-4-i)>BUF_SIZE?BUF_SIZE:(idx-4-i);
|
||||
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
||||
flash_stream_read(&flash_ota, NewImg2Addr+i, rlen, buf);
|
||||
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
||||
for(k = 0; k < rlen; k++)
|
||||
flash_checksum+=buf[k];
|
||||
}
|
||||
|
||||
ret = update_ota_checksum(file_checksum, flash_checksum, NewImg2Addr);
|
||||
if(ret == -1){
|
||||
printf("\n\r[%s] The checksume is wrong!\n\r", __FUNCTION__);
|
||||
goto update_ota_exit;
|
||||
}
|
||||
}
|
||||
update_ota_exit:
|
||||
if(alloc)
|
||||
update_free(alloc);
|
||||
if(request)
|
||||
update_free(request);
|
||||
if(server_socket >= 0)
|
||||
close(server_socket);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,97 @@
|
|||
#ifndef OTA_8195A_H
|
||||
#define OTA_8195A_H
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <platform_stdlib.h>
|
||||
#include <flash_api.h>
|
||||
#include <lwip/sockets.h>
|
||||
|
||||
/************************Related setting****************************/
|
||||
#define HTTP_OTA_UPDATE //if define, using http protocol, if not, will use socket
|
||||
#define CONFIG_CUSTOM_SIGNATURE 0 //if verify the custom signature(define in ota_8195a.c cus_sig)
|
||||
#define WRITE_OTA_ADDR 1
|
||||
#define SWAP_UPDATE 0
|
||||
|
||||
|
||||
#define BUF_SIZE 512
|
||||
#define HEADER_BAK_LEN 32
|
||||
|
||||
#define OFFSET_DATA FLASH_SYSTEM_DATA_ADDR
|
||||
#define IMAGE_2 0x0000B000
|
||||
#if WRITE_OTA_ADDR
|
||||
#define BACKUP_SECTOR (FLASH_SYSTEM_DATA_ADDR - 0x1000)
|
||||
#endif
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/****************Define the structures used*************************/
|
||||
typedef struct{
|
||||
uint32_t ip_addr;
|
||||
uint16_t port;
|
||||
}update_cfg_local_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t status_code;
|
||||
uint32_t header_len;
|
||||
uint8_t *body;
|
||||
uint32_t body_len;
|
||||
uint8_t *header_bak;
|
||||
uint32_t parse_status;
|
||||
} http_response_result_t;
|
||||
|
||||
typedef union {
|
||||
uint32_t u;
|
||||
unsigned char c[4];
|
||||
} _file_checksum;
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/****************General functions used by ota update***************/
|
||||
void *update_malloc(unsigned int size);
|
||||
void update_free(void *buf);
|
||||
void ota_platform_reset(void);
|
||||
#if WRITE_OTA_ADDR
|
||||
int write_ota_addr_to_system_data(flash_t *flash, uint32_t ota_addr);
|
||||
#endif
|
||||
int update_ota_connect_server(int server_socket, update_cfg_local_t *cfg);
|
||||
uint32_t update_ota_prepare_addr(void);
|
||||
#if SWAP_UPDATE
|
||||
uint32_t update_ota_swap_addr(uint32_t img_len, uint32_t NewImg2Addr);
|
||||
#endif
|
||||
int update_ota_erase_upg_region(uint32_t img_len, uint32_t NewImg2Len, uint32_t NewImg2Addr);
|
||||
int update_ota_checksum(_file_checksum *file_checksum, uint32_t flash_checksum, uint32_t NewImg2Addr);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/*******************Functions called by AT CMD**********************/
|
||||
void cmd_update(int argc, char **argv);
|
||||
void cmd_ota_image(bool cmd);
|
||||
/*******************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
** Function Name : update_ota_local
|
||||
** Description : Starting a thread of OTA updating through socket
|
||||
** Input : ip:The IP address of OTA server
|
||||
** port:The Port of OTA server
|
||||
** Return : 0: Task created OK
|
||||
** -1: Task created failed
|
||||
**************************************************************************************************/
|
||||
int update_ota_local(char *ip, int port);
|
||||
|
||||
|
||||
#ifdef HTTP_OTA_UPDATE
|
||||
int parse_http_response(uint8_t *response, uint32_t response_len, http_response_result_t *result);
|
||||
int update_ota_http_connect_server(int server_socket, char *host, int port);
|
||||
|
||||
/*************************************************************************************************
|
||||
** Function Name : http_update_ota
|
||||
** Description : The process of OTA updating through http protocol
|
||||
** Input : cfg:struct update_cfg_local_t
|
||||
** Return : NULL
|
||||
**************************************************************************************************/
|
||||
int http_update_ota(char *host, int port, char *resource);
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue