main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. #include "stm32f4xx.h"
  2. #include "common_config.h"
  3. #include "conf.h"
  4. #include "main.h"
  5. #include "led.h"
  6. #include "systick.h"
  7. #include "usart.h"
  8. #include "httpserver.h"
  9. #include "flash_if.h"
  10. #include "settings_api.h"
  11. #include "gpio_io.h"
  12. #include "gpio.h"
  13. #include "crc.h"
  14. #include "wdg.h"
  15. #include "tinystdio.h"
  16. #include "time.h"
  17. #include "string.h"
  18. #include "stm32f4x7_eth.h"
  19. #include "netconf.h"
  20. #include "rng.h"
  21. #ifdef SD_ENABLE
  22. #include "SD_Card/sdio_sd.h"
  23. #include "FATFS/ff.h"
  24. #include "FATFS/diskio.h"
  25. #endif
  26. #ifdef LCD_ENABLE
  27. #include "lcd.h"
  28. #endif
  29. #ifdef SLAVEBRD_ENABLE
  30. #include "stm32sprog.h"
  31. #endif
  32. /* Секция размещения СRC прошивки */
  33. #if defined ( __GNUC__ )
  34. uint32_t crc __attribute__ ((section (".crc"))) = 0xAABBCCDD;
  35. #endif
  36. #define FW_FILE_NAME MAIN_FW_NAME
  37. /*
  38. * Bootloader verification key section.
  39. * Use "openssl rand -hex 8" to generate new key.
  40. * */
  41. uint64_t bootkey __attribute__ ((section (".bootkey"))) = 0x92dc73b8fef3b041;
  42. bool IAPviaETH = false;
  43. bool fDoneReset = false;
  44. bool fUpload = false;
  45. bool fInvalidFw = false;
  46. bool fBootFailed = false;
  47. volatile uint32_t resetCounter = 0;
  48. bool UpdateTimeoutFlag = false;
  49. #ifdef SD_ENABLE
  50. extern FATFS fs;
  51. extern FIL fil_obj;
  52. #endif
  53. /* this variable is used to create a time reference incremented by 10ms */
  54. __IO uint32_t LocalTime = 0;
  55. pFunction Jump_To_App;
  56. uint32_t JumpAdd;
  57. /**
  58. * @brief Общая структура настроек
  59. */
  60. extern SETTINGS_t sSettings;
  61. void UpdateTimeout_Handler(void);
  62. #ifdef SD_ENABLE
  63. bool mmc_mount(void)
  64. {
  65. if (disk_initialize(0) != RES_OK) return false;
  66. if (f_mount(&fs, "0:", 1) != FR_OK) return false;
  67. return true;
  68. }
  69. #endif
  70. bool CheckFWIsValid(void)
  71. {
  72. if (((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000 &&
  73. *(__IO uint32_t *)USER_FLASH_CRC_ADDRESS != 0xFFFFFFFF) {
  74. return true;
  75. }
  76. return false;
  77. }
  78. void main(void)
  79. {
  80. uint8_t bootTry;
  81. uint8_t loadMode;
  82. gpio_init();
  83. WDG_Init();
  84. InitUSART();
  85. #ifdef PRINTF_STDLIB
  86. setvbuf(stdin, NULL, _IONBF, 0);
  87. setvbuf(stdout, NULL, _IONBF, 0);
  88. setvbuf(stderr, NULL, _IONBF, 0);
  89. #endif
  90. /* Enable PWR peripheral clock */
  91. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  92. /* Allow access to BKP Domain */
  93. PWR_BackupAccessCmd(ENABLE);
  94. /* Включаем тактирование модуля CRC */
  95. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  96. /* Проверка флага, определяющего состояние устройства. */
  97. /* Флаг установлен - работает Bootloader */
  98. /* Флаг сброшен - запускается основная программа */
  99. SETTINGS_Load();
  100. /* Проверка флага bootTry. Если флаг установлен, значит произошел сбой в
  101. основной прошивке. Нужно загружать bootloader и ждать обновления ПО */
  102. loadMode = RTC_ReadBackupRegister(RTC_BKP_DR1);
  103. bootTry = RTC_ReadBackupRegister(RTC_BKP_DR2);
  104. fInvalidFw = RTC_ReadBackupRegister(RTC_BKP_DR7);
  105. printf("loadMode: %d\r\nbootTry: %d\r\n", loadMode, bootTry);
  106. printf("loadMode: %d\r\n", loadMode);
  107. printf("loadMode: %d\r\n", bootTry);
  108. printf("fInvalidFw: %s\r\n", fInvalidFw ? "true" : "false");
  109. if (bootTry > 1) {
  110. bootTry--;
  111. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  112. /* Check if valid stack address (RAM address) then jump to user application */
  113. if (CheckFWIsValid()) {
  114. CLEAR_FWINVALID_FLAG();
  115. /* Jump to user application */
  116. JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  117. Jump_To_App = (pFunction) JumpAdd;
  118. /* Initialize user application's Stack Pointer */
  119. __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
  120. Jump_To_App();
  121. } else {
  122. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  123. SET_FWINVALID_FLAG();
  124. printf("\r\nFW empty. Started bootloader\r\n");
  125. }
  126. } else if (bootTry == 1) {
  127. fBootFailed = 1;
  128. printf("\r\nFW boot failed. Started bootloader\r\n");
  129. bootTry = 0;
  130. loadMode = 1;
  131. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  132. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  133. }
  134. /* Флаг не установлен прыгаем на основную программу */
  135. if (loadMode == 0) {
  136. printf("Run main FW\r\n");
  137. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS) = 0x%X\r\n", *(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS);
  138. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4) = 0x%X\r\n", *(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4));
  139. /* Set bootTry flag every time to ensure that
  140. * IAP will starts again if FW is corrupted */
  141. bootTry = BOOT_TRY;
  142. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  143. /* Check if valid stack address (RAM address) then jump to user application */
  144. if (CheckFWIsValid()) {
  145. CLEAR_FWINVALID_FLAG();
  146. /* Jump to user application */
  147. JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  148. Jump_To_App = (pFunction) JumpAdd;
  149. /* Initialize user application's Stack Pointer */
  150. __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
  151. Jump_To_App();
  152. }
  153. }
  154. /* Загружается Bootloader... */
  155. SysTick_Config(168000);//120000
  156. LED_Init();
  157. LED_On(LED_INIT_ERR);
  158. PRINT_USART("\n\rBootloader starting... \n\r");
  159. #ifdef LCD_ENABLE
  160. LCD_Init();
  161. LCD_PrintAligned(1, alignCENTER, "Обновление ПО");
  162. #endif
  163. /* Random number generator */
  164. RNG_Init();
  165. ETH_BSP_Config();
  166. LwIP_Init();
  167. IAP_httpd_init();
  168. CRC_Init();
  169. //Если нажата DEF начинаем обновление с sd
  170. if (IO_BtnDefaultPressed()) {
  171. #ifdef SD_ENABLE
  172. IAPviaETH = false;
  173. timer_AddFunction(500, &LED_Blinky_Red);
  174. SD_NVIC_Init();
  175. #endif
  176. } else {
  177. IAPviaETH = true;
  178. timer_AddFunction(500, &LED_Blinky_Red);
  179. }
  180. /* Check if valid stack address (RAM address) */
  181. if (((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000 && !fInvalidFw) {
  182. #if UPDATE_TIMEOUT != 0
  183. timer_AddFunction(1000, &UpdateTimeout_Handler);
  184. #endif
  185. } else {
  186. update_timeout = 0;
  187. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  188. SET_FWINVALID_FLAG();
  189. #ifdef LCD_ENABLE
  190. LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
  191. LCD_PrintAligned(7, alignCENTER, "Ошибка ПО");
  192. #endif
  193. }
  194. if (fBootFailed) {
  195. #ifdef LCD_ENABLE
  196. LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
  197. LCD_ClearRow(7);
  198. #endif
  199. }
  200. while (1)
  201. {
  202. timer_Main();
  203. if (IAPviaETH) { // Обновление по ETH
  204. /* Handle received packets and periodic timers for LwIP */
  205. LwIP_Periodic_Handle(0);
  206. if (fDoneReset) {
  207. resetCounter++;
  208. if (resetCounter > 400000) {
  209. loadMode = 0;
  210. bootTry = BOOT_TRY;
  211. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  212. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  213. SET_FWUPDATED_FLAG();
  214. CLEAR_FWINVALID_FLAG();
  215. #ifdef SLAVEBRD_ENABLE
  216. /* Reboot daughter board */
  217. stmReboot();
  218. #endif
  219. /* Self reboot */
  220. NVIC_SystemReset();
  221. }
  222. }
  223. } else {
  224. #ifdef SD_ENABLE
  225. // Обновление с SD
  226. // Пробуем смонтировать SD
  227. if (mmc_mount()) {
  228. // Пробуем открыть файл с именем FW_FILE_NAME
  229. timer_Stop(&LED_Blinky_Yellow);
  230. LED_Off(RED1_INT);
  231. LED_Off(GREEN_INT);
  232. if (f_open(&fil_obj, FW_FILE_NAME, FA_READ | FA_OPEN_EXISTING) == FR_OK) { // открываем файл
  233. LED_On(GREEN_INT);
  234. if (startFlashing() < 0) {
  235. Error_Handler();
  236. }
  237. f_close(&fil_obj);
  238. // CRC посчитанная при сборке и записанная в последине 4 байта прошивки
  239. // Должна сойтись с CRC посчитанной на контроллере
  240. if (CRC_Read() == CRC_Calculate()) {
  241. loadMode = 0;
  242. bootTry = BOOT_TRY;
  243. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  244. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  245. #ifdef SLAVEBRD_ENABLE
  246. /* Reboot daughter board */
  247. stmReboot();
  248. #endif
  249. /* Self reboot */
  250. NVIC_SystemReset();
  251. } else {
  252. Error_Handler();
  253. }
  254. } else { // Файл не найден
  255. LED_On(RED1_INT);
  256. }
  257. }
  258. #endif
  259. }
  260. //Если нажата DEF переходим в основную прошивку
  261. if (IO_BtnDefaultPressed() || UpdateTimeoutFlag) {
  262. if (!fUpload && ((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) != 0xFFFFFFFF)) {
  263. printf("\r\nUpdate timeout... Return to main FW\r\n");
  264. loadMode = 0;
  265. bootTry = BOOT_TRY;
  266. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  267. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  268. #ifdef SLAVEBRD_ENABLE
  269. /* Reboot daughter board */
  270. stmReboot();
  271. #endif
  272. /* Self reboot */
  273. NVIC_SystemReset();
  274. }
  275. }
  276. }
  277. }
  278. /**
  279. * @brief Updates the system local time
  280. * @param None
  281. * @retval None
  282. */
  283. void Time_Update(void)
  284. {
  285. LocalTime += SYSTEMTICK_PERIOD_MS;
  286. }
  287. /**
  288. * @brief
  289. */
  290. u32_t sys_now(void) {
  291. return LocalTime;
  292. }
  293. /**
  294. * @brief Error handler
  295. * @param None
  296. * @retval None
  297. */
  298. void Error_Handler(void) {
  299. LED_Off(LED_INIT_ERR);
  300. LED_Off(LED_INIT_OK);
  301. timer_AddFunction(500, &LED_Blinky_Red);
  302. while (1)
  303. {
  304. timer_Main();
  305. }
  306. }
  307. /**
  308. * @brief
  309. */
  310. void UpdateTimeout_Handler(void)
  311. {
  312. if ((fUpload) || (fInvalidFw) || (fDoneReset)) {
  313. return;
  314. }
  315. if (update_timeout == 0) {
  316. UpdateTimeoutFlag = true;
  317. } else {
  318. #ifdef LCD_ENABLE
  319. static char lcdbuf[32] = {0};
  320. sprintf(lcdbuf, "Ожидание (%d) ", update_timeout);
  321. LCD_ClearRow(7);
  322. LCD_PrintAligned(7, alignCENTER, lcdbuf);
  323. #endif
  324. update_timeout--;
  325. }
  326. }