iap.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /************************************************************************************************
  2. * Include *
  3. ************************************************************************************************/
  4. #include "iap.h"
  5. #include "can_task.h"
  6. #include "flash.h"
  7. #include <stdint.h>
  8. #include <string.h>
  9. /************************************************************************************************
  10. * Config *
  11. ************************************************************************************************/
  12. extern uint8_t jump_flag;
  13. uint8_t can_rx_flag;
  14. // extern can_receive_message receive_iap_message;
  15. static uint16_t jump_boot_time = 0;
  16. uint8_t send_buff[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  17. unsigned char recv_crc[2];
  18. unsigned char recvdata_ema[204];
  19. unsigned char recvdata_buffer[210];
  20. uint16_t firm_ver[UPGRADE_APP_DATA_SIZE] = {IAP_CMD_JUMP_OVER};
  21. uint16_t firm_ver_buff[UPGRADE_BUFF_DATA_SIZE] = {0};
  22. uint8_t iap_disconnect_count = 0;
  23. /************************************************************************************************
  24. * Data structs *
  25. ************************************************************************************************/
  26. iap_type g_iap;
  27. upgrade_param upgrade;
  28. /************************************************************************************************
  29. * implements *
  30. ************************************************************************************************/
  31. void invert_uint8()
  32. {
  33. }
  34. void iap_connect_clear(void)
  35. {
  36. iap_disconnect_count = 0;
  37. send_buff[0] = 0x00;
  38. send_buff[1] = 0x00;
  39. send_buff[2] = 0x00;
  40. send_buff[3] = 0x00;
  41. send_buff[4] = 0x00;
  42. send_buff[5] = 0x00;
  43. send_buff[6] = 0x00;
  44. send_buff[7] = 0x00;
  45. }
  46. void iap_disconnect_check(void)
  47. {
  48. if (++iap_disconnect_count >= 5)
  49. {
  50. iap_disconnect_count = 5;
  51. }
  52. }
  53. // iap相关参数初始化
  54. void iap_param_init(void)
  55. {
  56. g_iap.recv_len = 0;
  57. g_iap.total_packages = 0;
  58. g_iap.current_packages = 0;
  59. g_iap.crc16 = 0xFFFF;
  60. g_iap.total_bytes = 0;
  61. g_iap.count_bytes = 0;
  62. g_iap.count_packages = 0;
  63. g_iap.firmware_crc16 = 0;
  64. g_iap.firmware_ver = 0;
  65. }
  66. // 清除升级信息标志位
  67. void set_firmver(void)
  68. {
  69. fmc_clear_flag_star();
  70. fmc_read_n_half_word(UPGRADE_FLAG_START_ADDR, firm_ver_buff, UPGRADE_BUFF_DATA_SIZE);
  71. fmc_erase_pages(UPGRADE_FLAG_START_ADDR, 1);
  72. fmc_write_n_half_word(UPGRADE_FLAG_START_ADDR, firm_ver_buff, UPGRADE_BUFF_DATA_SIZE);
  73. fmc_clear_flag_end();
  74. }
  75. void iap_flag_release(void)
  76. {
  77. fmc_read_n_half_word(UPGRADE_FLAG_START_ADDR, upgrade.infor_buf, UPGRADE_FLAG_DATA_SIZE);
  78. if (upgrade.param.sign == UPGRADE_SIGN)
  79. {
  80. fmc_clear_flag_star();
  81. fmc_erase_pages(UPGRADE_FLAG_START_ADDR, 1);
  82. fmc_write_n_half_word(UPGRADE_FLAG_START_ADDR + (UPGRADE_FLAG_DATA_SIZE * 2), firm_ver,
  83. UPGRADE_APP_DATA_SIZE);
  84. fmc_clear_flag_end();
  85. for (uint8_t i = 0; i < (UPGRADE_APP_DATA_SIZE * 2); i++)
  86. {
  87. send_buff[i] =
  88. fmc_read_byte(UPGRADE_FLAG_START_ADDR + (UPGRADE_FLAG_DATA_SIZE * 2) + i);
  89. }
  90. CAN_IT_TME_ENABLE();
  91. }
  92. }
  93. uint8_t erase_app_flash(uint32_t start_address, uint32_t end_addr)
  94. {
  95. uint8_t status = 0;
  96. uint16_t page_len = 0;
  97. page_len = (end_addr - start_address) / FMC_PAGE_SIZE;
  98. status = fmc_erase_pages(start_address, page_len);
  99. return status;
  100. }
  101. void jump_boot_time_ctrl(void)
  102. {
  103. if (jump_boot_time > 0)
  104. {
  105. jump_boot_time--;
  106. if (jump_boot_time == 0)
  107. {
  108. // jump_flag = 1;
  109. __set_FAULTMASK(1); // 关闭所有中断
  110. NVIC_SystemReset(); // 复位
  111. }
  112. }
  113. }
  114. void write_app_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
  115. {
  116. static uint32_t w_start_addr = 0;
  117. w_start_addr = pack_num * 6 + APP_START_ADDR;
  118. fmc_write_n_half_word(w_start_addr, buf, pack_len);
  119. }
  120. void read_app_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
  121. {
  122. static uint32_t w_start_addr = 0;
  123. w_start_addr = pack_num * 6 + APP_START_ADDR;
  124. fmc_read_n_half_word(w_start_addr, buf, pack_len);
  125. }
  126. uint8_t write_download_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
  127. {
  128. uint8_t status = 0;
  129. static uint32_t w_start_addr = 0;
  130. w_start_addr = pack_num * 6 + DOWNLOAD_START_ADDR;
  131. status = fmc_write_n_half_word(w_start_addr, buf, pack_len);
  132. return status;
  133. }
  134. void read_download_flash(uint16_t *buf, uint16_t pack_len, uint16_t pack_num)
  135. {
  136. static uint32_t w_start_addr = 0;
  137. w_start_addr = pack_num * 6 + DOWNLOAD_START_ADDR;
  138. fmc_read_n_half_word(w_start_addr, buf, pack_len);
  139. }
  140. void iap_rec_handler(pdu_tag rec_msg)
  141. {
  142. uint8_t erase_flag = 0x01;
  143. // ota_can_id = rec_msg.id.r;
  144. if (rec_msg.data.u8_buf[0] != IAP_CMD_VERSION)
  145. iap_connect_clear();
  146. if (rec_msg.data.u8_buf[0] >> 7)
  147. {
  148. if (rec_msg.id.b.sa == 0xE1)
  149. {
  150. g_iap.recv_len = rec_msg.reg.dlc - 2;
  151. g_iap.current_packages =
  152. ((uint16_t)(rec_msg.data.u8_buf[0] & 0x7F) << 8) | rec_msg.data.u8_buf[1];
  153. memcpy(g_iap.flash_data.u8_buf, &rec_msg.data.u8_buf[2], g_iap.recv_len);
  154. if ((g_iap.count_packages == g_iap.current_packages) &&
  155. (g_iap.current_packages < g_iap.total_packages))
  156. {
  157. g_iap.count_bytes += g_iap.recv_len;
  158. if ((g_iap.recv_len % 2) != 0)
  159. {
  160. g_iap.flash_data.u8_buf[g_iap.recv_len] = 0xFF;
  161. g_iap.recv_len++;
  162. }
  163. fmc_clear_flag_star();
  164. erase_flag = write_download_flash(g_iap.flash_data.u16_buf, g_iap.recv_len / 2,
  165. g_iap.count_packages);
  166. fmc_clear_flag_end();
  167. g_iap.crc16 = firmware_crc16_ccitt_false(g_iap.crc16, g_iap.flash_data.u8_buf,
  168. g_iap.recv_len);
  169. send_buff[0] = IAP_CMD_DATA;
  170. send_buff[1] = !erase_flag;
  171. g_iap.count_packages++;
  172. }
  173. else
  174. {
  175. send_buff[0] = IAP_CMD_DATA;
  176. send_buff[1] = 0x06;
  177. }
  178. send_buff[2] = rec_msg.data.u8_buf[0] & 0x7F;
  179. send_buff[3] = rec_msg.data.u8_buf[1];
  180. send_buff[4] = g_iap.count_packages >> 8;
  181. send_buff[5] = g_iap.count_packages & 0xFF;
  182. }
  183. }
  184. else
  185. {
  186. switch (rec_msg.data.u8_buf[0])
  187. {
  188. case IAP_CMD_VERSION:
  189. iap_param_init();
  190. for (uint8_t i = 0; i < (UPGRADE_APP_DATA_SIZE * 2); i++)
  191. {
  192. send_buff[i] =
  193. fmc_read_byte(UPGRADE_FLAG_START_ADDR + (UPGRADE_FLAG_DATA_SIZE * 2) + i);
  194. }
  195. send_buff[0] = IAP_CMD_VERSION;
  196. send_buff[1] = 0x01;
  197. break;
  198. case IAP_CMD_INFO:
  199. g_iap.total_bytes = (uint16_t)rec_msg.data.u8_buf[1] << 8 | rec_msg.data.u8_buf[2];
  200. g_iap.total_bytes <<= 16;
  201. g_iap.total_bytes |= (uint16_t)rec_msg.data.u8_buf[3] << 8 | rec_msg.data.u8_buf[4];
  202. g_iap.total_packages = (uint16_t)rec_msg.data.u8_buf[5] << 8 | rec_msg.data.u8_buf[6];
  203. send_buff[0] = IAP_CMD_INFO;
  204. send_buff[1] = 0x01;
  205. break;
  206. case IAP_CMD_ERASE:
  207. g_iap.firmware_crc16 = (uint16_t)rec_msg.data.u8_buf[2] << 8 | rec_msg.data.u8_buf[3];
  208. if (rec_msg.data.u8_buf[1])
  209. {
  210. // 喂狗
  211. fmc_clear_flag_star();
  212. erase_flag = erase_app_flash(DOWNLOAD_START_ADDR, DOWNLOAD_END_ADDR);
  213. fmc_clear_flag_end();
  214. // 喂狗
  215. g_iap.count_bytes = 0;
  216. g_iap.count_packages = 0;
  217. }
  218. send_buff[0] = IAP_CMD_ERASE;
  219. send_buff[1] = !erase_flag;
  220. break;
  221. case IAP_CMD_CRC:
  222. send_buff[0] = IAP_CMD_CRC;
  223. send_buff[1] = (g_iap.crc16 == g_iap.firmware_crc16 ? 1 : 0);
  224. break;
  225. case IAP_CMD_JUMP:
  226. if (g_iap.crc16 != g_iap.firmware_crc16)
  227. {
  228. send_buff[1] = 0x00;
  229. }
  230. else
  231. {
  232. fmc_clear_flag_star();
  233. fmc_erase_pages(UPGRADE_FLAG_START_ADDR, 1);
  234. upgrade.param.sign = UPGRADE_SIGN;
  235. upgrade.param.crc16 = g_iap.crc16;
  236. upgrade.param.moving_size = g_iap.total_bytes;
  237. fmc_write_n_half_word(UPGRADE_FLAG_START_ADDR, upgrade.infor_buf,
  238. UPGRADE_FLAG_DATA_SIZE);
  239. fmc_clear_flag_end();
  240. jump_boot_time = 10;
  241. send_buff[1] = 0x01;
  242. }
  243. send_buff[0] = IAP_CMD_JUMP;
  244. break;
  245. case IAP_CMD_MODEL_TYPE:
  246. send_buff[0] = IAP_CMD_MODEL_TYPE;
  247. send_buff[1] = 0x01;
  248. send_buff[2] = DEVICE_ID >> 8;
  249. send_buff[3] = DEVICE_ID & 0xFF;
  250. }
  251. }
  252. push_can_message_to_queue(0x18DFE1F4, 8, send_buff);
  253. }