Browse Source

iap初版

樊春春 4 months ago
parent
commit
bdd4fed0a9

+ 40 - 8
applications/bootloader/bootloader.c

@@ -1,18 +1,50 @@
+#include "bootloader.h"
+#include "dev_iap.h"
 #include "global.h"
+#include <stdint.h>
 
-u8 boot_goto_app(u32 addr)
+void boot_goto_app(void)
 {
-    pFunction Jump_To_Application;
-    __IO u32  JumpAddress;
+    pFunction     Jump_To_Application;
+    __IO uint32_t JumpAddress;
 
-    CAN_DeInit(CAN1);
+    // CAN_DeInit(CAN1);
 
-    if (((*(__IO u32 *)addr) & 0x2FFE0000) == 0x20000000)
+    if (((*(__IO uint32_t *)APP_START_ADDR) & 0x2FFE0000) == 0x20000000)
     {
-        JumpAddress         = *(__IO u32 *)(addr + 4);
+        JumpAddress         = *(__IO uint32_t *)(APP_START_ADDR + 4);
         Jump_To_Application = (pFunction)JumpAddress;
-        __set_MSP(*(__IO u32 *)addr);
+        __set_MSP(*(__IO uint32_t *)APP_START_ADDR);
         Jump_To_Application();
     }
-    return 1;
+}
+
+uint8_t check_addr_sp(uint32_t addr)
+{
+    int ret;
+
+    if (((*(uint32_t *)addr) & 0x2FFE0000) == 0x20000000) // 检查栈顶地址是否合法
+    {
+        ret = VALID;
+    }
+    else
+    {
+        ret = INVALID;
+    }
+    return ret;
+}
+
+uint8_t check_addr_pc(uint32_t addr)
+{
+    int ret;
+
+    if (((*(uint32_t *)(addr + 4)) & 0xFF000000) == 0x08000000) // 检查中断向量表地址是否合法
+    {
+        ret = VALID;
+    }
+    else
+    {
+        ret = INVALID;
+    }
+    return ret;
 }

+ 12 - 1
applications/bootloader/bootloader.h

@@ -2,7 +2,18 @@
 #define __BOOTLOADER_H
 
 #include "global.h"
+#include <stdint.h>
 
-u8 boot_goto_app(u32 addr);
+typedef enum
+{
+    INVALID = 0,
+    VALID   = !INVALID
+} validity_status;
+
+typedef void (*pFunction)(void);
+
+void    boot_goto_app(void);
+uint8_t check_addr_sp(uint32_t addr);
+uint8_t check_addr_pc(uint32_t addr);
 
 #endif

+ 262 - 0
applications/dev_iap.c

@@ -0,0 +1,262 @@
+/************************************************************************************************
+ *                                          Include                                              *
+ ************************************************************************************************/
+#include "dev_iap.h"
+#include "hal_flash.h"
+#include "queue.h"
+#include <stdint.h>
+#include <string.h>
+
+/************************************************************************************************
+ *                                          Config                                                *
+ ************************************************************************************************/
+extern uint8_t jump_flag;
+uint8_t        can_rx_flag;
+// extern can_receive_message receive_iap_message;
+static uint16_t jump_boot_time = 0;
+uint8_t         send_buff[8]   = {0, 0, 0, 0, 0, 0, 0, 0};
+unsigned char   recv_crc[2];
+unsigned char   recvdata_ema[204];
+unsigned char   recvdata_buffer[210];
+
+uint16_t firm_ver[UPGRADE_APP_DATA_SIZE]       = {IAP_CMD_JUMP_OVER};
+uint16_t firm_ver_buff[UPGRADE_BUFF_DATA_SIZE] = {0};
+uint8_t  iap_disconnect_count                  = 0;
+/************************************************************************************************
+ *                                          Data structs                                         *
+ ************************************************************************************************/
+iap_type      g_iap;
+upgrade_param upgrade;
+/************************************************************************************************
+ *                                          implements                                           *
+ ************************************************************************************************/
+void invert_uint8()
+{
+}
+
+void iap_connect_clear(void)
+{
+    iap_disconnect_count = 0;
+    send_buff[0]         = 0x00;
+    send_buff[1]         = 0x00;
+    send_buff[2]         = 0x00;
+    send_buff[3]         = 0x00;
+    send_buff[4]         = 0x00;
+    send_buff[5]         = 0x00;
+    send_buff[6]         = 0x00;
+    send_buff[7]         = 0x00;
+}
+
+void iap_disconnect_check(void)
+{
+    if (++iap_disconnect_count >= 5)
+    {
+        iap_disconnect_count = 5;
+    }
+}
+
+// iap相关参数初始化
+void iap_param_init(void)
+{
+    g_iap.recv_len         = 0;
+    g_iap.total_packages   = 0;
+    g_iap.current_packages = 0;
+    g_iap.crc16            = 0xFFFF;
+    g_iap.total_bytes      = 0;
+    g_iap.count_bytes      = 0;
+    g_iap.count_packages   = 0;
+    g_iap.firmware_crc16   = 0;
+    g_iap.firmware_ver     = 0;
+}
+
+// 清除升级信息标志位
+void set_firmver(void)
+{
+    fmc_clear_flag_star();
+    fmc_read_n_half_word(UPGRADE_FLAG_START_ADDR, firm_ver_buff, UPGRADE_BUFF_DATA_SIZE);
+    fmc_erase_pages(UPGRADE_FLAG_START_ADDR, 1);
+
+    fmc_write_n_half_word(UPGRADE_FLAG_START_ADDR, firm_ver_buff, UPGRADE_BUFF_DATA_SIZE);
+    fmc_clear_flag_end();
+}
+
+void iap_flag_release(void)
+{
+    fmc_read_n_half_word(UPGRADE_FLAG_START_ADDR, upgrade.infor_buf, UPGRADE_FLAG_DATA_SIZE);
+
+    if (upgrade.param.sign == UPGRADE_SIGN)
+    {
+        fmc_clear_flag_star();
+        fmc_erase_pages(UPGRADE_FLAG_START_ADDR, 1);
+        fmc_write_n_half_word(UPGRADE_FLAG_START_ADDR + (UPGRADE_FLAG_DATA_SIZE * 2), firm_ver, UPGRADE_APP_DATA_SIZE);
+        fmc_clear_flag_end();
+        for (uint8_t i = 0; i < (UPGRADE_APP_DATA_SIZE * 2); i++)
+        {
+            send_buff[i] = fmc_read_byte(UPGRADE_FLAG_START_ADDR + (UPGRADE_FLAG_DATA_SIZE * 2) + i);
+        }
+        // hal_can_msg_tx(0x180000001, CAN_Id_Extended, send_buff, 8);
+        CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);
+    }
+}
+
+uint8_t erase_app_flash(uint32_t start_address, uint32_t end_addr)
+{
+    uint8_t  status   = 0;
+    uint16_t page_len = 0;
+    // page_len          = (end_addr - start_address) / FMC_PAGE_SIZE;
+    status = fmc_erase_pages(start_address, page_len);
+    return status;
+}
+
+void write_app_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
+{
+    static uint32_t w_start_addr = 0;
+
+    w_start_addr = pack_num * 6 + APP_START_ADDR;
+    fmc_write_n_half_word(w_start_addr, buf, pack_len);
+}
+
+void read_app_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
+{
+    static uint32_t w_start_addr = 0;
+
+    w_start_addr = pack_num * 6 + APP_START_ADDR;
+    fmc_read_n_half_word(w_start_addr, buf, pack_len);
+}
+
+uint8_t write_download_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
+{
+    uint8_t         status       = 0;
+    static uint32_t w_start_addr = 0;
+
+    w_start_addr = pack_num * 6 + DOWNLOAD_START_ADDR;
+    status       = fmc_write_n_half_word(w_start_addr, buf, pack_len);
+    return status;
+}
+
+void read_download_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
+{
+    static uint32_t w_start_addr = 0;
+
+    w_start_addr = pack_num * 6 + DOWNLOAD_START_ADDR;
+    fmc_read_n_half_word(w_start_addr, buf, pack_len);
+}
+
+// void iap_rec_handler(pdu_tag rec_msg)
+// {
+//     uint8_t erase_flag = 0x01;
+
+//     // ota_can_id = rec_msg.id.r;
+//     if (rec_msg.data.u8_buf[0] != IAP_CMD_VERSION)
+//         iap_connect_clear();
+
+//     if (rec_msg.data.u8_buf[0] >> 7)
+//     {
+//         if (rec_msg.id.b.sa == 0xE1)
+//         {
+//             g_iap.recv_len         = rec_msg.reg.dlc - 2;
+//             g_iap.current_packages = ((uint16_t)(rec_msg.data.u8_buf[0] & 0x7F) << 8) | rec_msg.data.u8_buf[1];
+//             memcpy(g_iap.flash_data.u8_buf, &rec_msg.data.u8_buf[2], g_iap.recv_len);
+
+//             if ((g_iap.count_packages == g_iap.current_packages) && (g_iap.current_packages < g_iap.total_packages))
+//             {
+//                 g_iap.count_bytes += g_iap.recv_len;
+
+//                 if ((g_iap.recv_len % 2) != 0)
+//                 {
+//                     g_iap.flash_data.u8_buf[g_iap.recv_len] = 0xFF;
+//                     g_iap.recv_len++;
+//                 }
+
+//                 fmc_clear_flag_star();
+//                 erase_flag = write_download_flash(g_iap.flash_data.u16_buf, g_iap.recv_len / 2, g_iap.count_packages);
+//                 fmc_clear_flag_end();
+
+//                 g_iap.crc16 = firmware_crc16_ccitt_false(g_iap.crc16, g_iap.flash_data.u8_buf, g_iap.recv_len);
+
+//                 send_buff[0] = IAP_CMD_DATA;
+//                 send_buff[1] = !erase_flag;
+//                 g_iap.count_packages++;
+//             }
+//             else
+//             {
+//                 send_buff[0] = IAP_CMD_DATA;
+//                 send_buff[1] = 0x06;
+//             }
+
+//             send_buff[2] = rec_msg.data.u8_buf[0] & 0x7F;
+//             send_buff[3] = rec_msg.data.u8_buf[1];
+
+//             send_buff[4] = g_iap.count_packages >> 8;
+//             send_buff[5] = g_iap.count_packages & 0xFF;
+//         }
+//         else
+//         {
+//             switch (rec_msg.data.u8_buf[0])
+//             {
+//             case IAP_CMD_VERSION:
+//                 iap_param_init();
+//                 for (uint8_t i = 0; i < (UPGRADE_APP_DATA_SIZE * 2); i++)
+//                 {
+//                     send_buff[i] = fmc_read_byte(UPGRADE_FLAG_START_ADDR + (UPGRADE_FLAG_START_ADDR * 2) + i);
+//                 }
+
+//                 send_buff[0] = IAP_CMD_VERSION;
+//                 send_buff[1] = 0x01;
+//                 break;
+//             case IAP_CMD_INFO:
+//                 g_iap.total_bytes = (uint16_t)rec_msg.data.u8_buf[1] << 8 | rec_msg.data.u8_buf[2];
+//                 g_iap.total_bytes <<= 16;
+//                 g_iap.total_bytes |= (uint16_t)rec_msg.data.u8_buf[3] << 8 | rec_msg.data.u8_buf[4];
+//                 g_iap.total_packages = (uint16_t)rec_msg.data.u8_buf[5] << 8 | rec_msg.data.u8_buf[6];
+//                 send_buff[0]         = IAP_CMD_INFO;
+//                 send_buff[1]         = 0x01;
+//                 break;
+//             case IAP_CMD_ERASE:
+//                 g_iap.firmware_crc16 = (uint16_t)rec_msg.data.u8_buf[2] << 8 | rec_msg.data.u8_buf[3];
+//                 if (rec_msg.data.u8_buf[1])
+//                 {
+//                     // 喂狗
+//                     fmc_clear_flag_star();
+//                     erase_flag = erase_app_flash(DOWNLOAD_START_ADDR, DOWNLOAD_END_ADDR / 2);
+//                     fmc_clear_flag_end();
+//                     // 喂狗
+//                     g_iap.count_bytes    = 0;
+//                     g_iap.count_packages = 0;
+//                 }
+//                 send_buff[0] = IAP_CMD_ERASE;
+//                 send_buff[1] = !erase_flag;
+//             case IAP_CMD_CRC:
+//                 send_buff[0] = IAP_CMD_CRC;
+//                 send_buff[1] = (g_iap.crc16 == g_iap.firmware_crc16 ? 1 : 0);
+//                 break;
+//             case IAP_CMD_JUMP:
+//                 if (g_iap.crc16 != g_iap.firmware_crc16)
+//                 {
+//                     send_buff[1] = 0x00;
+//                 }
+//                 else
+//                 {
+//                     fmc_clear_flag_star();
+//                     fmc_erase_pages(UPGRADE_FLAG_START_ADDR, 1);
+//                     upgrade.param.sign        = UPGRADE_SIGN;
+//                     upgrade.param.crc16       = g_iap.crc16;
+//                     upgrade.param.moving_size = g_iap.total_bytes;
+//                     fmc_write_n_half_word(UPGRADE_FLAG_START_ADDR, upgrade.infor_buf, UPGRADE_FLAG_DATA_SIZE);
+//                     fmc_clear_flag_end();
+//                     jump_boot_time = 10;
+//                     send_buff[1]   = 0x01;
+//                 }
+//                 break;
+//             case IAP_CMD_MODEL_TYPE:
+//                 send_buff[0] = IAP_CMD_MODEL_TYPE;
+//                 send_buff[1] = 0x01;
+
+//                 send_buff[2] = DEVICE_ID >> 8;
+//                 send_buff[3] = DEVICE_ID & 0xFF;
+//             }
+//         }
+
+//         // push_can_message_to_queue(IAP, 8, send_buff);
+//     }
+// }

