main.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "at32f403a_407.h"
  2. #include "at32f403a_407_board.h"
  3. #include "at32f403a_407_clock.h"
  4. #include "common_config.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"
  7. #include "queue.h"
  8. #include "semphr.h"
  9. #include "usb_eth.h"
  10. #include "mux.h"
  11. #include "misc.h"
  12. #include "spi_common.h"
  13. #include "extended_sram.h"
  14. #include "modbus.h"
  15. #include "common_gpio.h"
  16. #include "io.h"
  17. #include "input.h"
  18. #include "wdt.h"
  19. #include <stdio.h>
  20. #include <stdbool.h>
  21. #include <string.h>
  22. //
  23. bool jump_to_app(uint32_t address);
  24. void (*pftarget)(void);
  25. bool boot_failed = false;
  26. int main()
  27. {
  28. uint8_t load_mode;
  29. uint8_t boot_try;
  30. uint8_t fw_invalid = 0;
  31. nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  32. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
  33. crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
  34. pwc_battery_powered_domain_access(TRUE);
  35. system_clock_config();
  36. delay_init();
  37. uart_print_init(115200);
  38. // Флаг - нужно ли обновляться
  39. load_mode = bpr_data_read(BPR_DATA1);
  40. // Число попыток загрузки основного ПО
  41. boot_try = bpr_data_read(BPR_DATA2);
  42. DBG printf("[IAP] load_mode: %u, boot_try: %u\r\n", load_mode, boot_try);
  43. // Если есть попытки, то пытаемся загрузить FW.
  44. // Используем ограниченное число попыток загрузить основное FW.
  45. if (boot_try > 1)
  46. {
  47. boot_try--;
  48. bpr_data_write(BPR_DATA2, boot_try);
  49. if (!jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS))
  50. {
  51. // Флеш пустая. Нечего загружать
  52. fw_invalid = 1;
  53. boot_failed = false;
  54. DBG printf("FW empty! Bootloader starting...\n\r");
  55. }
  56. }
  57. else if (boot_try == 1)
  58. {
  59. boot_failed = true;
  60. DBG printf("FW boot failed. Bootloader starting...\r\n");
  61. load_mode = 1;
  62. boot_try = 0;
  63. bpr_data_write(BPR_DATA1, load_mode);
  64. bpr_data_write(BPR_DATA2, boot_try);
  65. }
  66. if ((load_mode == 0) && (!fw_invalid))
  67. {
  68. DBG printf("Run main FW\r\n");
  69. bpr_data_write(BPR_DATA2, BOOT_TRY);
  70. DBG printf("Go to main FW...\r\n");
  71. jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS);
  72. }
  73. DBG printf("IAP starting...\r\n");
  74. // Для теста. Сброс.
  75. DBG printf("For test reset load_mode flag and jump to FW\r\n");
  76. bpr_data_write(BPR_DATA1, 0);
  77. jump_to_app(0x08021000);
  78. while (1) {}
  79. }
  80. //
  81. bool jump_to_app(uint32_t address)
  82. {
  83. uint32_t stkptr, jumpaddr;
  84. stkptr = *(uint32_t *)address;
  85. jumpaddr = *(uint32_t *)(address + sizeof(uint32_t));
  86. if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x20000000) == 0x20000000)
  87. {
  88. __set_MSP(stkptr);
  89. pftarget = (void (*) (void))jumpaddr;
  90. pftarget();
  91. }
  92. return false;
  93. }