Files
HBshuiwuConcentrator/APP/update.c
2025-12-15 16:07:49 +08:00

917 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/******************************************************************************************
update Function
STM32F103RCT6 256K flash 48K RAM
flash : 0-15k API API : 0x0800,0000-0x0800,3FFF
: 16-17, params : 0x0800,4000-0x0800,47FF
: 18-19k key : 0x0800,4800-0x0800,4FFF
: 20K - 137K app : 0x0800,5000-0x0802,27FF
: 138K- 255K update app: 0x0802,2800-0x0803,FFFF
typedef struct
{
u8 file_indication;
u8 file_property;
u8 file_instr;
u16 total_packets;
u32 current_packet_No;
u16 packet_length;
u8 * data;
}st_update_packet;
typedef enum
{
UPDATE_END = 0,
UPDATE_RUNNING,
UPDATE_FINISH,
UPDATE_SUCCESS,
UPDATE_FAILED,
UPDATE_SALVE,
}EM_UPDATE_STATUS;
******************************************************************************/
#include "apl.h"
#include "update.h"
#include "Flash.h"
#include "uart.h"
#include "Mem.h"
#include "addr.h"
#include "General.h"
#include "MD5.h"
#include "Led.h"
st_update_params st_update;
static u8 packet_nnmber;
extern const u16 CRC16_Table[];
static u8 g_update_ctrl = UPDATE_NONE;
static QueueHandle_t updateQueue;
#define UPDATE_BUF_LEN 255
/*****************************************************************************
* Function : write_update_ctrlner
* Description : none
* Input : u8 ctrlner
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void write_update_ctrlner(u8 ctrlner)
{
if (ctrlner < UPDATE_MAX)
{
g_update_ctrl = ctrlner;
}
}
/*****************************************************************************
* Function : read_update_ctrlner
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 read_update_ctrlner(void)
{
return g_update_ctrl;
}
/*****************************************************************************
* Function : set_update_packetState
* Description : none
* Input : u16 packetNo
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void set_update_packetState(u16 packetNo)
{
st_update.packetsState[packetNo/8] |= (1<<(packetNo%8));
}
/*****************************************************************************
* Function : check_update_packect_state
* Description : none
* Input : u16 packetNo
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
bool check_update_packect_state(u16 packetNo)
{
if (st_update.packetsState[packetNo/8] & (1<<(packetNo%8)) )
{
return TRUE;
}
else
{
return FALSE;
}
}
/*****************************************************************************
*
check if all packet reserved
*
*****************************************************************************/
bool check_update_state(u16 total_packets)
{
for (u16 j = 0; j < total_packets; j++)
{
if (check_update_packect_state(j) == FALSE)
{
return FALSE;
}
}
return TRUE;
}
/*****************************************************************************
*
check if update data reserved right
*
*****************************************************************************/
bool update_software_check(u32 totalBytes)
{
u16 temp;
u16 crc16 = 0xFFFF;
u32 count = totalBytes -2;
u8 flash_temp;
u32 current_flash_addr = FLASH_APP_BACK_ADDRESS;
if (totalBytes <= 2)
{
return FALSE;
}
while (count--)
{
//GDflash_read(current_flash_addr, &flash_temp, 1);
flash_temp = *((u8*)current_flash_addr);
current_flash_addr++;
crc16 = (crc16 >> 8 ) ^ CRC16_Table[(crc16 ^ flash_temp) & 0xFF];
}
crc16 ^= 0xFFFF;
//GDflash_read(current_flash_addr, &flash_temp, 1);
flash_temp = *((u8*)current_flash_addr);
current_flash_addr++;
temp = (u16)flash_temp*256;
//GDflash_read(current_flash_addr, &flash_temp, 1);
flash_temp = *((u8*)current_flash_addr);
current_flash_addr++;
temp += flash_temp;
if (crc16 == temp)
{
return TRUE;
}
else
{
return FALSE;
}
}
/*****************************************************************************
*
write update packet in flash
*
*****************************************************************************/
void FLASH_Write_update_page(u16 packetNo, u8 * Data, u8 length)
{
u32 packet_start_addr = FLASH_APP_BACK_ADDRESS + packetNo * UPDATE_DEFAULT_PACKET_SIZE;
u8 buf[128];
MemCpy(buf, Data, length);
__disable_irq();
STM32_FlashWrite(packet_start_addr, Data, length);
__enable_irq();
}
/********************************************************************************
*
read update params from flash
*
*********************************************************************************/
bool read_update_flash(st_update_params *st_update_Structure)
{
memcpy(st_update_Structure, (u8*)FLASH_UPDATE_PARAMS_ADDRESS,sizeof(st_update_params));
if ( GetCRC16((u8*)st_update_Structure, sizeof(st_update_params) -2) == (st_update_Structure->crc) )
{
return TRUE;
}
else
{
return FALSE;
}
}
/********************************************************************************
*
write update params in flash
*
*********************************************************************************/
void write_update_flash(st_update_params *st_update_Structure )
{
st_update_Structure->crc = GetCRC16((u8*)st_update_Structure, sizeof(st_update_params) - 2);
if (STM32_FlashPageErase(FLASH_UPDATE_PARAMS_ADDRESS) == FLH_SUCCESS)
{
STM32_FlashWrite( FLASH_UPDATE_PARAMS_ADDRESS, (u8*)st_update_Structure, sizeof(st_update_params));
}
}
/*****************************************************************************
*
*
*****************************************************************************/
void reset_update_params(void)
{
memset(&st_update, 0 , sizeof(st_update));
write_update_flash(&st_update);
}
void update_ack(u8 number, u32 current_packet_No, u8 ctrl, u8 ctrlner)
{
static st_AFN15_ack afn15ack;
afn15ack.head.start = 0x68;
afn15ack.head.len = 0x13;
afn15ack.head.ctrl = ctrl | 0xc0;
afn15ack.head.info_route = 0;
afn15ack.head.info_slave = 0;
afn15ack.head.info_com_module = 0;
afn15ack.head.info_conflict = 0;
afn15ack.head.info_relay = 0;
afn15ack.head.info[0] = 0;
afn15ack.head.info[1] = 0;
afn15ack.head.info[2] = 0;
afn15ack.head.info[3] = 0;
afn15ack.head.number = number;
afn15ack.afn = 0x15;
afn15ack.dt1 = 0x01;
afn15ack.dt2 = 0x00;
afn15ack.current_packet_No = current_packet_No;
afn15ack.cs = GetSum((u8*)(&afn15ack)+ 3, 14);
afn15ack.end = 0x16;
if (ctrlner == UPDATE_485)
{
debug_Tx( (u8*)&afn15ack, sizeof(st_AFN15_ack));
}
else
{
plc_uart_Tx( (u8*)&afn15ack, sizeof(st_AFN15_ack));
}
}
u16 get_DT(u8 DT1, u8 DT2)
{
u16 temp = 0;
for (u8 i = 0; i < 8; i++)
{
temp += ((DT1 >> i) & 0x01);
}
if (temp != 1)
{
return 0xFF;
}
temp = 0;
do{
DT1 = DT1 >> 1;
if (DT1 == 0)
{
break;
}
temp++;
}while(1);
return (0xF1 + DT2*8 + temp);
}
void decode_dt(u16 DT, u8 *dt1, u8 *dt2)
{
*dt2 = (DT - 0xF1)/ 8;
*dt1 = (1 << (DT - 0xF1) % 8);
}
void defaut_13762head_ack_write(st_13762_head * head, u8 length, bool com_module_exist, u8 ctrl)
{
head->start = 0x68;
head->len = length;
head->ctrl = ctrl | 0x80;
head->info_route = 0;
head->info_slave = 0;
head->info_com_module = (u8)com_module_exist;
head->info_conflict = 0;
head->info_relay = 0;
MemSet(head->info, 0, 4);
head->number = packet_nnmber;
}
void apl_process_1372(u8 * ptr1372, u8 ctrlner)
{
static st_13762 temp_1372_frame;
static st_13762 *ptr_1372 = &temp_1372_frame;
static st_13762_03F1_ack ack_ptr_13762_03f1;
u8 *current_ptr = NULL;
u16 DT;
memcpy(ptr_1372, ptr1372, 10);
u16 length = temp_1372_frame.lenL + temp_1372_frame.lenH *256;
ptr_1372->cs = ptr1372[length - 2];
ptr_1372->end = ptr1372[length - 1];
if ((ptr_1372->ctrl & 0x08) == 1)
{
return ;
}
current_ptr = &ptr1372[10];
packet_nnmber = ptr_1372->number;
if (ptr_1372->info_com_module)
{
ptr_1372->source_addr = current_ptr;
current_ptr += 6;
if (cmp_addr(ptr_1372->source_addr) == ADDR_NEQ)
{
return;
}
if (ptr_1372->info_relay)
{
ptr_1372->relay_addr = current_ptr;
current_ptr += ptr_1372->info_relay*6;
}
ptr_1372->desc_addr = current_ptr;
current_ptr += 6;
}
ptr_1372->AFN = *current_ptr;
ptr_1372->DT1 = *(current_ptr + 1);
ptr_1372->DT2 = *(current_ptr + 2);
current_ptr += 3;
DT = get_DT(ptr_1372->DT1, ptr_1372->DT2);
ptr_1372->data = current_ptr;
if (!(ptr_1372->info_com_module))
{
switch (ptr_1372->AFN)
{
case 0x03:
if (DT == 0xF1)
{
if (ctrlner == UPDATE_PLC)
{
defaut_13762head_ack_write(&ack_ptr_13762_03f1.head, sizeof(st_13762_03F1_ack), FALSE, ptr_1372->ctrl);
ack_ptr_13762_03f1.AFN = 0x03;
ack_ptr_13762_03f1.DT1 = 0x01;
ack_ptr_13762_03f1.DT2 = 0x00;
MemCpy(ack_ptr_13762_03f1.Manu_code, (u8*)get_apl_version_ptr(), sizeof(Manufacturer_Version));
ack_ptr_13762_03f1.cs = GetSum( (u8*)&ack_ptr_13762_03f1 + 3, sizeof(st_13762_03F1_ack) - 5);
ack_ptr_13762_03f1.end = 0x16;
plc_uart_Tx((u8*)&ack_ptr_13762_03f1, sizeof(st_13762_03F1_ack));
}
}
break;
case 0x15:
if (DT == 0xF1)
{
if (read_update_ctrlner() == UPDATE_NONE)
{
write_update_ctrlner(ctrlner);
xQueueSendToBack( updateQueue, (u8*)ptr_1372->data, 10);
}
else if (read_update_ctrlner() == ctrlner)
{
xQueueSendToBack( updateQueue, (u8*)ptr_1372->data, 10);
}
}
break;
default:
break;
}
}
}
bool check_13762_packet(u8 *buf)
{
u8 len = buf[1] + buf[2]*256;
if ( (buf[0] == 0x68) && (buf[len -1] == 0x16) )
{
if (buf[len -2] == GetSum(buf + 3, len - 5))
{
return TRUE;
}
}
return FALSE;
}
void transparent_Proc(void)
{
//transparent xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
u8 *start_pos = NULL;
// u8 transparent_cmd[] = "transparent 00 ";
start_pos = get_debugBuf() + sizeof("transparent 00 ") - 1;
if (check_13762_packet(start_pos))
{
apl_process_1372(start_pos, UPDATE_485);
}
}
uint16_t get_packets(uint32_t totalBytes )
{
uint16_t packet;
packet = totalBytes /FLASH_PAGE_SIZE;
if (totalBytes % FLASH_PAGE_SIZE )
{
packet += 1;
}
return packet;
}
/*****************************************************************************
* Function : update_iap
* Description : none
* Input : u32 totalBytes
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170425
* Author : barry
* Modification: Created function
此处还需要修改不要使用1页的内存来存储用小内存或者直接用半字的方式来处理
*****************************************************************************/
bool update_iap(u32 totalBytes)
{
//static u8 updateBuf[FLASH_PAGE_SIZE];
u16 iap_flash_pages = get_packets(totalBytes);
for (u32 j = 0; j < iap_flash_pages; j++)
{
// memcpy(updateBuf, (u8*)(FLASH_APP_BACK_ADDRESS + j*FLASH_PAGE_SIZE), FLASH_PAGE_SIZE);
if (STM32_FlashPageErase(FLASH_API_ADDRESS + FLASH_PAGE_SIZE*j) == FLH_SUCCESS)
{
if (STM32_FlashWrite(FLASH_API_ADDRESS + FLASH_PAGE_SIZE*j, (u8*)(FLASH_APP_BACK_ADDRESS + j*FLASH_PAGE_SIZE) , FLASH_PAGE_SIZE) != FLH_SUCCESS)
{
return FALSE;
}
}
else
{
return FALSE;
}
}
return TRUE;
}
bool proceess_packet(st_update_packet * current_ptr, st_update_params * flash_ptr)
{
if (check_update_packect_state( current_ptr->current_packet_No))
{
printf("the same packet\r\n");
return FALSE;
}
printf("write packet %d in flash\r\n", current_ptr->current_packet_No);
FLASH_Write_update_page(current_ptr->current_packet_No, current_ptr->data, current_ptr->packet_length);
set_update_packetState(current_ptr->current_packet_No);
flash_ptr->received_packets++;
flash_ptr->current_packets = current_ptr->current_packet_No;
if (current_ptr->current_packet_No >= (current_ptr->total_packets - 1))
{
if (check_update_state(flash_ptr->total_packets) == TRUE)
{
printf("all packet received\r\n");
printf("total updte bytes = %d\r\n", flash_ptr->totalBytes );
flash_ptr->totalBytes = (current_ptr->total_packets - 1)*UPDATE_DEFAULT_PACKET_SIZE + current_ptr->packet_length;
if (current_ptr->file_indication == 0x03)
{
flash_ptr->status = UPDATE_FINISH;
write_update_flash(flash_ptr);
return TRUE;
}
else if (current_ptr->file_indication == 0xFD )
{
return TRUE;
}
else
{
reset_update_params();
printf("update file indication err\r\n");
return FALSE;
}
}
else
{
reset_update_params();
printf("update file err\r\n");
return FALSE;
}
}
else
{
return FALSE;
}
}
void erase_128k(void)
{
for (u32 i = 0; i < FLASH_APPL_BACK_PAGES; i++)
{
STM32_FlashPageErase(FLASH_APP_BACK_ADDRESS + i*2048);
}
}
static bool is_update_process = false;
bool get_update_process()
{
return is_update_process;
}
void set_update_process()
{
is_update_process = true;
}
void update_process_task(void *ptr)
{
static st_update_packet update_packet;
static bool update_finish_state = FALSE;
static u8 tempBuf[UPDATE_BUF_LEN];
static u32 last_packet_No = 0;
updateQueue = xQueueCreate(1, UPDATE_BUF_LEN);
for (;;)
{
xQueueReceive(updateQueue, tempBuf, portMAX_DELAY );
memcpy(&update_packet, tempBuf, sizeof(st_update_packet) - 4);
update_packet.data = tempBuf + sizeof(st_update_packet) -4;
if (update_packet.current_packet_No != 0)
{
continue;
}
printf("update start\r\n");
set_update_process();
vTaskDelay(1000/portTICK_RATE_MS);
close_printf();
memset(&st_update, 0 , sizeof(st_update));
erase_128k();
vTaskDelay(1000/portTICK_RATE_MS);
st_update.status = UPDATE_RUNNING;
st_update.total_packets = update_packet.total_packets;
printf("update_totalPackets = %d\r\n", st_update.total_packets);
last_packet_No = 0;
update_finish_state = proceess_packet(&update_packet, &st_update);
update_ack(packet_nnmber, update_packet.current_packet_No, 0x0A, g_update_ctrl);
if ( g_update_ctrl == UPDATE_PLC)
{
vTaskDelay(100/portTICK_RATE_MS);
set_PLC_UART_baud(57600);
}
while(1)
{
if( xQueueReceive(updateQueue, tempBuf, 3000/portTICK_RATE_MS ) == pdPASS)
{
memcpy(&update_packet, tempBuf, sizeof(st_update_packet) - 4);
update_packet.data = tempBuf + sizeof(st_update_packet) -4;
if (update_packet.current_packet_No != (last_packet_No + 1))
{
reset_update_params();
open_printf();
if ( g_update_ctrl == UPDATE_PLC)
{
set_PLC_UART_baud(COM_PLC_BAUD);
}
break;
}
else
{
last_packet_No += 1;
update_finish_state = proceess_packet(&update_packet, &st_update);
update_ack(packet_nnmber, update_packet.current_packet_No, 0x0A, g_update_ctrl);
if (update_finish_state)
{
update_finish_state = FALSE;
if (update_packet.file_indication == 0x03 ) //升级自身
{
vTaskDelay(300/portTICK_RATE_MS);
SysReset();
}
else if (update_packet.file_indication == 0xFD ) //升级IAP
{
if (update_software_check(st_update.totalBytes))
{
bool iap_result = update_iap(st_update.totalBytes);
if (iap_result)
{
SysReset();
}
}
set_PLC_UART_baud(COM_PLC_BAUD);
reset_update_params();
}
else //升级标志错误
{
set_PLC_UART_baud(COM_PLC_BAUD);
reset_update_params();
}
}
}
}
else
{
if ( g_update_ctrl == UPDATE_PLC)
{
set_PLC_UART_baud(COM_PLC_BAUD);
}
memset(&st_update, 0 , sizeof(st_update));
break;
}
}
}
}
void create_update_task(void)
{
xTaskCreate( update_process_task, NULL, 200, NULL, 3, NULL);
}
void updata_finish(u32 total_packets)
{
reset_update_params();
st_update.status = UPDATE_FINISH;
st_update.totalBytes = total_packets;
write_update_flash(&st_update);
}
/*
#define ONE_HOUR_TIME 3600000
#define HALF_HOUR_TIME 1800000
PROCESS(apl_update_process, "update_process ");
PROCESS_THREAD(apl_update_process, ev, data)
{
static st_update_packet update_packet;
static bool update_finish_state = FALSE;
static struct etimer update_timer;
static struct etimer timeout_timer;
static u8 tempBuf[255];
static u8 buf[12];
PROCESS_BEGIN();
if (ev == PROCESS_EVENT_INIT)
{
read_update_flash(&st_update);
if (st_update.status == UPDATE_SUCCESS)
{
all_light_delay();
reset_update_params();
}
memset(&st_update, 0 , sizeof(st_update));
}
while (1)
{
PROCESS_WAIT_EVENT();
if (ev == PROCESS_EVENT_MSG)
{
memcpy(tempBuf, (u8*)data, COM_PLC_RX_BUFFER_SIZE);
memcpy(&update_packet, tempBuf, sizeof(st_update_packet) - 4);
update_packet.data = tempBuf + sizeof(st_update_packet) -4;
if (update_packet.current_packet_No >= update_packet.total_packets )
{
printf("packet no error\r\n");
continue;
}
if (update_packet.current_packet_No == 0)
{
close_printf();
printf("update start\r\n");
memset(&st_update, 0 , sizeof(st_update));
erase_128k();
etimer_set(&update_timer, 1000);
PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &update_timer));
etimer_set(&update_timer, HALF_HOUR_TIME);
st_update.status = UPDATE_RUNNING;
st_update.total_packets = update_packet.total_packets;
printf("update_totalPackets = %d\r\n", st_update.total_packets);
}
else
{
if (st_update.status != UPDATE_RUNNING)
{
reset_update_params();
open_printf();
continue;
}
}
update_finish_state = proceess_packet(&update_packet, &st_update);
update_ack(packet_nnmber, update_packet.current_packet_No, 0x0A, g_update_ctrl);
if ((update_packet.current_packet_No == 0) && (g_update_ctrl == UPDATE_PLC))
{
etimer_set(&update_timer, 100);
PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &update_timer));
set_PLC_UART_baud(57600);
}
if (update_packet.current_packet_No == update_packet.total_packets -1)
{
etimer_stop(&timeout_timer);
}
if (update_finish_state)
{
update_finish_state = FALSE;
if (update_packet.file_indication == 0x03 )
{
etimer_set(&update_timer, 300);
PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &update_timer));
SysReset();
}
else if (update_packet.file_indication == 0xFD )
{
if (update_software_check(st_update.totalBytes))
{
if (!update_iap(st_update.totalBytes))
{
SysReset();
}
set_PLC_UART_baud(9600);
}
}
else
{
reset_update_params();
}
}
}
else if ((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &timeout_timer))
{
reset_update_params();
set_PLC_UART_baud(9600);
open_printf();
}
}
PROCESS_END();
}
*/
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/