iap.c
3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "iap.h"
#include "usart.h"
#include "timer.h"
#include "crc.h"
#include "flash.h"
#include "delay.h"
iapfun jump2app;
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void Run_Flash_App(u32 appxaddr)
{
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP.
}
}
/****************************************************
* @brief: 通过RS485接口,本地下载固件
* @param:
* @retva:
* @note:
******************************************************/
uint8_t Success[] = "FireWare Check Success\r\n";
uint8_t Fail[] = "FireWare Check Fail\r\n";
uint8_t Incorrect[] = "Input Command Incorrect\r\n";
uint8_t Manual_Labal[] = "CMD Description\r\n";
uint8_t Manual_Start[] = "START Start Up Transmit FireWare\r\n";
uint8_t Manual_Ack[] = "ACK: Confirm The FireWare\r\n";
uint8_t Manual_Cancel[] = "CANCEL Cancel The Update Program\r\n";
uint8_t Manual_Line[] = "\r\n*******************************************\r\n";
uint8_t Ok[] = "OK\r\n";
void Local_Update(void)
{
Clear_Uart5_Cache();
uint16_t crc = 0xFFFF;
uint32_t handle;
Tick_Delay_ms(70);
Uart5_Send(Manual_Line,sizeof(Manual_Line));
Tick_Delay_ms(70);
Uart5_Send(Manual_Labal,sizeof(Manual_Labal));
Tick_Delay_ms(70);
Uart5_Send(Manual_Start,sizeof(Manual_Start));
Tick_Delay_ms(70);
Uart5_Send(Manual_Ack,sizeof(Manual_Ack));
Tick_Delay_ms(70);
Uart5_Send(Manual_Cancel,sizeof(Manual_Cancel));
Tick_Delay_ms(70);
Uart5_Send(Manual_Line,sizeof(Manual_Line));
while(1)
{
if(UART_FINISH)
{
if(strncmp((char *)UART_RX_BUF,"ACK",sizeof("ACK")) == 0) //确认数据
{
Uart5_Send(Ok,sizeof(Ok));
handle = BOOTLOADER_RUN;
STMFLASH_Write(FLAG_BASE_ADDR,(uint32_t *)&handle,4);
}
else if(strncmp((char *)UART_RX_BUF,"START",sizeof("START")) == 0) //启动传输
{
Uart5_Send(Ok,sizeof(Ok));
Clear_Uart5_Cache();
UART_FINISH = false;
while(UART_FINISH != true);
printf("receive %d Bytes msg\r\n",&UART_RX_CNT);
Uart5_Send(Ok,sizeof(Ok));
crc = GenerateCRC16(UART_RX_BUF,UART_RX_CNT-2);
printf("CACL = %x\r\n",crc);
if(crc == ((UART_RX_BUF[UART_RX_CNT-2] << 8 ) | UART_RX_BUF[UART_RX_CNT-1]))
{
STMFLASH_Write(APP_RUN_ADDR,(uint32_t *)UART_RX_BUF,UART_RX_CNT - 2);
Uart5_Send(Success,sizeof(Success));
}
else
{
Uart5_Send(Fail,sizeof(Fail));
}
printf("CRC = %x\r\n",crc);
}
else if(strncmp((char *)UART_RX_BUF,"CANCEL",sizeof("CANCEL")) == 0 ) //返回
{
Uart5_Send(Ok,sizeof(Ok));
break;
}
else
{
Uart5_Send(Incorrect,sizeof(Incorrect));
}
Clear_Uart5_Cache();
UART_FINISH = false;
UART5_Mode(RS485_READ);
}
}
}
/******************************************************
* @brief: 检测是否有触发本地升级
* @param:
* @retva:
* @note:
********************************************************/
uint8_t Update[] = "Enter Local Update\r\n";
void Detection_Update(void)
{
uint8_t i ;
for(i=0;i<WAIT_TIME;i++)
{
Tick_Delay_ms(1000);
if(UART_FINISH)
{
UART_FINISH= false;
if(strncmp((char *)UART_RX_BUF,"UPDATE",sizeof("UPDATE")) == 0)//F12
{
Uart5_Send(Update,sizeof(Update));
Local_Update();
break;
}
}
}
}