dev_iap.c 10 KB

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