+ 114 - 0
applications/dev_iap.h

@@ -0,0 +1,114 @@
+#ifndef __DEV_IAP_H
+#define __DEV_IAP_H
+
+#ifdef __cplusplus
+extern 'C'
+{
+#endif
+#ifdef __DEV_IAP_H_GLOBAL
+#define __DEV_IAP_H_EXTERN
+#else
+#define __DEV_IAP_H_EXTERN extern
+#endif
+
+/************************************************************************************************
+ *                                          Version                                              *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          How to use                                           *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          Enable config                                         *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          Includes                                             *
+ ************************************************************************************************/
+#include <stdint.h>
+
+    /************************************************************************************************
+     *                                          Defines                                              *
+     ************************************************************************************************/
+
+#define UPGRADE_FLAG_DATA_SIZE 4                                                // 升级参数数组元素个数
+#define UPGRADE_APP_DATA_SIZE  4                                                // 升级参数数组元素个数
+#define UPGRADE_BUFF_DATA_SIZE (UPGRADE_FLAG_DATA_SIZE + UPGRADE_APP_DATA_SIZE) // 升级参数数组元素个数
+
+#define APP_START_ADDR ((uint32_t)0x08010000)
+#define APP_END_ADDR   ((uint32_t)0x08060000)
+
+#define UPGRADE_FLAG_START_ADDR ((uint32_t)0x08060000)
+#define UPGRADE_FLAG_END_ADDR   ((uint32_t)0x08061000)
+
+#define DOWNLOAD_START_ADDR  ((uint32_t)0x08080000)
+#define DOWNLOAD_END_ADDR    ((uint32_t)0x080C0000)
+#define DOWNLOAD_MIDDLE_ADDR ((uint32_t)0x080A0000)
+
+// 升级命令
+#define IAP_CMD_VERSION    0x71   // 查询版本号
+#define IAP_CMD_INFO       0x72   // 包信息
+#define IAP_CMD_ERASE      0x73   // 擦除命令
+#define IAP_CMD_DATA       0x80   // 数据帧 IAP_CMD_DATA |帧号
+#define IAP_CMD_CRC        0x74   // 传输结果校验
+#define IAP_CMD_JUMP       0x75   // 执行跳转
+#define IAP_CMD_JUMP_OVER  0x0175 // 执行跳转
+#define IAP_CMD_MODEL_TYPE 0x76   // 执行跳转
+
+#define UPGRADE_SIGN 0x5AA5
+#define DEVICE_ID    0x5AA4
+
+    typedef union
+    {
+        uint16_t u8_buf[8];
+        uint16_t u16_buf[4];
+    } u16_u8;
+
+    typedef union
+    {
+        uint16_t u8_save[200];
+        uint16_t u16_save[100];
+    } u16save_u8save;
+
+    typedef struct
+    {
+        uint16_t       total_packages;
+        uint16_t       current_packages;
+        uint16_t       count_packages;
+        uint16_t       recv_len;
+        uint16_t       crc16;
+        uint16_t       firmware_crc16;
+        uint16_t       firmware_ver;
+        uint16_t       total_bytes;
+        uint16_t       count_bytes;
+        u16_u8         flash_data;
+        u16_u8         recheck_data;
+        u16save_u8save save_data;
+    } iap_type;
+
+    typedef union
+    {
+        struct
+        {
+            uint16_t sign;        // 首地址 buf[0]
+            uint16_t crc16;       // 中地址 buf[1]
+            uint32_t moving_size; // 高地址 buf[2] buf[3]
+        } param;
+        uint16_t infor_buf[UPGRADE_FLAG_DATA_SIZE];
+    } upgrade_param; // 升级参数使用
+
+    extern upgrade_param upgrade;
+
+    void    iap_param_init(void);
+    void    iap_flag_release(void);
+    uint8_t erase_app_flash(uint32_t start_address, uint32_t end_addr);
+
+/************************************************************************************************
+ *                                          Defines                                              *
+ ************************************************************************************************/
+#ifdef __cplusplus
+};
+#endif
+
+#endif // __DEV_IAP_H

+ 1 - 1
applications/global/global.h

@@ -7,7 +7,7 @@ typedef uint32_t u32;
 typedef uint16_t u16;
 typedef uint8_t  u8;
 
