main.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "main.h"
  2. void soft_wdt(void *params);
  3. void init_task(void *params);
  4. bool jump_to_app(uint32_t address);
  5. void (*pftarget)(void);
  6. bool boot_failed = false;
  7. int main()
  8. {
  9. uint8_t load_mode;
  10. uint8_t boot_try;
  11. uint8_t fw_invalid = 0;
  12. nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  13. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
  14. crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE);
  15. pwc_battery_powered_domain_access(TRUE);
  16. system_clock_config();
  17. delay_init();
  18. uart_print_init(115200);
  19. // Флаг - нужно ли обновляться
  20. load_mode = bpr_data_read(BPR_DATA1);
  21. // Число попыток загрузки основного ПО
  22. boot_try = bpr_data_read(BPR_DATA2);
  23. DBG printf("[IAP] load_mode: %u, boot_try: %u\r\n", load_mode, boot_try);
  24. #if 1
  25. // Если есть попытки, то пытаемся загрузить FW.
  26. // Используем ограниченное число попыток загрузить основное FW.
  27. if (boot_try > 1)
  28. {
  29. boot_try--;
  30. bpr_data_write(BPR_DATA2, boot_try);
  31. if (!jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS))
  32. {
  33. // Флеш пустая. Нечего загружать
  34. fw_invalid = 1;
  35. boot_failed = false;
  36. DBG printf("FW empty! Bootloader starting...\n\r");
  37. }
  38. }
  39. else if (boot_try == 1)
  40. {
  41. boot_failed = true;
  42. DBG printf("FW boot failed. Bootloader starting...\r\n");
  43. load_mode = 1;
  44. boot_try = 0;
  45. bpr_data_write(BPR_DATA1, load_mode);
  46. bpr_data_write(BPR_DATA2, boot_try);
  47. }
  48. if ((load_mode == 0) && (!fw_invalid))
  49. {
  50. DBG printf("Run main FW\r\n");
  51. bpr_data_write(BPR_DATA2, BOOT_TRY);
  52. DBG printf("Go to main FW...\r\n");
  53. jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS);
  54. }
  55. #endif
  56. DBG printf("IAP starting...\r\n");
  57. #if 0
  58. // -------------------------------------------------------------------------
  59. // Для теста. Сброс.
  60. DBG printf("For test reset load_mode flag and jump to FW\r\n");
  61. bpr_data_write(BPR_DATA1, 0);
  62. jump_to_app(0x08021000);
  63. #endif
  64. //
  65. cm_gpio_init();
  66. taskENTER_CRITICAL();
  67. xTaskCreate(soft_wdt, "soft_wdt", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
  68. xTaskCreate(init_task, "init_task", 10*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
  69. taskEXIT_CRITICAL();
  70. vTaskStartScheduler();
  71. while (1) {}
  72. }
  73. //
  74. bool jump_to_app(uint32_t address)
  75. {
  76. uint32_t stkptr, jumpaddr;
  77. stkptr = *(uint32_t *)address;
  78. jumpaddr = *(uint32_t *)(address + sizeof(uint32_t));
  79. //if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x20000000) == 0x20000000)
  80. if (*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS != 0xFFFFFFFF)
  81. {
  82. __set_MSP(stkptr);
  83. pftarget = (void (*) (void))jumpaddr;
  84. pftarget();
  85. }
  86. return false;
  87. }
  88. //
  89. void soft_wdt(void *params)
  90. {
  91. (void)params;
  92. for (;;)
  93. {
  94. extern_wdt_togle(); // extern WDT
  95. vTaskDelay(500);
  96. }
  97. }
  98. //
  99. void init_task(void *params)
  100. {
  101. (void)params;
  102. crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE);
  103. init_settings();
  104. settings_load(&settings);
  105. mb_init();
  106. for (;;)
  107. {
  108. vTaskDelay(500);
  109. }
  110. }