添加OTA升级功能 zsxfly20240819

This commit is contained in:
zsx 2024-08-19 12:09:05 +08:00
parent c95d8275c2
commit 87184aa643
13 changed files with 5105 additions and 4203 deletions

View File

@ -338,6 +338,32 @@ __INLINE__ void write32p(const void *ptr32, uint32_t value)
*ptr = (uint8_t)((value&0xff000000)>>24); *ptr = (uint8_t)((value&0xff000000)>>24);
} }
/**
****************************************************************************************
* @brief Reads a 16-bit word in an array
* @param[in] ptr16 The address of the first byte of the 16 bits word.
* @return The 16 bits value.
****************************************************************************************
*/
__INLINE__ uint16_t read16Swap(const void *ptr16)
{
uint16_t value = ((uint8_t *)ptr16)[1] | ((uint8_t *)ptr16)[0] << 8;
return value;
}
/**
****************************************************************************************
* @brief Write a 16-bit word in an array
* @param[in] ptr16 The address of the first byte of the 16 bits word.
* @param[in] value The value to write.
****************************************************************************************
*/
__INLINE__ void write16Swap(const void *ptr16, uint16_t value)
{
uint8_t *ptr=(uint8_t*)ptr16;
*ptr++ = (value&0xff00)>>8;
*ptr = value&0xff;
}
/** /**
**************************************************************************************** ****************************************************************************************

View File

@ -26,7 +26,7 @@
#endif #endif
#if !defined(DBG_UART_PORT) #if !defined(DBG_UART_PORT)
#define DBG_UART_PORT (0) //UART1 #define DBG_UART_PORT (1) //UART1
#endif #endif
#if !defined(DBG_UART_TXD) #if !defined(DBG_UART_TXD)
#define DBG_UART_TXD (6) //PA06 #define DBG_UART_TXD (6) //PA06

View File

@ -21,7 +21,7 @@
/// Number of Soft-Timer Instances /// Number of Soft-Timer Instances
#if !defined(SFTMR_NUM) #if !defined(SFTMR_NUM)
#define SFTMR_NUM (8) #define SFTMR_NUM (12)
#endif #endif
#if (SFTMR_NUM > 15) #if (SFTMR_NUM > 15)
@ -133,7 +133,15 @@ void CTMR_IRQHandler(void)
#elif (SFTMR_SRC == TMS_SysTick) #elif (SFTMR_SRC == TMS_SysTick)
#if !defined(TMS_SysTick_ARR) #if !defined(TMS_SysTick_ARR)
#if (SYS_CLK == 1)
#define TMS_SysTick_ARR (32 * 10000) // 10ms(32MHz CLK)
#elif (SYS_CLK == 2)
#define TMS_SysTick_ARR (48 * 10000) // 10ms(48MHz CLK)
#elif (SYS_CLK == 3)
#define TMS_SysTick_ARR (64 * 10000) // 10ms(64MHz CLK)
#else
#define TMS_SysTick_ARR (16 * 10000) // 10ms(16MHz CLK) #define TMS_SysTick_ARR (16 * 10000) // 10ms(16MHz CLK)
#endif //SYS_CLK
#endif #endif
// SysTick configure // SysTick configure
@ -260,7 +268,7 @@ static __forceinline tmr_id_t find_free_tmr(void)
{ {
for (tmr_id_t idx = 0; idx < SFTMR_NUM; idx++) for (tmr_id_t idx = 0; idx < SFTMR_NUM; idx++)
{ {
if (((sftmr_env.field & (1 << idx)) == 0) /*&& (sftmr_env.func[idx] == NULL)*/) if (((sftmr_env.field & (1 << idx)) == 0) && (sftmr_env.func[idx] == NULL))
{ {
return idx + 1; // found timer return idx + 1; // found timer
} }
@ -289,9 +297,8 @@ tmr_id_t sftmr_start(tmr_tk_t delay, tmr_cb_t func)
return tmr_id; return tmr_id;
} }
// ˢ<><EFBFBD>ʱʱ<CAB1><CAB1> // Refresh timer delay time, continue mode.
void sftmr_Refresh(tmr_id_t tmr_id, tmr_tk_t delay) void sftmr_Refresh(tmr_id_t tmr_id, tmr_tk_t delay){
{
if (TMR_ID_VALID(tmr_id)){ if (TMR_ID_VALID(tmr_id)){
tmr_id_t idx = tmr_id - 1; tmr_id_t idx = tmr_id - 1;
TMR_TK_RANGE(delay); TMR_TK_RANGE(delay);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -432,6 +432,18 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<bShared>0</bShared> <bShared>0</bShared>
</File> </File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>15</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\src\app_ota.c</PathWithFileName>
<FilenameWithoutPath>app_ota.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group> </Group>
<Group> <Group>
@ -442,7 +454,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>15</FileNumber> <FileNumber>16</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -454,7 +466,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>16</FileNumber> <FileNumber>17</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -466,7 +478,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>17</FileNumber> <FileNumber>18</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -478,7 +490,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>18</FileNumber> <FileNumber>19</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -490,7 +502,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>19</FileNumber> <FileNumber>20</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -502,7 +514,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>20</FileNumber> <FileNumber>21</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -514,7 +526,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>21</FileNumber> <FileNumber>22</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -526,7 +538,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber> <FileNumber>23</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -538,7 +550,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber> <FileNumber>24</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -550,7 +562,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>24</FileNumber> <FileNumber>25</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -562,7 +574,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>25</FileNumber> <FileNumber>26</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -574,7 +586,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>26</FileNumber> <FileNumber>27</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -586,7 +598,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>27</FileNumber> <FileNumber>28</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -598,7 +610,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>28</FileNumber> <FileNumber>29</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -610,7 +622,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>29</FileNumber> <FileNumber>30</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -622,7 +634,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>30</FileNumber> <FileNumber>31</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -634,7 +646,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>31</FileNumber> <FileNumber>32</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -646,7 +658,7 @@
</File> </File>
<File> <File>
<GroupNumber>3</GroupNumber> <GroupNumber>3</GroupNumber>
<FileNumber>32</FileNumber> <FileNumber>33</FileNumber>
<FileType>4</FileType> <FileType>4</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -666,7 +678,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>33</FileNumber> <FileNumber>34</FileNumber>
<FileType>5</FileType> <FileType>5</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -686,7 +698,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>5</GroupNumber> <GroupNumber>5</GroupNumber>
<FileNumber>34</FileNumber> <FileNumber>35</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -706,7 +718,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>35</FileNumber> <FileNumber>36</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -718,7 +730,7 @@
</File> </File>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>36</FileNumber> <FileNumber>37</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -730,7 +742,7 @@
</File> </File>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>37</FileNumber> <FileNumber>38</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -742,7 +754,7 @@
</File> </File>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>38</FileNumber> <FileNumber>39</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -754,7 +766,7 @@
</File> </File>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>39</FileNumber> <FileNumber>40</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -766,7 +778,7 @@
</File> </File>
<File> <File>
<GroupNumber>6</GroupNumber> <GroupNumber>6</GroupNumber>
<FileNumber>40</FileNumber> <FileNumber>41</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -786,7 +798,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>7</GroupNumber> <GroupNumber>7</GroupNumber>
<FileNumber>41</FileNumber> <FileNumber>42</FileNumber>
<FileType>4</FileType> <FileType>4</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -806,7 +818,7 @@
<RteFlg>0</RteFlg> <RteFlg>0</RteFlg>
<File> <File>
<GroupNumber>8</GroupNumber> <GroupNumber>8</GroupNumber>
<FileNumber>42</FileNumber> <FileNumber>43</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
@ -818,7 +830,7 @@
</File> </File>
<File> <File>
<GroupNumber>8</GroupNumber> <GroupNumber>8</GroupNumber>
<FileNumber>43</FileNumber> <FileNumber>44</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>

View File

@ -456,6 +456,11 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\src\sys_config.c</FilePath> <FilePath>..\src\sys_config.c</FilePath>
</File> </File>
<File>
<FileName>app_ota.c</FileName>
<FileType>1</FileType>
<FilePath>..\src\app_ota.c</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>

View File

@ -8,8 +8,15 @@
#include "app_PAD.h" #include "app_PAD.h"
// 用于PAD通信处理
// void app_otas_txd(uint16_t len, const uint8_t *data){
// app_PAD_Sendcmd(OTA_CMD_ID ,OTA_REG_ADDR ,data ,len);
// }
// 用于PAD通信处理
PAD_daraframe_t PAD_daraframe; PAD_daraframe_t PAD_daraframe;
volatile uint8_t Rec_state =0; volatile uint8_t Rec_state =0;
volatile uint8_t Rec_data_cnt =0; volatile uint8_t Rec_data_cnt =0;
@ -17,7 +24,12 @@ volatile uint8_t Rec_data_cnt =0;
static void PAD_Data_Hande(void){ static void PAD_Data_Hande(void){
uint8_t ret_data[MAX_LEN]={0,0}; uint8_t ret_data[MAX_LEN]={0,0};
uint8_t length=0; uint8_t length=0;
if((PAD_daraframe.cmd_id == OTA_CMD_ID) && (PAD_daraframe.reg_addr == OTA_REG_ADDR) && (PAD_daraframe.length == 18)){
app_otas_rxd(PAD_daraframe.length ,PAD_daraframe.data);
goto PAD_Data_Hande_end;
}
switch(PAD_daraframe.reg_addr){ switch(PAD_daraframe.reg_addr){
case 0x01: // 写入系统配置 case 0x01: // 写入系统配置
if(PAD_daraframe.cmd_id == 0x06){// 写入 if(PAD_daraframe.cmd_id == 0x06){// 写入
@ -137,6 +149,8 @@ static void PAD_Data_Hande(void){
// break; // break;
} }
app_PAD_Sendcmd(PAD_daraframe.cmd_id ,PAD_daraframe.reg_addr ,ret_data ,length); app_PAD_Sendcmd(PAD_daraframe.cmd_id ,PAD_daraframe.reg_addr ,ret_data ,length);
PAD_Data_Hande_end:
Rec_state =0;//数据处理完要清零,准备接收下一帧数据 Rec_state =0;//数据处理完要清零,准备接收下一帧数据
} }
@ -214,7 +228,7 @@ void app_PAD_Receive(uint8_t data){
} }
//发送命令 //发送命令
void app_PAD_Sendcmd(volatile uint8_t cmd_id ,volatile uint8_t reg_addr ,volatile uint8_t *data, volatile uint8_t length){ void app_PAD_Sendcmd(uint8_t cmd_id ,uint8_t reg_addr ,const uint8_t *data, uint8_t length){
PAD_daraframe_t frame; PAD_daraframe_t frame;
uint8_t *cmd_data =(uint8_t *)&frame; uint8_t *cmd_data =(uint8_t *)&frame;
uint8_t i; uint8_t i;

View File

@ -7,19 +7,21 @@
//数据帧头 //数据帧头
#define FRAME_HEADER 0xA100 #define FRAME_HEADER 0xA100
#define OTA_CMD_ID 0xA5
#define OTA_REG_ADDR 0x00
#define MAX_LEN 32 #define MAX_LEN 32
//0:失能数据校验 //0:失能数据校验
#define PAD_CRC8_EN 0 #define PAD_CRC8_EN 0
typedef struct PAD_daraframe typedef struct PAD_daraframe{
{ uint16_t header;//0xA100
volatile uint16_t header;//0xA100 uint8_t cmd_id;
volatile uint8_t cmd_id; uint8_t reg_addr;
volatile uint8_t reg_addr; uint8_t length;
volatile uint8_t length; uint8_t data[MAX_LEN];
volatile uint8_t data[MAX_LEN]; uint8_t crc;
volatile uint8_t crc;
} PAD_daraframe_t; } PAD_daraframe_t;
@ -30,6 +32,6 @@ void app_uart_Init(uint8_t port, uint32_t baudrate, uint8_t io_tx, uint8_t io_rx
// 接收数据 // 接收数据
void app_PAD_Receive(uint8_t data); void app_PAD_Receive(uint8_t data);
//发送命令 //发送命令
void app_PAD_Sendcmd(volatile uint8_t cmd_id ,volatile uint8_t reg_addr ,volatile uint8_t *data, volatile uint8_t length); void app_PAD_Sendcmd(uint8_t cmd_id ,uint8_t reg_addr ,const uint8_t *data, uint8_t length);
#endif #endif

View File

@ -0,0 +1,442 @@
/**
****************************************************************************************
*
* @file ota.c
*
* @brief Main loop of the application.
*
****************************************************************************************
*/
#include "drvs.h"
#include "regs.h"
// #include "prf_otas.h"
// #include "app.h"
#include "sftmr.h"
#include "list.h"
#include "utils.h"
#include "app_ota.h"
#include "sys_config.h"
/*
* DEFINES
****************************************************************************************
*/
/// examples\loader
#define CFG_USE_LOAD 0
#define DBG_OTAS 1
#if (DBG_OTAS)
#include "dbg.h"
#define DEBUG(format, ...) debug("[OTA]" format "\r\n", ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
#define debugHex(dat, len)
#endif
#ifndef FLASH_BASE
#define FLASH_BASE (0x18000000)
#endif
#define FLASH_SIZE (0x40000) // 256KB
#define FLASH_PAGE_SIZE (0x100) // 256B
#define FLASH_SECTOR_SIZE (0x1000) // 4KB
#define FLASH_PAGE_SIZE_WLEN (FLASH_PAGE_SIZE >> 2)
#define FLASH_INFO_PAGE (0x00)
#define FLASH_INFO_MAGIC (FLASH_BASE + 0x00)
#define FLASH_INFO_CODE_LEN (FLASH_BASE + 0x04)
#define FLASH_INFO_CODE_ADDR (FLASH_BASE + 0x08)
#define OTA_BANK_A_BASE (0x18004000)
#if (CFG_USE_LOAD)
#define OTA_BANK_B_BASE (0x18020100)
#else
#define OTA_BANK_B_BASE (0x18020000)
#endif
#define OTA_BANK_A (OTA_BANK_A_BASE - FLASH_BASE)
#define OTA_BANK_B (OTA_BANK_B_BASE - FLASH_BASE)
#define FLASH_ADDR_INVALID (0xFFFFFFFF)
#define OTA_FW_SECTOR_MAX_SIZE ((FLASH_SIZE - OTA_BANK_B) / FLASH_SECTOR_SIZE)
#define OTA_FW_MAX_SIZE (OTA_FW_SECTOR_MAX_SIZE * FLASH_SECTOR_SIZE) / 16 // 112K
#define OTA_PKT_LEN (20) // 2B peer_index + 16B ota data + 2B CRC
#define OTA_DATA_LEN (OTA_PKT_LEN - 4)
#define OTA_DATA_OLD (0x55)
#define OTA_DATA_NEW (0xAA)
#define OTA_TIMER_TICK _MS(3000) // 3s
#define OTA_MAX_TIMEOUT (400) // 600s/20min
#define OTA_CRC_EN 0 // CRC校验使能/0:不检验/1:检验
enum ota_state{
OTA_IDLE,
OTA_START,
OTA_BUSY,
OTA_ERROR,
};
enum ota_cmd{
OTA_CMD_START = 0xFF01,
OTA_CMD_END = 0xFF02,
};
enum ota_err_code{
OTA_ERR_NONE = 0, // No error
OTA_ERR_BANK_ADDR = 0x5501,//升级固件地址无效
OTA_ERR_FAIL = 0x5502,//升级失败
OTA_ERR_CRC = 0x5503,//CRC校验失败
OTA_ERR_FW = 0x5504,//固件过大
OTA_ERR_TIMEOUT = 0x5505,//升级超时
OTA_ERR_INDEX = 0x5506,//数据索引错误
OTA_ERR_DLEN = 0x5507,//数据长度错误
};
typedef struct ota_env{
uint32_t bank; //当前选择的BANK
uint8_t ota_sta;//OTA状态
uint8_t new_data_flag; //新数据标志
uint16_t data_idx;//本地OTA数据索引
uint16_t err_info; //错误信息
tmr_tk_t tick_cnt; //计时器
tmr_tk_t time_id; //定时器ID
}ota_env_t;
uint8_t ota_recv_buf[OTA_PKT_LEN];
uint32_t ota_wr_data[FLASH_PAGE_SIZE_WLEN];
volatile ota_env_t ota_env;
/*
* FUNCTION DEFINITIONS
****************************************************************************************
*/
__attribute__((section("ram_func.ota.124")))
static void flash_sector_erase(uint32_t offset)
{
GLOBAL_INT_DISABLE();
while (SYSCFG->ACC_CCR_BUSY);
fshc_erase(offset, FSH_CMD_ER_SECTOR);
GLOBAL_INT_RESTORE();
}
__attribute__((section("ram_func.ota.136")))
static void flash_wr_protect(uint8_t val)
{
GLOBAL_INT_DISABLE();
while (SYSCFG->ACC_CCR_BUSY);
uint8_t sta_reg0 = fshc_rd_sta(FSH_CMD_RD_STA0, 1);
if (val != sta_reg0)
{
// д<><D0B4><EFBFBD><EFBFBD>0x000-0xFFF (4KB)
// write en singal
fshc_en_cmd(FSH_CMD_WR_EN);
// send write sta cmd
fshc_wr_sta(FSH_CMD_WR_STA, 1, val);
bootDelayUs(12000);
}
GLOBAL_INT_RESTORE();
}
/******************************************************************************
* Name: CRC-16/MODBUS
* Poly: 0x8005 ( x16+x15+x2+1 )
* Init: 0xFFFF
* Refin: True
* Refout: True
* Xorout: 0x0000
*****************************************************************************/
#if (OTA_CRC_EN)
static uint16_t crc16_modbus(uint8_t *data, uint16_t length)
{
uint8_t i;
uint16_t crc = 0xFFFF; // Initial value
while (length--)
{
crc ^= *data++;
for (i = 0; i < 8; ++i)
{
if (crc & 1)
{
crc = (crc >> 1) ^ 0xA001; // 0xA001 = reverse 0x8005
}
else
{
crc = (crc >> 1);
}
}
}
return crc;
}
#endif
void app_otas_rxd(uint16_t len, const uint8_t *data)
{
#if (OTA_CRC_EN)
uint8_t OTA_pack_len =OTA_PKT_LEN;
#else
uint8_t OTA_pack_len = OTA_DATA_LEN - 2;//减去CRC16的两字节
#endif
// 接收20字节数据包
if (len > OTA_pack_len){
len = OTA_pack_len;
}
// memcpy(ota_recv_buf, data, ota_env.data_len);
for(uint16_t i = 0; i < len; i++){
ota_recv_buf[i] = data[i];
}
// uart_send(UART1_PORT ,len ,ota_recv_buf);
// debugHex(ota_recv_buf, len);
ota_env.new_data_flag = OTA_DATA_NEW;
app_ota_proc();
}
void app_otas_txd(uint16_t len, const uint8_t *data){
// uart_send(UART1_PORT ,len ,data);
app_PAD_Sendcmd(OTA_CMD_ID ,OTA_REG_ADDR ,data ,len);
}
tmr_tk_t ota_time_handle(uint8_t timeid){
ota_env.tick_cnt++;
DEBUG("sta:%d,tick_cnt:%d",ota_env.ota_sta, ota_env.tick_cnt);
if (ota_env.tick_cnt > OTA_MAX_TIMEOUT){
ota_env.tick_cnt = 0;
ota_env.ota_sta = OTA_ERROR;
ota_env.err_info = OTA_ERR_TIMEOUT;
DEBUG("time_handle -> OTA_TIMEOUT");
sftmr_clear(ota_env.time_id);
}else if (ota_env.ota_sta == OTA_IDLE){
DEBUG("time_handle -> OTA_IDLE");
ota_env.tick_cnt = 0;
sftmr_clear(ota_env.time_id);
}
return OTA_TIMER_TICK;
}
#define PEER_IDX (read16Swap(p_OTAData))
#define PEER_CRC (read16Swap(p_OTAData + OTA_PKT_LEN - 2))
#define PEER_DAT (p_OTAData + 2)
uint32_t OTA_read32(const void *ptr32){
uint32_t value = (0xff & ((uint8_t *)ptr32)[0]) | ((0xff & ((uint8_t *)ptr32)[1]) << 8) | ((0xff & ((uint8_t *)ptr32)[2]) << 16) | ((0xff & ((uint8_t *)ptr32)[3]) << 24);
return value;
}
void app_ota_proc(void){
uint8_t *p_OTAData = ota_recv_buf;
switch (ota_env.ota_sta){
case OTA_IDLE:{
if (ota_env.new_data_flag == OTA_DATA_OLD){ //跳过旧包数据
return;
}
ota_env.new_data_flag = OTA_DATA_OLD;
if ((PEER_IDX == OTA_CMD_START) && (ota_env.err_info == OTA_ERR_NONE)){ //初始帧
#if (OTA_CRC_EN)
uint16_t local_crc16 = crc16_modbus(p_OTAData, OTA_PKT_LEN - 2);
if(local_crc16 != PEER_CRC){
DEBUG("CRC16:0x%X,local_crc16:0x%X", PEER_CRC, local_crc16);
ota_env.ota_sta = OTA_ERROR;
ota_env.err_info = OTA_ERR_CRC;
DEBUG("OTA_ERR_CRC");
return;
}
#endif
if((ota_env.bank != FLASH_ADDR_INVALID) && (ota_env.bank ==(0xFFF000 & OTA_read32(PEER_DAT)))){//检验数据包的是否有效
// Erase
uint32_t erase_offset = (ota_env.bank & 0xFFFFF000UL);
uint32_t erase_end = (ota_env.bank == OTA_BANK_B ? FLASH_SIZE : OTA_BANK_B);
DEBUG("erase_offset:0x%X,erase_end:0x%X", erase_offset, erase_end);
for (;erase_offset < erase_end; erase_offset += FLASH_SECTOR_SIZE){
flash_sector_erase(erase_offset);
}
DEBUG("sector_erase OK");
ota_env.ota_sta = OTA_START;
ota_env.err_info = OTA_ERR_NONE;
app_otas_txd(2, p_OTAData);//初始帧应答 FF01
}else{
ota_env.ota_sta = OTA_ERROR;
ota_env.err_info = OTA_ERR_BANK_ADDR;
DEBUG("OTA_PACK_INVALID");
return;
}
}
}break;
case OTA_START:{
DEBUG("OTA_START");
ota_env.ota_sta = OTA_BUSY;
ota_env.err_info = OTA_ERR_NONE;
ota_env.data_idx = 0;
ota_env.tick_cnt = 0;
if(0==ota_env.time_id)ota_env.time_id = sftmr_start(OTA_TIMER_TICK, ota_time_handle);
// app_led_TurnOff(LED_Keyboard);
// app_led_Blink(LED_Mifare,200,200,0xffff);
}break;
case OTA_BUSY:{ //按扇区编程数据
if (ota_env.new_data_flag == OTA_DATA_OLD){ //跳过旧包数据
return;
}
ota_env.new_data_flag = OTA_DATA_OLD;
#if (OTA_CRC_EN)
uint16_t local_crc16 = crc16_modbus(p_OTAData, OTA_PKT_LEN - 2);
if(local_crc16 != PEER_CRC){
DEBUG("IDX:%d,CRC16:0x%X,local_crc16:0x%X",PEER_IDX, PEER_CRC, local_crc16);
ota_env.ota_sta = OTA_ERROR;
ota_env.err_info = OTA_ERR_CRC;
DEBUG("OTA_ERR_CRC");
return;
}
#endif
if(ota_env.data_idx == PEER_IDX && ota_env.data_idx < OTA_FW_MAX_SIZE){ //数据索引正确
uint8_t wr_data_pos = (ota_env.data_idx % OTA_DATA_LEN) * OTA_DATA_LEN;
uint32_t wr_addr = (ota_env.data_idx / OTA_DATA_LEN) * FLASH_PAGE_SIZE + ota_env.bank;
memcpy(((uint8_t *)ota_wr_data + wr_data_pos), PEER_DAT, OTA_DATA_LEN);
if((ota_env.data_idx % OTA_DATA_LEN) == (OTA_DATA_LEN - 1)){
DEBUG("ADDRW:0x%X,peer_idx:%d", wr_addr, ota_env.data_idx);
flash_write(wr_addr, ota_wr_data, FLASH_PAGE_SIZE_WLEN);
}
ota_env.data_idx ++;
// ota_env.err_info = OTA_ERR_NONE;
}else if((PEER_IDX == OTA_CMD_END ) && (read16Swap(PEER_DAT) == (0xffff & (~read16Swap(PEER_DAT+2))))
&& (ota_env.data_idx == read16Swap(PEER_DAT) + 1)){//尾帧
// uint16_t txd_data = read16Swap(&PEER_IDX);
// app_otas_txd(2, (uint8_t *)&txd_data);
app_otas_txd(2, p_OTAData);//尾帧应答 FF02
// write remain data
if ((ota_env.data_idx % OTA_DATA_LEN) != 0){
uint32_t wr_addr = (ota_env.data_idx / OTA_DATA_LEN) * FLASH_PAGE_SIZE + ota_env.bank;
DEBUG("ADDRW:0x%X,ota_app_idx:%d", wr_addr, ota_env.data_idx);
flash_write(wr_addr, ota_wr_data, FLASH_PAGE_SIZE_WLEN);
}
DEBUG("OTA_success");
#if (CFG_USE_LOAD)
DEBUG("data_idx:%d", ota_env.data_idx);
memset((uint8_t *)ota_wr_data, 0xFF, sizeof(ota_wr_data));
ota_wr_data[0] = 0x55AA5AA5;
ota_wr_data[1] = (ota_env.data_idx * 16);
ota_wr_data[2] = OTA_BANK_B_BASE;
flash_page_erase(OTA_BANK_B - FLASH_PAGE_SIZE);
flash_write(OTA_BANK_B - FLASH_PAGE_SIZE, ota_wr_data, FLASH_PAGE_SIZE_WLEN);
#else
flash_wr_protect(0x00);
flash_read(FLASH_INFO_PAGE, ota_wr_data, FLASH_PAGE_SIZE_WLEN);
ota_wr_data[1] = ota_env.data_idx * 16;
ota_wr_data[2] = ota_env.bank | FLASH_BASE;
flash_page_erase(FLASH_INFO_PAGE);
flash_write(FLASH_INFO_PAGE, ota_wr_data, FLASH_PAGE_SIZE_WLEN);
flash_wr_protect(0x64);
#endif
ota_env.ota_sta = OTA_IDLE;
ota_env.err_info = OTA_ERR_NONE;
ota_env.data_idx = 0;
ota_env.tick_cnt = 0;
// app_led_TurnOn(LED_Keyboard);
// app_led_Blink(LED_Mifare,80,80,0xffff);
bootDelayMs(5000);
NVIC_SystemReset();
}else{//数据索引错误
DEBUG("IDX_ERR:env_idx:0x%04X,peer_idx:0x%04X-0x%04X=0x%04X", ota_env.data_idx, PEER_IDX,read16Swap(PEER_DAT),(0xffff & (~read16Swap(PEER_DAT+2))));
ota_env.ota_sta = OTA_ERROR;
ota_env.err_info = OTA_ERR_INDEX;
DEBUG("INDEX_ERROR");
return;
}
} break;
case OTA_ERROR:{
if(OTA_ERR_NONE != ota_env.err_info){
DEBUG("ERROR_CODE:0x%x", ota_env.err_info);
ota_env.err_info = read16Swap((void *)&ota_env.err_info);
app_otas_txd(2, (uint8_t *)&ota_env.err_info);//错误帧应答 5501~5507
// app_led_Blink(LED_Keyboard,200,200,10);//4S
// app_led_Blink(LED_Mifare,200,200,10);
ota_env.ota_sta = OTA_IDLE;
// ota_env.new_data_flag = OTA_DATA_OLD;
ota_env.data_idx = 0;
ota_env.err_info = OTA_ERR_NONE;
ota_env.tick_cnt = 0;
DEBUG("OTA_IDLE");
// NVIC_SystemReset();
}
}break;
default:
break;
}
}
bool app_is_ota_proc(void)
{
return (ota_env.ota_sta != OTA_IDLE);
}
static void ota_env_init(void)
{
ota_env.bank = FLASH_ADDR_INVALID;
ota_env.ota_sta = OTA_IDLE;
ota_env.new_data_flag = OTA_DATA_OLD;
ota_env.data_idx = 0;
ota_env.err_info = OTA_ERR_NONE;
ota_env.tick_cnt = 0;
ota_env.time_id = TMR_ID_NONE;
}
void app_ota_init(void)
{
ota_env_init();
#if (CFG_USE_LOAD)
ota_env.bank = OTA_BANK_B;
#else
uint32_t curr_code_addr = RD_32(FLASH_INFO_CODE_ADDR);
DEBUG("Curr Addr:0x%x", curr_code_addr);
ota_env.bank = FLASH_ADDR_INVALID;
if(curr_code_addr == OTA_BANK_A_BASE){
ota_env.bank = OTA_BANK_B;
}
else if(curr_code_addr == OTA_BANK_B_BASE){
ota_env.bank = OTA_BANK_A;
}
#endif
// app_led_Blink(LED_Keyboard,200,200,0xffff);
// app_led_TurnOff(LED_Mifare);
DEBUG("OTA_BANK:0x%x", ota_env.bank);
}

View File

@ -0,0 +1,12 @@
#ifndef _APP_OTA_H_
#define _APP_OTA_H_
#include <stdbool.h>
void app_ota_init(void);
void app_ota_proc(void);
bool app_is_ota_proc(void);
void app_otas_rxd(uint16_t len, const uint8_t *data);
#endif

View File

@ -203,6 +203,7 @@ int main(void)
Time_Event_Init(); Time_Event_Init();
GRB_WS2812_Init(); GRB_WS2812_Init();
BAT_Message_Init(); BAT_Message_Init();
app_ota_init();
// read config // read config
uint8_t ret = read_cfg(&sys_conf); uint8_t ret = read_cfg(&sys_conf);
@ -246,6 +247,9 @@ int main(void)
// User's Procedure // User's Procedure
// app_ble_procedure(); // app_ble_procedure();
// OTA Procedure
// app_ota_proc();
Control_procedure(); Control_procedure();
iwdt_feed();//喂狗 iwdt_feed();//喂狗
} }

View File

@ -8,7 +8,7 @@
#include "app_Time_Event.h" #include "app_Time_Event.h"
#include "app_bat.h" #include "app_bat.h"
#include "app_PAD.h" #include "app_PAD.h"
#include "app_ota.h"
// 存储在第1扇区第0页 // 存储在第1扇区第0页
#define CONF_OFFSET_BASE (0x18001000) // 配置信息存储地址(以页为单位0x100) #define CONF_OFFSET_BASE (0x18001000) // 配置信息存储地址(以页为单位0x100)