-typedef void (*pFunction)(void);
+// typedef void (*pFunction)(void);
 
 typedef struct
 {

+ 396 - 395
applications/iap/iap.c

@@ -1,395 +1,396 @@
-#include "iap.h"
-#include "bootloader.h"
-#include "can.h"
-#include "dwt.h"
-#include "global.h"
-#include "stm32f4xx_flash.h"
-#include <string.h>
-
-static u8  iap_index             = 0;
-static u16 iap_buf[IAP_BUF_SIZE] = {0};
-
-extern SqQueue CanQueueImportant; // CAN重要数据队列
-
-uint16_t STMFLASH_GetFlashSector(u32 addr)
-{
-    if (addr < ADDR_FLASH_SECTOR_1)
-        return FLASH_Sector_0;
-    else if (addr < ADDR_FLASH_SECTOR_2)
-        return FLASH_Sector_1;
-    else if (addr < ADDR_FLASH_SECTOR_3)
-        return FLASH_Sector_2;
-    else if (addr < ADDR_FLASH_SECTOR_4)
-        return FLASH_Sector_3;
-    else if (addr < ADDR_FLASH_SECTOR_5)
-        return FLASH_Sector_4;
-    else if (addr < ADDR_FLASH_SECTOR_6)
-        return FLASH_Sector_5;
-    else if (addr < ADDR_FLASH_SECTOR_7)
-        return FLASH_Sector_6;
-    else if (addr < ADDR_FLASH_SECTOR_8)
-        return FLASH_Sector_7;
-    else if (addr < ADDR_FLASH_SECTOR_9)
-        return FLASH_Sector_8;
-    else if (addr < ADDR_FLASH_SECTOR_10)
-        return FLASH_Sector_9;
-    else if (addr < ADDR_FLASH_SECTOR_11)
-        return FLASH_Sector_10;
-    return FLASH_Sector_11;
-}
-
-u8 flash_read_byte(u32 faddr)
-{
-    return *(vu8 *)faddr;
-}
-
-u16 STMFLASH_ReadHalfWord(u32 faddr)
-{
-    return *(vu16 *)faddr;
-}
-
-u32 flash_read_page(u32 faddr)
-{
-    return *(vu32 *)faddr;
-}
-
-void copy_to_runaddr(u32 end_addr)
-{
-    FLASH_Status status      = FLASH_COMPLETE;
-    u32          write_addr1 = IAP_RUN_START_SECTOR, read_addr = IAP_DOWN_BEGIN_ADDR;
-    // u8  erase_sector = 0, index = 0;
-    u32 temp_value = 0;
-    // erase_sector = STMFLASH_GetFlashSector(IAP_RUN_START_SECTOR);
-    FLASH_Unlock();              // 解锁
-    FLASH_DataCacheCmd(DISABLE); // FLASH擦除期间,必须禁止数据缓存
-    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
-
-    status = FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3);
-    if (status != FLASH_COMPLETE)
-    {
-        FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存
-        FLASH_Lock();               // 上锁
-        return;
-    }
-    status = FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3);
-    if (status != FLASH_COMPLETE)
-    {
-        FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存
-        FLASH_Lock();               // 上锁
-        return;
-    }
-
-    while (end_addr > read_addr)
-    {
-        temp_value = flash_read_page(read_addr);
-        if (FLASH_ProgramWord(write_addr1, temp_value) != FLASH_COMPLETE) // 写入数据
-        {
-            break; // 写入异常
-        }
-
-        write_addr1 += 4;
-        read_addr += 4;
-    }
-
-    FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存
-    FLASH_Lock();               // 上锁
-}
-
-void iap_send_dataresp(u8 res, u32 addr, u32 sum)
-{
-    u8 send_buf[8] = {0};
-    send_buf[0]    = IAP_CMD_DOWNLOAD;
-
-    send_buf[1] = addr;
-    send_buf[2] = addr >> 8;
-    send_buf[3] = addr >> 16;
-    send_buf[4] = res;
-    send_buf[5] = addr >> 24;
-    send_buf[6] = (u8)(sum >> 8);
-    send_buf[7] = (u8)sum;
-    can_send_msg(send_buf, DLC_8, IAP_MCU_DATA_FRAME);
-}
-
-void iap_send_datafinish(u16 page_num)
-{
-    u8 send_buf[8] = {0};
-    send_buf[0]    = IAP_CMD_DOWNLOAD_END;
-    send_buf[1]    = (u8)page_num;
-    send_buf[2]    = (u8)(page_num >> 8);
-    send_buf[3]    = 0xFF;
-    send_buf[4]    = 0xFF;
-    send_buf[5]    = 0xFF;
-    send_buf[6]    = 0xFF;
-    send_buf[7]    = 0xFF;
-    can_send_msg(send_buf, DLC_8, IAP_MCU_DATA_FRAME);
-}
-
-u8 stm_flash_write(u32 addr, u16 *array, u32 len)
-{
-    u8           res   = TRUE;
-    u32          index = 0, temp_addr = addr;
-    FLASH_Status status = FLASH_COMPLETE;
-    FLASH_Unlock();
-    FLASH_DataCacheCmd(DISABLE);
-    for (index = 0; index < len;)
-    {
-        if (STMFLASH_ReadHalfWord(temp_addr) != 0xFFFF)
-        {
-            status = FLASH_EraseSector(STMFLASH_GetFlashSector(temp_addr), VoltageRange_3);
-            if (status != FLASH_COMPLETE)
-            {
-                res = FALSE;
-                break;
-            }
-        }
-        else
-        {
-            index++;
-            temp_addr += 2;
-        }
-    }
-    if (status == FLASH_COMPLETE)
-    {
-        for (index = 0; index < len; index++)
-        {
-            if (FLASH_ProgramHalfWord(addr, array[index]) != FLASH_COMPLETE) // 写入数据
-            {
-                res = FALSE;
-                // 写入异常
-                break;
-            }
-            addr += 2;
-        }
-    }
-    FLASH_DataCacheCmd(ENABLE);
-    FLASH_Lock();
-
-    return res;
-}
-
-void stm_flash_write_word(u32 addr, u32 value)
-{
-    u32          temp_addr = addr;
-    FLASH_Status status    = FLASH_COMPLETE;
-    FLASH_Unlock();
-    FLASH_DataCacheCmd(DISABLE);
-
-    if (flash_read_page(temp_addr) != 0xFFFFFFFF)
-    {
-        status = FLASH_EraseSector(STMFLASH_GetFlashSector(temp_addr), VoltageRange_3);
-        if (status != FLASH_COMPLETE)
-        {
-            return;
-        }
-    }
-
-    if (status == FLASH_COMPLETE)
-    {
-        if (FLASH_ProgramWord(addr, value) != FLASH_COMPLETE) // 写入数据
-        {
-            return;
-        }
-    }
-    FLASH_DataCacheCmd(ENABLE);
-    FLASH_Lock();
-}
-
-void stm_flash_write_byte(u32 addr, u8 value)
-{
-    u32          temp_addr = addr;
-    FLASH_Status status    = FLASH_COMPLETE;
-    FLASH_Unlock();
-    FLASH_DataCacheCmd(DISABLE);
-
-    if (flash_read_byte(temp_addr) != 0xFF)
-    {
-        status = FLASH_EraseSector(STMFLASH_GetFlashSector(temp_addr), VoltageRange_3);
-        if (status != FLASH_COMPLETE)
-        {
-            return;
-        }
-    }
-
-    if (status == FLASH_COMPLETE)
-    {
-        if (FLASH_ProgramByte(addr, value) != FLASH_COMPLETE) // 写入数据
-        {
-            return;
-        }
-    }
-    FLASH_DataCacheCmd(ENABLE);
-    FLASH_Lock();
-}
-
-void iap_process(CanData_TypeDef *rx_msg)
-{
-    // 握手帧回复,最后一个字节为前7个字节累加和
-    u8  handle_buf[DLC_8] = {'S', 'U', 'C', 'C', 'E', 'S', 'S', 0x19};
-    u8  pc_frame[DLC_8]   = {'A', 'P', 'P', 'L', 'O', 'A', 'D', 0x01};
-    u8  index = 0, pc_cmd = 0, pack_num = 0, res = 0;
-    u16 rec_page_num = 0;
-    u32 temp_addr    = 0;
-
-    static u16 cnt            = 0;
-    static u16 total_page_num = 0;
-    static u32 iap_sum        = 0;
-    static u32 pack_receive   = 0;
-    static u32 write_addr = 0, old_write_addr = 0;
-
-    if (rx_msg->can_id == IAP_PC_BEGINE_FRAME)
-    {
-        cnt = 0;
-        if (memcmp(rx_msg->buf, pc_frame, 7) == 0)
-        {
-            total_page_num = 0;
-            if (res == 0)
-            {
-                InitQueue(&CanQueueImportant);
-                can_send_msg(handle_buf, DLC_8, IAP_MCU_BIGEN_FRAME);
-                write_addr = IAP_RUN_START_SECTOR; // IAP_DOWN_BEGIN_ADDR;
-            }
-            else
-            {
-                return;
-            }
-        }
-    }
-    else if (rx_msg->can_id == IAP_PC_DATA_FRAME)
-    {
-        cnt    = 0;
-        pc_cmd = rx_msg->buf[0];
-        switch (pc_cmd)
-        {
-        case IAP_CMD_DOWNLOAD:
-            pack_num = rx_msg->buf[1];
-            if (pack_num == 0x01)
-            {
-                iap_sum      = 0;
-                iap_index    = 0;
-                pack_receive = 0;
-                pack_receive |= (1 << (pack_num - 1));
-                write_addr = (rx_msg->buf[6] << 24) + (rx_msg->buf[5] << 16) + (rx_msg->buf[4] << 8) + rx_msg->buf[3];
-            }
-            else if ((pack_num > 0x01) && (pack_num < 0x17))
-            {
-                if (((pack_receive & 0x00000001) != 0x00000001) || ((pack_receive & (1 << (pack_num - 1))) == (1 << (pack_num - 1))))
-                {
-                    break;
-                }
-                iap_index = (pack_num - 2) * 3;
-                for (index = 0; index < 3; index++)
-                {
-                    if (iap_index < (IAP_BUF_SIZE - 1))
-                    {
-                        pack_receive |= 1 << (pack_num - 1);
-                        iap_buf[iap_index] = ((u16)rx_msg->buf[2 * index + 3] << 8) + rx_msg->buf[2 * index + 2];
-                        iap_sum += iap_buf[iap_index];
-                        iap_index++;
-                    }
-                }
-            }
-            else if (pack_num == 0x17)
-            {
-                if (((pack_receive & 0x00000001) != 0x00000001) || ((pack_receive & (1 << (pack_num - 1))) == (1 << (pack_num - 1))))
-                {
-                    break;
-                }
-                iap_index = 63;
-                pack_receive |= 1 << (pack_num - 1);
-                iap_buf[iap_index] = ((u16)rx_msg->buf[3] << 8) + rx_msg->buf[2];
-                iap_sum += iap_buf[iap_index];
-            }
-            if ((pack_receive & 0x007FFFFF) == 0x007FFFFF)
-            {
-                temp_addr = write_addr;
-                if ((write_addr >= ADDR_FLASH_SECTOR_4) && (write_addr <= ADDR_FLASH_SECTOR_END) && (stm_flash_write(temp_addr, iap_buf, IAP_BUF_SIZE) == TRUE))
-                {
-                    iap_send_dataresp(MCU_DOWNLOAD_SUCC, write_addr, iap_sum);
-                    if (write_addr != old_write_addr)
-                    {
-                        total_page_num++;
-                        old_write_addr = write_addr;
-                    }
-                }
-                else
-                {
-                    iap_send_dataresp(MCU_DOWNLOAD_FAIL, write_addr, iap_sum);
-                }
-
-                iap_sum      = 0;
-                iap_index    = 0;
-                pack_receive = 0;
-            }
-            break;
-        case IAP_CMD_DOWNLOAD_END:
-            rec_page_num = rx_msg->buf[2];
-            rec_page_num = (rec_page_num << 8) | rx_msg->buf[1];
-            if (rec_page_num != total_page_num)
-            {
-                break;
-            }
-            iap_send_datafinish(total_page_num);
-            write_addr     = IAP_RUN_START_SECTOR;
-            total_page_num = 0;
-            delay_ms(300);
-            boot_goto_app(APP_ADDRESS);
-            break;
-        }
-    }
-    else
-    {
-        cnt++;
-        delay_ms(10);
-        if (cnt > 50)
-        {
-            boot_goto_app(APP_ADDRESS);
-        }
-    }
-}
-
-u8 flash_up_is_ok(void)
-{
-    u32 len = 0;
-    len     = flash_read_page(IAP_FLASH_UP_LEN);
-    if ((len > 0) && (len < 455680)) // 445K
-    {
-        return TRUE;
-    }
-    else
-    {
-        return FALSE;
-    }
-}
-
-void iap_from_flash(void)
-{
-    u32 value = 0, read_add = IAP_FLASH_UP_ADDR, write_add = IAP_RUN_START_SECTOR; // IAP_DOWN_BEGIN_ADDR;
-    u32 len = 0;
-
-    len = flash_read_page(IAP_FLASH_UP_LEN);
-
-    while (len >= 4)
-    {
-        value = flash_read_page(read_add);
-        stm_flash_write_word(write_add, value);
-        read_add += 4;
-        write_add += 4;
-        len -= 4;
-    }
-
-    for (; len > 0; len--)
-    {
-        value = flash_read_byte(read_add);
-        stm_flash_write_byte(write_add, (u8)value);
-        write_add++;
-    }
-
-    FLASH_Unlock();
-    FLASH_DataCacheCmd(DISABLE);
-    FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3);
-    FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3);
-    FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3);
-    FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
-    FLASH_DataCacheCmd(ENABLE);
-    FLASH_Lock();
-}
+// #include "iap.h"
+// #include "bootloader.h"
+// #include "can.h"
+// #include "dwt.h"
+// #include "global.h"
+// #include "stm32f4xx_flash.h"
+// #include <string.h>
+
+// static u8 iap_index = 0;
+// // static u16 iap_buf[IAP_BUF_SIZE] = {0};
+
+// void iap_connect_clear(void){
+//     iap_}
+
+// uint16_t STMFLASH_GetFlashSector(u32 addr)
+// {
+//     if (addr < ADDR_FLASH_SECTOR_1)
+//         return FLASH_Sector_0;
+//     else if (addr < ADDR_FLASH_SECTOR_2)
+//         return FLASH_Sector_1;
+//     else if (addr < ADDR_FLASH_SECTOR_3)
+//         return FLASH_Sector_2;
+//     else if (addr < ADDR_FLASH_SECTOR_4)
+//         return FLASH_Sector_3;
+//     else if (addr < ADDR_FLASH_SECTOR_5)
+//         return FLASH_Sector_4;
+//     else if (addr < ADDR_FLASH_SECTOR_6)
+//         return FLASH_Sector_5;
+//     else if (addr < ADDR_FLASH_SECTOR_7)
+//         return FLASH_Sector_6;
+//     else if (addr < ADDR_FLASH_SECTOR_8)
+//         return FLASH_Sector_7;
+//     else if (addr < ADDR_FLASH_SECTOR_9)
+//         return FLASH_Sector_8;
+//     else if (addr < ADDR_FLASH_SECTOR_10)
+//         return FLASH_Sector_9;
+//     else if (addr < ADDR_FLASH_SECTOR_11)
+//         return FLASH_Sector_10;
+//     return FLASH_Sector_11;
+// }
+
+// u8 flash_read_byte(u32 faddr)
+// {
+//     return *(vu8 *)faddr;
+// }
+
+// u16 STMFLASH_ReadHalfWord(u32 faddr)
+// {
+//     return *(vu16 *)faddr;
+// }
+
+// u32 flash_read_page(u32 faddr)
+// {
+//     return *(vu32 *)faddr;
+// }
+
+// void copy_to_runaddr(u32 end_addr)
+// {
+//     FLASH_Status status      = FLASH_COMPLETE;
+//     u32          write_addr1 = IAP_RUN_START_SECTOR, read_addr = IAP_DOWN_BEGIN_ADDR;
+//     // u8  erase_sector = 0, index = 0;
+//     u32 temp_value = 0;
+//     // erase_sector = STMFLASH_GetFlashSector(IAP_RUN_START_SECTOR);
+//     FLASH_Unlock();              // 解锁
+//     FLASH_DataCacheCmd(DISABLE); // FLASH擦除期间,必须禁止数据缓存
+//     FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
+
+//     status = FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3);
+//     if (status != FLASH_COMPLETE)
+//     {
+//         FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存
+//         FLASH_Lock();               // 上锁
+//         return;
+//     }
+//     status = FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3);
+//     if (status != FLASH_COMPLETE)
+//     {
+//         FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存
+//         FLASH_Lock();               // 上锁
+//         return;
+//     }
+
+//     while (end_addr > read_addr)
+//     {
+//         temp_value = flash_read_page(read_addr);
+//         if (FLASH_ProgramWord(write_addr1, temp_value) != FLASH_COMPLETE) // 写入数据
+//         {
+//             break; // 写入异常
+//         }
+
+//         write_addr1 += 4;
+//         read_addr += 4;
+//     }
+
+//     FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存
+//     FLASH_Lock();               // 上锁
+// }
+
+// void iap_send_dataresp(u8 res, u32 addr, u32 sum)
+// {
+//     u8 send_buf[8] = {0};
+//     send_buf[0]    = IAP_CMD_DOWNLOAD;
+
+//     send_buf[1] = addr;
+//     send_buf[2] = addr >> 8;
+//     send_buf[3] = addr >> 16;
+//     send_buf[4] = res;
+//     send_buf[5] = addr >> 24;
+//     send_buf[6] = (u8)(sum >> 8);
+//     send_buf[7] = (u8)sum;
+//     can_send_msg(send_buf, DLC_8, IAP_MCU_DATA_FRAME);
+// }
+
+// void iap_send_datafinish(u16 page_num)
+// {
+//     u8 send_buf[8] = {0};
+//     send_buf[0]    = IAP_CMD_DOWNLOAD_END;
+//     send_buf[1]    = (u8)page_num;
+//     send_buf[2]    = (u8)(page_num >> 8);
+//     send_buf[3]    = 0xFF;
+//     send_buf[4]    = 0xFF;
+//     send_buf[5]    = 0xFF;
+//     send_buf[6]    = 0xFF;
+//     send_buf[7]    = 0xFF;
+//     can_send_msg(send_buf, DLC_8, IAP_MCU_DATA_FRAME);
+// }
+
+// u8 stm_flash_write(u32 addr, u16 *array, u32 len)
+// {
+//     u8           res   = TRUE;
+//     u32          index = 0, temp_addr = addr;
+//     FLASH_Status status = FLASH_COMPLETE;
+//     FLASH_Unlock();
+//     FLASH_DataCacheCmd(DISABLE);
+//     for (index = 0; index < len;)
+//     {
+//         if (STMFLASH_ReadHalfWord(temp_addr) != 0xFFFF)
+//         {
+//             status = FLASH_EraseSector(STMFLASH_GetFlashSector(temp_addr), VoltageRange_3);
+//             if (status != FLASH_COMPLETE)
+//             {
+//                 res = FALSE;
+//                 break;
+//             }
+//         }
+//         else
+//         {
+//             index++;
+//             temp_addr += 2;
+//         }
+//     }
+//     if (status == FLASH_COMPLETE)
+//     {
+//         for (index = 0; index < len; index++)
+//         {
+//             if (FLASH_ProgramHalfWord(addr, array[index]) != FLASH_COMPLETE) // 写入数据
+//             {
+//                 res = FALSE;
+//                 // 写入异常
+//                 break;
+//             }
+//             addr += 2;
+//         }
+//     }
+//     FLASH_DataCacheCmd(ENABLE);
+//     FLASH_Lock();
+
+//     return res;
+// }
+
+// void stm_flash_write_word(u32 addr, u32 value)
+// {
+//     u32          temp_addr = addr;
+//     FLASH_Status status    = FLASH_COMPLETE;
+//     FLASH_Unlock();
+//     FLASH_DataCacheCmd(DISABLE);
+
+//     if (flash_read_page(temp_addr) != 0xFFFFFFFF)
+//     {
+//         status = FLASH_EraseSector(STMFLASH_GetFlashSector(temp_addr), VoltageRange_3);
+//         if (status != FLASH_COMPLETE)
+//         {
+//             return;
+//         }
+//     }
+
+//     if (status == FLASH_COMPLETE)
+//     {
+//         if (FLASH_ProgramWord(addr, value) != FLASH_COMPLETE) // 写入数据
+//         {
+//             return;
+//         }
+//     }
+//     FLASH_DataCacheCmd(ENABLE);
+//     FLASH_Lock();
+// }
+
+// void stm_flash_write_byte(u32 addr, u8 value)
+// {
+//     u32          temp_addr = addr;
+//     FLASH_Status status    = FLASH_COMPLETE;
+//     FLASH_Unlock();
+//     FLASH_DataCacheCmd(DISABLE);
+
+//     if (flash_read_byte(temp_addr) != 0xFF)
+//     {
+//         status = FLASH_EraseSector(STMFLASH_GetFlashSector(temp_addr), VoltageRange_3);
+//         if (status != FLASH_COMPLETE)
+//         {
+//             return;
+//         }
+//     }
+
+//     if (status == FLASH_COMPLETE)
+//     {
+//         if (FLASH_ProgramByte(addr, value) != FLASH_COMPLETE) // 写入数据
+//         {
+//             return;
+//         }
+//     }
+//     FLASH_DataCacheCmd(ENABLE);
+//     FLASH_Lock();
+// }
+
+// void iap_process(CanData_TypeDef *rx_msg)
+// {
+//     // 握手帧回复,最后一个字节为前7个字节累加和
+//     u8  handle_buf[DLC_8] = {'S', 'U', 'C', 'C', 'E', 'S', 'S', 0x19};
+//     u8  pc_frame[DLC_8]   = {'A', 'P', 'P', 'L', 'O', 'A', 'D', 0x01};
+//     u8  index = 0, pc_cmd = 0, pack_num = 0, res = 0;
+//     u16 rec_page_num = 0;
+//     u32 temp_addr    = 0;
+
+//     static u16 cnt            = 0;
+//     static u16 total_page_num = 0;
+//     static u32 iap_sum        = 0;
+//     static u32 pack_receive   = 0;
+//     static u32 write_addr = 0, old_write_addr = 0;
+
+//     if (rx_msg->can_id == IAP_PC_BEGINE_FRAME)
+//     {
+//         cnt = 0;
+//         if (memcmp(rx_msg->buf, pc_frame, 7) == 0)
+//         {
+//             total_page_num = 0;
+//             if (res == 0)
+//             {
+//                 InitQueue(&CanQueueImportant);
+//                 can_send_msg(handle_buf, DLC_8, IAP_MCU_BIGEN_FRAME);
+//                 write_addr = IAP_RUN_START_SECTOR; // IAP_DOWN_BEGIN_ADDR;
+//             }
+//             else
+//             {
+//                 return;
+//             }
+//         }
+//     }
+//     else if (rx_msg->can_id == IAP_PC_DATA_FRAME)
+//     {
+//         cnt    = 0;
+//         pc_cmd = rx_msg->buf[0];
+//         switch (pc_cmd)
+//         {
+//         case IAP_CMD_DOWNLOAD:
+//             pack_num = rx_msg->buf[1];
+//             if (pack_num == 0x01)
+//             {
+//                 iap_sum      = 0;
+//                 iap_index    = 0;
+//                 pack_receive = 0;
+//                 pack_receive |= (1 << (pack_num - 1));
+//                 write_addr = (rx_msg->buf[6] << 24) + (rx_msg->buf[5] << 16) + (rx_msg->buf[4] << 8) + rx_msg->buf[3];
+//             }
+//             else if ((pack_num > 0x01) && (pack_num < 0x17))
+//             {
+//                 if (((pack_receive & 0x00000001) != 0x00000001) || ((pack_receive & (1 << (pack_num - 1))) == (1 << (pack_num - 1))))
+//                 {
+//                     break;
+//                 }
+//                 iap_index = (pack_num - 2) * 3;
+//                 for (index = 0; index < 3; index++)
+//                 {
+//                     if (iap_index < (IAP_BUF_SIZE - 1))
+//                     {
+//                         pack_receive |= 1 << (pack_num - 1);
+//                         iap_buf[iap_index] = ((u16)rx_msg->buf[2 * index + 3] << 8) + rx_msg->buf[2 * index + 2];
+//                         iap_sum += iap_buf[iap_index];
+//                         iap_index++;
+//                     }
+//                 }
+//             }
+//             else if (pack_num == 0x17)
+//             {
+//                 if (((pack_receive & 0x00000001) != 0x00000001) || ((pack_receive & (1 << (pack_num - 1))) == (1 << (pack_num - 1))))
+//                 {
+//                     break;
+//                 }
+//                 iap_index = 63;
+//                 pack_receive |= 1 << (pack_num - 1);
+//                 iap_buf[iap_index] = ((u16)rx_msg->buf[3] << 8) + rx_msg->buf[2];
+//                 iap_sum += iap_buf[iap_index];
+//             }
+//             if ((pack_receive & 0x007FFFFF) == 0x007FFFFF)
+//             {
+//                 temp_addr = write_addr;
+//                 if ((write_addr >= ADDR_FLASH_SECTOR_4) && (write_addr <= ADDR_FLASH_SECTOR_END) && (stm_flash_write(temp_addr, iap_buf, IAP_BUF_SIZE) == TRUE))
+//                 {
+//                     iap_send_dataresp(MCU_DOWNLOAD_SUCC, write_addr, iap_sum);
+//                     if (write_addr != old_write_addr)
+//                     {
+//                         total_page_num++;
+//                         old_write_addr = write_addr;
+//                     }
+//                 }
+//                 else
+//                 {
+//                     iap_send_dataresp(MCU_DOWNLOAD_FAIL, write_addr, iap_sum);
+//                 }
+
+//                 iap_sum      = 0;
+//                 iap_index    = 0;
+//                 pack_receive = 0;
+//             }
+//             break;
+//         case IAP_CMD_DOWNLOAD_END:
+//             rec_page_num = rx_msg->buf[2];
+//             rec_page_num = (rec_page_num << 8) | rx_msg->buf[1];
+//             if (rec_page_num != total_page_num)
+//             {
+//                 break;
+//             }
+//             iap_send_datafinish(total_page_num);
+//             write_addr     = IAP_RUN_START_SECTOR;
+//             total_page_num = 0;
+//             delay_ms(300);
+//             boot_goto_app(APP_ADDRESS);
+//             break;
+//         }
+//     }
+//     else
+//     {
+//         cnt++;
+//         delay_ms(10);
+//         if (cnt > 50)
+//         {
+//             boot_goto_app(APP_ADDRESS);
+//         }
+//     }
+// }
+
+// u8 flash_up_is_ok(void)
+// {
+//     u32 len = 0;
+//     len     = flash_read_page(IAP_FLASH_UP_LEN);
+//     if ((len > 0) && (len < 455680)) // 445K
+//     {
+//         return TRUE;
+//     }
+//     else
+//     {
+//         return FALSE;
+//     }
+// }
+
+// void iap_from_flash(void)
+// {
+//     u32 value = 0, read_add = IAP_FLASH_UP_ADDR, write_add = IAP_RUN_START_SECTOR; // IAP_DOWN_BEGIN_ADDR;
+//     u32 len = 0;
+
+//     len = flash_read_page(IAP_FLASH_UP_LEN);
+
+//     while (len >= 4)
+//     {
+//         value = flash_read_page(read_add);
+//         stm_flash_write_word(write_add, value);
+//         read_add += 4;
+//         write_add += 4;
+//         len -= 4;
+//     }
+
+//     for (; len > 0; len--)
+//     {
+//         value = flash_read_byte(read_add);
+//         stm_flash_write_byte(write_add, (u8)value);
+//         write_add++;
+//     }
+
+//     FLASH_Unlock();
+//     FLASH_DataCacheCmd(DISABLE);
+//     FLASH_EraseSector(FLASH_Sector_8, VoltageRange_3);
+//     FLASH_EraseSector(FLASH_Sector_9, VoltageRange_3);
+//     FLASH_EraseSector(FLASH_Sector_10, VoltageRange_3);
+//     FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
+//     FLASH_DataCacheCmd(ENABLE);
+//     FLASH_Lock();
+// }

