iap.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <string.h>
  2. #include "app/iap.h"
  3. #include "app/nv_storage.h"
  4. #include "bsp/fmc_flash.h"
  5. #include "bsp/shark_rtc.h"
  6. static int iap_write_image(uint8_t *data, int len);
  7. static int iap_check_image(uint8_t *data, int len);
  8. void _reboot_timer_handler(shark_timer_t *t);
  9. void iap_read_string(can_frame_t *frame);
  10. static u8 _write_success = 0;
  11. static int _write_position = 0;
  12. static shark_timer_t _reboot_timer = {.handler = _reboot_timer_handler,};
  13. void process_iap_message(can_frame_t *frame, int len){
  14. uint8_t *data = NULL;
  15. int data_len = 0;
  16. switch(frame->key) {
  17. case CAN_KEY_IAP_ENTER:
  18. if (gd32_flash_size() < 128 * 1024){
  19. wdog_reload();
  20. fmc_iap_write_magic(0xFFFFFFFF);
  21. shark_rtc_set_backup(0x3000);
  22. nv_save_all_soc();
  23. NVIC_SystemReset();
  24. while(1);
  25. }
  26. protocol_send_ack(frame->head.can_addr, frame->key, 0);
  27. break;
  28. case CAN_KEY_IAP_BEGIN:
  29. if (gd32_flash_size() < 128 * 1024){
  30. protocol_send_ack(frame->head.can_addr, frame->key, 1);
  31. break;
  32. }
  33. fmc_write_image_begin();
  34. _write_position = 0;
  35. _write_success = 0;
  36. protocol_send_ack(frame->head.can_addr, frame->key, 0);
  37. break;
  38. case CAN_KEY_IAP_WRITE:
  39. _write_success = 0;
  40. data_len = iap_write_image(frame->data, len);
  41. data = frame->data;
  42. break;
  43. case CAN_KEY_IAP_CHECK:
  44. fmc_write_image_end();
  45. data_len = iap_check_image(frame->data, len);
  46. data = frame->data;
  47. break;
  48. case CAN_KEY_IAP_BOOT:
  49. if (_write_success) {
  50. nv_save_all_soc();
  51. NVIC_SystemReset();
  52. while(1);
  53. } else {
  54. protocol_send_ack(frame->head.can_addr, frame->key, 0);
  55. }
  56. break;
  57. case CAN_KEY_IAP_STAT:
  58. protocol_send_ack(frame->head.can_addr, frame->key, 0);
  59. break;
  60. case CAN_EEY_IAP_READ_STRING:
  61. iap_read_string(frame);
  62. break;
  63. case CAN_KEY_REBOOT:
  64. if (len == 4 && shark_decode_u32(frame->data) == SHARK_IAP_MAGIC_SUCCESS) {
  65. fmc_iap_write_magic(0xFFFFFFFF);
  66. }
  67. shark_rtc_set_backup(0x3003);
  68. shark_timer_post(&_reboot_timer, 100);
  69. protocol_send_ack(frame->head.can_addr, frame->key, 1);
  70. break;
  71. case CAN_KET_ERASE_NV:
  72. shark_rtc_set_backup(0x3002);
  73. nv_erase_soc(0);
  74. nv_erase_soc(1);
  75. shark_timer_post(&_reboot_timer, 100);
  76. protocol_send_ack(frame->head.can_addr, frame->key, 1);
  77. break;
  78. }
  79. if (data != NULL && data_len > 0){
  80. protocol_send_bms_info(frame->head.can_addr, frame->key, frame->data, data_len);
  81. }
  82. }
  83. void _reboot_timer_handler(shark_timer_t *t){
  84. nv_save_all_soc();
  85. NVIC_SystemReset();
  86. }
  87. static int iap_write_image(uint8_t *data, int len){
  88. int w_pos = shark_decode_u24(data);
  89. if (w_pos == _write_position && len > 3) {
  90. fmc_write_image_continue(data + 3, len - 3);
  91. _write_position += len - 3;
  92. }
  93. data[0] = 0;
  94. shark_encode_u24(data+1, _write_position);
  95. return 4;
  96. }
  97. void iap_read_string(can_frame_t *frame)
  98. {
  99. uint8_t buff[64];
  100. const char *text;
  101. uint32_t addr;
  102. uint32_t len;
  103. addr = ((uint32_t) frame->data[2]) << 16 | ((uint32_t) frame->data[1]) << 8 | frame->data[0];
  104. text = (const char *) (0x08000000 + addr);
  105. len = strlen(text);
  106. if (len > (sizeof(buff)-4)) {
  107. len = sizeof(buff) - 4;
  108. }
  109. buff[0] = 0;
  110. memcpy(buff+1, frame->data, 3);
  111. memcpy(buff + 4, text, len);
  112. protocol_send_bms_info(frame->head.can_addr, frame->key, buff, len + 4);
  113. }
  114. static int iap_check_image(uint8_t *data, int len) {
  115. uint32_t size, checksum;
  116. size = shark_decode_u24(data);
  117. checksum = shark_decode_u32(data + 3);
  118. uint32_t d_checksum = shark_iap_checksum_init();
  119. d_checksum = shark_iap_checksum_put(d_checksum, (const u8 *)fmc_iap_image_addr(), size);
  120. d_checksum = shark_iap_checksum_finish(d_checksum);
  121. if (checksum != d_checksum) {
  122. data[0] = 1;
  123. return 1;
  124. }
  125. fmc_write_magic(size, checksum, SHARK_IAP_MAGIC_FLASH);
  126. _write_success = 1;
  127. data[0] = 0;
  128. return 1;
  129. }