|
@@ -0,0 +1,286 @@
|
|
|
+/************************************************************************************************
|
|
|
+ * Include *
|
|
|
+ ************************************************************************************************/
|
|
|
+
|
|
|
+#include "iap.h"
|
|
|
+#include "can_task.h"
|
|
|
+#include "flash.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);
|
|
|
+ }
|
|
|
+ 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 jump_boot_time_ctrl(void)
|
|
|
+{
|
|
|
+ if (jump_boot_time > 0)
|
|
|
+ {
|
|
|
+ jump_boot_time--;
|
|
|
+ if (jump_boot_time == 0)
|
|
|
+ {
|
|
|
+ // jump_flag = 1;
|
|
|
+ __set_FAULTMASK(1); // 关闭所有中断
|
|
|
+ NVIC_SystemReset(); // 复位
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+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_DATA_SIZE * 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);
|
|
|
+ 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;
|
|
|
+ break;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ send_buff[0] = IAP_CMD_JUMP;
|
|
|
+ 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(0x18DFE1F4, 8, send_buff);
|
|
|
+}
|