+ 91 - 56
applications/iap/iap.h

@@ -1,69 +1,104 @@
-#ifndef __IAP_H
-#define __IAP_H
-#include "global.h"
-#include <stm32f4xx.h>
+// #ifndef __IAP_H
+// #define __IAP_H
+// #include "global.h"
+// #include <stdint.h>
+// #include <stm32f4xx.h>
 
-#define IAP_FLASH_UP_LEN  0x8080000
-#define IAP_FLASH_UP_ADDR 0X8080004
+// #define IAP_FLASH_UP_LEN  0x8080000
+// #define IAP_FLASH_UP_ADDR 0X8080004
 
-#define IAP_RUN_START_SECTOR 0x8010000
-#define IAP_DOWN_BEGIN_ADDR  0x8080000 // iap代码下载起始地址
+// #define IAP_RUN_START_SECTOR 0x8010000
+// #define IAP_DOWN_BEGIN_ADDR  0x8080000 // iap代码下载起始地址
 
-#define IAP_BACKUP_SECTOR1 10
-#define IAP_BACKUP_SECTOR2 11
+// #define IAP_BACKUP_SECTOR1 10
+// #define IAP_BACKUP_SECTOR2 11
 
-#define IAP_PC_BEGINE_FRAME 0x18CFD0EF
-#define IAP_PC_DATA_FRAME   0x18CED0EF
+// #define IAP_PC_BEGINE_FRAME 0x18CFD0EF
+// #define IAP_PC_DATA_FRAME   0x18CED0EF
 
-#define IAP_MCU_BIGEN_FRAME 0x18CFEFD0
-#define IAP_MCU_DATA_FRAME  0x18CEEFD0
+// #define IAP_MCU_BIGEN_FRAME 0x18CFEFD0
+// #define IAP_MCU_DATA_FRAME  0x18CEEFD0
 
-#define IAP_CMD_CHECK        0x01 // 请求校验
-#define IAP_CMD_DOWNLOAD     0x02 // 数据下载
-#define IAP_CMD_DOWNLOAD_END 0x03 // 下载代码完成
-#define IAP_CMD_READ         0x04 // 读取下发帧内容
-#define IAP_CMD_DOWNLOAD_SUC 0X05 // 下载成功
+// #define UPGRADE_FLASH_DATA_SIZE 4                                                 // 升级参数数组元素个数
+// #define UPGRADE_APP_DATA_SIZE   4                                                 // 升级参数数组元素个数
+// #define UPGRADE_BUFF_DATA_SIZE  (UPGRADE_FLASH_DATA_SIZE + UPGRADE_APP_DATA_SIZE) // 升级参数数组元素个数
 
-#define IAP_BUF_SIZE 0x40
-#define MAX_PACK_NUM 0x17
+// #define IAP_CMD_VERSION 0x71 // 查询版本号
+// #define IAP_CMD_INFO    0x72 // 包信息
+// #define IAP_CMD_ERASE   0x73 // 擦除命令
+// #define IAP_CMD_DATA    0x80 // 数据帧 IAP_CMD_DATA |帧号
+// #define IAP_CMD_CRC     0x74 // 传输结果校验
+// #define IAP_CMD_OVER    0x76 // 执行跳转
 
-#define MCU_DOWNLOAD_SUCC 0x01
-#define MCU_DOWNLOAD_FAIL 0x02
+// typedef union
+// {
+//     uint16_t u8_buf[8];
+//     uint16_t u16_buf[4];
+// } u16_u8;
 
-#define IAP_UP_BEGINNING 0x37377373
-#define IAP_UP_SUCCESS   0x59599595
-#define IAP_UP_FAIL      0x6A6AA6A6
+// typedef union
+// {
+//     uint16_t u8_save[200];
+//     uint16_t u16_save[100];
+// } u16save_u8save;
 
-// FLASH 扇区的起始地址
-#define ADDR_FLASH_SECTOR_0   ((u32)0x08000000) // 扇区0起始地址, 16 Kbytes
-#define ADDR_FLASH_SECTOR_1   ((u32)0x08004000) // 扇区1起始地址, 16 Kbytes
-#define ADDR_FLASH_SECTOR_2   ((u32)0x08008000) // 扇区2起始地址, 16 Kbytes
-#define ADDR_FLASH_SECTOR_3   ((u32)0x0800C000) // 扇区3起始地址, 16 Kbytes
-#define ADDR_FLASH_SECTOR_4   ((u32)0x08010000) // 扇区4起始地址, 64 Kbytes
-#define ADDR_FLASH_SECTOR_5   ((u32)0x08020000) // 扇区5起始地址, 128 Kbytes
-#define ADDR_FLASH_SECTOR_6   ((u32)0x08040000) // 扇区6起始地址, 128 Kbytes
-#define ADDR_FLASH_SECTOR_7   ((u32)0x08060000) // 扇区7起始地址, 128 Kbytes
-#define ADDR_FLASH_SECTOR_8   ((u32)0x08080000) // 扇区8起始地址, 128 Kbytes
-#define ADDR_FLASH_SECTOR_9   ((u32)0x080A0000) // 扇区9起始地址, 128 Kbytes
-#define ADDR_FLASH_SECTOR_10  ((u32)0x080C0000) // 扇区10起始地址,128 Kbytes
-#define ADDR_FLASH_SECTOR_11  ((u32)0x080E0000) // 扇区11起始地址,128 Kbytes
-#define ADDR_FLASH_SECTOR_END ((u32)0x080FFFFF)
+// typedef struct
+// {
+//     uint16_t       total_packages;
+//     uint16_t       current_packages;
+//     uint16_t       count_packages;
+//     uint16_t       recv_len;
+//     uint16_t       crc16;
+//     uint16_t       firmware_crc16;
+//     uint16_t       firmware_ver;
+//     uint16_t       total_bytes;
+//     uint16_t       count_bytes;
+//     u16_u8         flash_data;
+//     u16_u8         recheck_data;
+//     u16save_u8save save_data;
+// } iap_type;
 
-typedef enum
-{
-    DISCONNECT = 0,
-    HANDSHAKE,
-    PROGRAMING,
-    PROGRAMFinish,
-} workmode;
+// typedef union
+// {
+//     struct
+//     {
+//         uint16_t sign;        // 首地址 buf[0]
+//         uint16_t crc16;       // 中地址 buf[1]
+//         uint32_t moving_size; // 高地址 buf[2] buf[3]
+//     } param;
+//     uint16_t infor_buf[UPGRADE_FLASH_DATA_SIZE];
+// } upgrade_param; // 升级参数使用
 
-typedef union
-{
-    u8  value[4];
-    u32 cmd;
-} IAP_Union;
+// // FLASH 扇区的起始地址
+// #define ADDR_FLASH_SECTOR_0   ((u32)0x08000000) // 扇区0起始地址, 16 Kbytes
+// #define ADDR_FLASH_SECTOR_1   ((u32)0x08004000) // 扇区1起始地址, 16 Kbytes
+// #define ADDR_FLASH_SECTOR_2   ((u32)0x08008000) // 扇区2起始地址, 16 Kbytes
+// #define ADDR_FLASH_SECTOR_3   ((u32)0x0800C000) // 扇区3起始地址, 16 Kbytes
+// #define ADDR_FLASH_SECTOR_4   ((u32)0x08010000) // 扇区4起始地址, 64 Kbytes
+// #define ADDR_FLASH_SECTOR_5   ((u32)0x08020000) // 扇区5起始地址, 128 Kbytes
+// #define ADDR_FLASH_SECTOR_6   ((u32)0x08040000) // 扇区6起始地址, 128 Kbytes
+// #define ADDR_FLASH_SECTOR_7   ((u32)0x08060000) // 扇区7起始地址, 128 Kbytes
+// #define ADDR_FLASH_SECTOR_8   ((u32)0x08080000) // 扇区8起始地址, 128 Kbytes
+// #define ADDR_FLASH_SECTOR_9   ((u32)0x080A0000) // 扇区9起始地址, 128 Kbytes
+// #define ADDR_FLASH_SECTOR_10  ((u32)0x080C0000) // 扇区10起始地址,128 Kbytes
+// #define ADDR_FLASH_SECTOR_11  ((u32)0x080E0000) // 扇区11起始地址,128 Kbytes
+// #define ADDR_FLASH_SECTOR_END ((u32)0x080FFFFF)
 
-void iap_process(CanData_TypeDef *rx_msg);
-u8   flash_up_is_ok(void);
-void iap_from_flash(void);
-#endif
+// typedef enum
+// {
+//     DISCONNECT = 0,
+//     HANDSHAKE,
+//     PROGRAMING,
+//     PROGRAMFinish,
+// } workmode;
+
+// typedef union
+// {
+//     u8  value[4];
+//     u32 cmd;
+// } IAP_Union;
+
+// void iap_process(CanData_TypeDef *rx_msg);
+// u8   flash_up_is_ok(void);
+// void iap_from_flash(void);
+// #endif

+ 111 - 17
applications/main.c

@@ -1,47 +1,141 @@
 #include "board.h"
 #include "bootloader.h"
+#include "core_cmFunc.h"
+#include "dev_iap.h"
 #include "global.h"
+#include "hal_flash.h"
 #include "iap.h"
 #include "queue.h"
 #include "stm32f4xx_gpio.h"
 #include "system_stm32f4xx.h"
+#include <stdint.h>
 #include <stm32f4xx.h>
 
-extern SqQueue CanQueueImportant; // CAN重要数据队列
+extern SqQueue CanQueueImportant; // CAN锟斤拷要锟斤拷锟捷讹拷锟斤拷
+uint16_t       cache_buf[1024] = {0};
 
 int main(void)
 {
     rt_hw_board_init();
-
-    u16             cnt = 0;
+    uint32_t        w_size = 0;
+    u16             cnt    = 0;
     CanData_TypeDef element;
 
     rt_pin_mode(RED_LED_PIN, PIN_MODE_OUTPUT);
     rt_pin_mode(GREEN_LED_PIN, PIN_MODE_OUTPUT);
     InitQueue(&CanQueueImportant);
+    can_init();
 
-    while (1)
+    iap_param_init();
+    fmc_read_n_half_word(UPGRADE_FLAG_START_ADDR, upgrade.infor_buf, 4);
+
+    if (upgrade.param.sign == UPGRADE_SIGN)
     {
-        if (GetHead(&CanQueueImportant, &element) != ERROR)
+        if (check_addr_sp(DOWNLOAD_START_ADDR))
         {
-            cnt = 0;
-            delay_ms(1000);
-            GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
-            iap_process(&element);
+            fmc_clear_flag_star();
+            erase_app_flash(APP_START_ADDR, APP_END_ADDR);
+            while (w_size < upgrade.param.moving_size)
+            {
+                if ((upgrade.param.moving_size - w_size) > FMC_PAGE_SIZE)
+                {
+                    fmc_read_n_half_word(DOWNLOAD_START_ADDR + w_size, cache_buf, FMC_PAGE_SIZE_U16);
+                    fmc_write_n_half_word(APP_START_ADDR + w_size, cache_buf, FMC_PAGE_SIZE_U16);
+                    w_size += FMC_PAGE_SIZE;
+                }
+                else
+                {
+                    if (((upgrade.param.moving_size - w_size) % 2) != 0)
+                        w_size--;
+                    fmc_read_n_half_word(DOWNLOAD_START_ADDR + w_size, cache_buf, (upgrade.param.moving_size - w_size) / 2);
+                    fmc_write_n_half_word(APP_START_ADDR + w_size, cache_buf, (upgrade.param.moving_size - w_size) / 2);
+                    w_size = upgrade.param.moving_size;
+                }
+            }
+            fmc_clear_flag_end();
+
+            if (check_addr_sp(APP_START_ADDR) && check_addr_pc(APP_START_ADDR + 4))
+            {
+                CAN_DeInit(CAN1);
+                __set_PRIMASK(1);
+                boot_goto_app();
+            }
+            else
+            {
+                iap_flag_release();
+            }
         }
-        else if (flash_up_is_ok() == TRUE)
+        else
         {
-            iap_from_flash();
-            boot_goto_app(APP_ADDRESS);
+            iap_flag_release();
+            CAN_DeInit(CAN1);
+            __set_PRIMASK(1);
+            boot_goto_app();
         }
-        else
+    }
+
+    if (INVALID == check_addr_sp(APP_START_ADDR))
+    {
+        if (check_addr_sp(DOWNLOAD_START_ADDR))
         {
-            cnt++;
-            delay_ms(10);
-            if (cnt > 100)
+            fmc_clear_flag_star();
+            erase_app_flash(APP_START_ADDR, APP_END_ADDR);
+            while (w_size < upgrade.param.moving_size)
+            {
+                if ((upgrade.param.moving_size - w_size) > FMC_PAGE_SIZE)
+                {
+                    fmc_read_n_half_word(DOWNLOAD_START_ADDR + w_size, cache_buf, FMC_PAGE_SIZE_U16);
+                    fmc_write_n_half_word(APP_START_ADDR + w_size, cache_buf, FMC_PAGE_SIZE_U16);
+                    w_size += FMC_PAGE_SIZE;
+                }
+                else
+                {
+                    if (((upgrade.param.moving_size - w_size) % 2) != 0)
+                        w_size--;
+                    fmc_read_n_half_word(DOWNLOAD_START_ADDR + w_size, cache_buf, (upgrade.param.moving_size - w_size) / 2);
+                    fmc_write_n_half_word(APP_START_ADDR + w_size, cache_buf, (upgrade.param.moving_size - w_size) / 2);
+                    w_size = upgrade.param.moving_size;
+                }
+            }
+            fmc_clear_flag_end();
+
+            if (check_addr_sp(APP_START_ADDR) && check_addr_pc(APP_START_ADDR))
             {
-                boot_goto_app(APP_ADDRESS);
+                CAN_DeInit(CAN1);
+                __set_PRIMASK(1);
+                boot_goto_app();
             }
         }
     }
+    else
+    {
+        CAN_DeInit(CAN1);
+        __set_PRIMASK(1);
+        boot_goto_app();
+    }
+
+    while (1)
+    {
+        // if (GetHead(&CanQueueImportant, &element) != ERROR)
+        // {
+        //     cnt = 0;
+        //     // delay_ms(1000);
+        //     GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
+        //     iap_process(&element);
+        // }
+        // else if (flash_up_is_ok() == TRUE)
+        // {
+        //     iap_from_flash();
+        //     boot_goto_app();
+        // }
+        // else
+        // {
+        //     cnt++;
+        //     delay_ms(10);
+        //     if (cnt > 100)
+        //     {
+        //         boot_goto_app();
+        //     }
+        // }
+    }
 }

+ 1 - 1
board/board.c

@@ -6,7 +6,7 @@ void rt_hw_board_init()
     rt_hw_pin_init();
 
     dwt_init();
-    can_init();
+    // can_init();
 
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
 }

+ 6 - 6
board/can/can.c

@@ -33,20 +33,20 @@ u8 CAN2_Mode_Init(u8 tsjw, u8 tbs2, u8 tbs1, u16 brp, u8 mode)
     u32 mask_id = MASK_ID;
 
     // 使能相关时钟
-    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // 使能PORTA时钟
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能PORTA时钟
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);  // 使能CAN1时钟
 
     // 初始化GPIO
-    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_12 | GPIO_Pin_13;
+    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11 | GPIO_Pin_12;
     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;      // 复用功能
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     // 推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz
     GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;      // 上拉
-    GPIO_Init(GPIOB, &GPIO_InitStructure);             // 初始化PA11,PA12
+    GPIO_Init(GPIOA, &GPIO_InitStructure);             // 初始化PA11,PA12
 
     // 引脚复用映射配置
-    GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); // GPIOB11复用为CAN1
-    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); // GPIOB12复用为CAN1
+    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_CAN1); // GPIOB11复用为CAN1
+    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1); // GPIOB12复用为CAN1
 
     // CAN单元设置
     CAN_InitStructure.CAN_TTCM      = DISABLE; // 非时间触发通信模式
@@ -140,7 +140,7 @@ u8 can_send_msg(u8 *msg, u8 len, u32 can_id)
 }
 
 // CAN1中断服务函数
-void CAN2_RX0_IRQHandler(void)
+void CAN1_RX0_IRQHandler(void)
 {
     // 1.6us  ucos时间戳、示波器测量都是1.6us
     CAN_Receive(CAN1, CAN_FIFO0, &RxMessageImportant);

+ 180 - 0
board/hal_flash.c

@@ -0,0 +1,180 @@
+/************************************************************************************************
+ *                                          Include                                              *
+ ************************************************************************************************/
+
+#include "hal_flash.h"
+#include "stm32f4xx.h"
+#include <stdint.h>
+
+/************************************************************************************************
+ *                                          Config                                                *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          Data structs                                         *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          implements                                           *
+ ************************************************************************************************/
+uint16_t fmc_get_flash_sector(u32 addr)
+{
+    if (addr < ADDR_FLASH_SECTOR_1)
+        return FLASH_Sector_0;
+    else if (addr < ADDR_FLASH_SECTOR_2)
+        return FLASH_Sector_1;
+    else if (addr < ADDR_FLASH_SECTOR_3)
+        return FLASH_Sector_2;
+    else if (addr < ADDR_FLASH_SECTOR_4)
+        return FLASH_Sector_3;
+    else if (addr < ADDR_FLASH_SECTOR_5)
+        return FLASH_Sector_4;
+    else if (addr < ADDR_FLASH_SECTOR_6)
+        return FLASH_Sector_5;
+    else if (addr < ADDR_FLASH_SECTOR_7)
+        return FLASH_Sector_6;
+    else if (addr < ADDR_FLASH_SECTOR_8)
+        return FLASH_Sector_7;
+    else if (addr < ADDR_FLASH_SECTOR_9)
+        return FLASH_Sector_8;
+    else if (addr < ADDR_FLASH_SECTOR_10)
+        return FLASH_Sector_9;
+    else if (addr < ADDR_FLASH_SECTOR_11)
+        return FLASH_Sector_10;
+    return FLASH_Sector_11;
+}
+
+// 解除写保护,清除fmc特定寄存器
+void fmc_clear_flag_star(void)
+{
+    FLASH_Unlock();              // 解锁
+    FLASH_DataCacheCmd(DISABLE); // FLASH擦除期间,必须禁止数据缓存
+    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
+}
+
+// 设置写保护,清除fmc特定寄存器
+void fmc_clear_flag_end(void)
+{
+    FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存
+    FLASH_Lock();               // 上锁
+}
+
+// 读取一字节, 读取无需考虑字节对齐
+uint8_t fmc_read_byte(uint32_t read_addr)
+{
+    return *(vu8 *)read_addr;
+}
+
+// 读取两字节, 读取需考虑字节对齐
+uint16_t fmc_read_half_word(uint32_t read_addr)
+{
+    return *(vu16 *)read_addr;
+}
+
+// 读取N字节, 读取必须需考虑字节对齐
+uint8_t fmc_read_n_half_word(uint32_t read_addr, uint16_t *buff, uint16_t count)
+{
+    uint16_t i = 0;
+
+    vu16 *addr = (vu16 *)read_addr;
+
+    if (read_addr % 2 != 0)
+        return 1; // 错误返回
+
+    for (i = 0; i < count; i++)
+    {
+        *buff++ = *addr++;
+    }
+    return 0;
+}
+
+// 读取1页, 地址必须对齐页首
+uint8_t fmc_read_one_page(uint32_t read_addr, uint16_t *buff)
+{
+    uint16_t i = 0;
+
+    vu16 *addr = (vu16 *)read_addr;
+
+    if (read_addr % FMC_PAGE_SIZE != 0)
+        return 1; // 错误返回
+
+    for (i = 0; i < 1024; i++)
+    {
+        *buff++ = *addr++;
+    }
+    return 0;
+}
+
+// 擦出N页, 地址必须对齐页首
+uint8_t fmc_erase_pages(uint32_t erase_addr, uint16_t len)
+{
+    uint8_t status = 0;
+    status         = FLASH_EraseSector(fmc_get_flash_sector(erase_addr), VoltageRange_3);
+    if (status != FLASH_COMPLETE)
+    {
+        return 1;
+    }
+    return 0;
+    // uint16_t i = 0, j = 0;
+
+    // uint32_t *addr = (uint32_t *)erase_addr;
+
+    // if (erase_addr % FMC_PAGE_SIZE != 0)
+    //     return 1; // 错误返回
+
+    // for (i = 0; i < len; i++)
+    // {
+    //     FLASH_EraseSector(fmc_get_flash_sector(erase_addr), VoltageRange_3);
+    //     for (j = 0; j < 512; j++)
+    //     {
+    //         if (*addr != 0xFFFFFFFF)
+    //             return 1;
+    //         else
+    //             addr++;
+    //     }
+    // }
+    // return 0;
+}
+
+// 只写入,写入前需擦除,地址必须两字节对齐
+uint8_t fmc_write_n_half_word(uint32_t write_addr, uint16_t *buff, uint16_t len)
+{
+
+    uint32_t end_addr = write_addr + len * 2;
+
+    if (write_addr % 2 != 0)
+        return 1;
+
+    while (write_addr < end_addr)
+    {
+
+        FLASH_ProgramHalfWord(write_addr, *buff); // 写入数据
+        if (*(vu16 *)write_addr != *buff)
+        {
+            return 1;
+        }
+        write_addr += 2;
+        buff++;
+    }
+    return 0;
+}
+
+uint16_t firmware_crc16_ccitt_false(uint16_t init_value, uint8_t *pbuff, uint32_t len)
+{
+    uint16_t temp = 0;
+    uint16_t crc  = init_value;
+
+    for (int i = 0; i < len; i++)
+    {
+        for (int j = 0; j < 8; j++)
+        {
+            temp = ((pbuff[i] << j) & 0x80) ^ ((crc & 0x8000) >> 8);
+            crc <<= 1;
+            if (temp != 0)
+            {
+                crc ^= 0x1021;
+            }
+        }
+    }
+    return crc;
+}

+ 69 - 0
board/hal_flash.h

@@ -0,0 +1,69 @@
+#ifndef __HAL_FLASH_H
+#define __HAL_FLASH_H
+
+#ifdef __cplusplus
+extern 'C'
+{
+#endif
+#ifdef __HAL_FLASH_H_GLOBAL
+#define __HAL_FLASH_H_EXTERN
+#else
+#define __HAL_FLASH_H_EXTERN extern
+#endif
+
+/************************************************************************************************
+ *                                          Version                                              *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          How to use                                           *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          Enable config                                         *
+ ************************************************************************************************/
+
+/************************************************************************************************
+ *                                          Includes                                             *
+ ************************************************************************************************/
+#include "stm32f4xx_flash.h"
+/************************************************************************************************
+ *                                          Defines                                              *
+ ************************************************************************************************/
+#define FMC_PAGE_SIZE     ((uint16_t)0x800)
+#define FMC_PAGE_SIZE_U16 ((uint16_t)0x400)
+#define FMC_FLASH_BASE    ((uint32_t)0x08000000)
+
+// FLASH 扇区的起始地址
+#define ADDR_FLASH_SECTOR_0   ((u32)0x08000000) // 扇区0起始地址, 16 Kbytes
+#define ADDR_FLASH_SECTOR_1   ((u32)0x08004000) // 扇区1起始地址, 16 Kbytes
+#define ADDR_FLASH_SECTOR_2   ((u32)0x08008000) // 扇区2起始地址, 16 Kbytes
+#define ADDR_FLASH_SECTOR_3   ((u32)0x0800C000) // 扇区3起始地址, 16 Kbytes
+#define ADDR_FLASH_SECTOR_4   ((u32)0x08010000) // 扇区4起始地址, 64 Kbytes
+#define ADDR_FLASH_SECTOR_5   ((u32)0x08020000) // 扇区5起始地址, 128 Kbytes
+#define ADDR_FLASH_SECTOR_6   ((u32)0x08040000) // 扇区6起始地址, 128 Kbytes
+#define ADDR_FLASH_SECTOR_7   ((u32)0x08060000) // 扇区7起始地址, 128 Kbytes
+#define ADDR_FLASH_SECTOR_8   ((u32)0x08080000) // 扇区8起始地址, 128 Kbytes
+#define ADDR_FLASH_SECTOR_9   ((u32)0x080A0000) // 扇区9起始地址, 128 Kbytes
+#define ADDR_FLASH_SECTOR_10  ((u32)0x080C0000) // 扇区10起始地址,128 Kbytes
+#define ADDR_FLASH_SECTOR_11  ((u32)0x080E0000) // 扇区11起始地址,128 Kbytes
+#define ADDR_FLASH_SECTOR_END ((u32)0x080FFFFF)
+    /************************************************************************************************
+     *                                          Defines                                              *
+     ************************************************************************************************/
+
+    void     fmc_clear_flag_star(void);
+    void     fmc_clear_flag_end(void);
+    uint8_t  fmc_read_byte(uint32_t read_addr);
+    uint16_t fmc_read_half_word(uint32_t read_addr);
+    uint8_t  fmc_read_n_half_word(uint32_t read_addr, uint16_t * buff, uint16_t count);
+    uint8_t  fmc_read_one_page(uint32_t read_addr, uint16_t * buff);
+    uint8_t  fmc_erase_pages(uint32_t erase_addr, uint16_t len);
+    uint8_t  fmc_write_n_half_word(uint32_t write_addr, uint16_t * buff, uint16_t len);
+    uint16_t firmware_crc16_ccitt_false(uint16_t init_value, uint8_t * pbuff, uint32_t len);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // __HAL_FLASH_H

+ 40 - 0
task/app_task.c

@@ -0,0 +1,40 @@
+#include "app_task.h"
+#include "app_can.h"
+#include "cli.h"
+#include "hal_led.h"
+#include "stdio.h"
+
+#define DB_TASK_LED_IDX (10)
+
+const uint32_t task_ass[8][2] = {
+    {5, 0},    // task0 周期:5ms, 延迟:0
+    {10, 2},   // task1 周期:10ms, 延迟:1
+    {20, 3},   // task2 周期:100ms, 延迟:2
+    {200, 4},  // task3 周期:200ms, 延迟:3
+    {500, 5},  // task4 周期:500ms, 延迟:4
+    {1000, 6}, // task5 周期:1000ms, 延迟:5
+    {1000, 7}, // task6 周期:0ms, 延迟:6
+    {1500, 8}, // task7 周期:0ms, 延迟:7
+};
+
+volatile uint32_t sys_run_time_u32 = 0;
+
+void task0(void)
+{
+    can_process();
+};
+
+void task1(void) {};
+void task2(void) {};
+void task3(void) {};
+void task4(void) {};
+
+void task5(void)
+{
+    sys_run_time_u32++;
+    // printf("RUNNING\r\n");
+    LED_RUN = !LED_RUN;
+};
+
+void task6(void) {};
+void task7(void) {};

+ 16 - 0
task/app_task.h

@@ -0,0 +1,16 @@
+#ifndef __APP_TASK_H
+#define __APP_TASK_H
+
+#include <stdint.h>
+extern const uint32_t task_ass[8][2];
+
+void task0(void);
+void task1(void);
+void task2(void);
+void task3(void);
+void task4(void);
+void task5(void);
+void task6(void);
+void task7(void);
+
+#endif

+ 115 - 0
task/schedule.c

@@ -0,0 +1,115 @@
+#include "schedule.h"
+#include "app_task.h"
+
+#define task0_mask 0x0000
+#define task1_mask 0x0001
+#define task2_mask 0x0003
+#define task3_mask 0x0007
+#define task4_mask 0x000F
+#define task5_mask 0x001F
+#define task6_mask 0x003F
+#define task7_mask 0x007F
+#define task8_mask 0x00FF
+
+#define TASK_MAX_QTY 8
+
+typedef struct
+{
+
+    uint32_t period;
+    uint32_t delay;
+} tag_task_list;
+
+typedef union
+{
+    struct
+    {
+        uint8_t task0_flag : 1;
+        uint8_t task1_flag : 1;
+        uint8_t task2_flag : 1;
+        uint8_t task3_flag : 1;
+        uint8_t task4_flag : 1;
+        uint8_t task5_flag : 1;
+        uint8_t task6_flag : 1;
+        uint8_t task7_flag : 1;
+        uint8_t task8_flag : 1;
+    } bits;
+
+    uint8_t all;
+} tag_tscw;
+
+tag_task_list task_list[TASK_MAX_QTY];
+tag_tscw      tscw;
+
+void schedule(void)
+{
+    if (tscw.bits.task0_flag)
+    {
+        task0();
+        tscw.bits.task0_flag = 0;
+    }
+    if (tscw.bits.task1_flag && (!(tscw.all & task1_mask)))
+    {
+        task1();
+        tscw.bits.task1_flag = 0;
+    }
+    if (tscw.bits.task2_flag && (!(tscw.all & task2_mask)))
+    {
+        task2();
+        tscw.bits.task2_flag = 0;
+    }
+    if (tscw.bits.task3_flag && (!(tscw.all & task3_mask)))
+    {
+        task3();
+        tscw.bits.task3_flag = 0;
+    }
+    if (tscw.bits.task4_flag && (!(tscw.all & task4_mask)))
+    {
+        task4();
+        tscw.bits.task4_flag = 0;
+    }
+    if (tscw.bits.task5_flag && (!(tscw.all & task5_mask)))
+    {
+        task5();
+        tscw.bits.task5_flag = 0;
+    }
+    if (tscw.bits.task6_flag && (!(tscw.all & task6_mask)))
+    {
+        task6();
+        tscw.bits.task6_flag = 0;
+    }
+    if (tscw.bits.task7_flag && (!(tscw.all & task7_mask)))
+    {
+        task7();
+        tscw.bits.task7_flag = 0;
+    }
+}
+
+void schedule_init(uint32_t task_period)
+{
+    uint32_t i;
+    for (i = 0; i < TASK_MAX_QTY; i++)
+    {
+        task_list[i].period = task_ass[i][0] / task_period;
+        task_list[i].delay  = task_ass[i][1] / task_period;
+    }
+}
+
+void schedule_clock(void)
+{
+    static volatile uint32_t sys_tick_count = 0;
+    uint8_t                  i              = 0;
+    sys_tick_count++;
+    for (i = 0; i < TASK_MAX_QTY; i++)
+    {
+        if (sys_tick_count % task_list[i].period == task_list[i].delay)
+        {
+            tscw.all |= 0x01 << i;
+        }
+    }
+
+    if (sys_tick_count > 4000000000)
+    {
+        sys_tick_count = 0;
+    }
+}

+ 14 - 0
task/schedule.h

@@ -0,0 +1,14 @@
+#ifndef __SCHEDULE_H
+#define __SCHEDULE_H
+
+#include <stdint.h>
+
+#define TASK_PERIOD (1)
+
+void schedule(void);
+
+void schedule_init(uint32_t task_period);
+
+void schedule_clock(void);
+
+#endif