main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  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. #ifdef FTP_ENABLE
  33. #include "spi_flash.h"
  34. #endif
  35. /* Секция размещения СRC прошивки */
  36. #if defined ( __GNUC__ )
  37. uint32_t crc __attribute__ ((section (".crc"))) = 0xAABBCCDD;
  38. #endif
  39. #define FW_FILE_NAME MAIN_FW_NAME
  40. /*
  41. * Bootloader verification key section.
  42. * Use "openssl rand -hex 8" to generate new key.
  43. * */
  44. uint64_t bootkey __attribute__ ((section (".bootkey"))) = 0x92dc73b8fef3b041;
  45. bool IAPviaETH = false;
  46. bool fDoneReset = false;
  47. bool fUpload = false;
  48. bool fInvalidFw = false;
  49. bool fBootFailed = false;
  50. extern uint8_t update_timeout;
  51. volatile uint32_t resetCounter = 0;
  52. bool UpdateTimeoutFlag = false;
  53. #ifdef SD_ENABLE
  54. extern FATFS fs;
  55. extern FIL fil_obj;
  56. #endif
  57. /* this variable is used to create a time reference incremented by 10ms */
  58. __IO uint32_t LocalTime = 0;
  59. pFunction Jump_To_App;
  60. uint32_t JumpAdd;
  61. /**
  62. * @brief Общая структура настроек
  63. */
  64. extern SETTINGS_t sSettings;
  65. void UpdateTimeout_Handler(void);
  66. #ifdef SD_ENABLE
  67. bool mmc_mount(void)
  68. {
  69. if (disk_initialize(0) != RES_OK) return false;
  70. if (f_mount(&fs, "0:", 1) != FR_OK) return false;
  71. return true;
  72. }
  73. #endif
  74. bool CheckFWIsValid(void)
  75. {
  76. if (((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000 &&
  77. *(__IO uint32_t *)USER_FLASH_CRC_ADDRESS != 0xFFFFFFFF) {
  78. return true;
  79. }
  80. printf("\r\nFW empty. Started bootloader\r\n");
  81. return false;
  82. }
  83. #ifdef FTP_ENABLE
  84. void spi_flash_update(void)
  85. {
  86. printf("ftp: trying to update the firmware from the SPI flash\r\n");
  87. const uint32_t spif_firmware_offset = SPI_FLASH_SECTOR_SIZE * FIRMWARE_UPDATE_SECTOR_OFFSET;
  88. uint32_t fw_begin;
  89. spi_flash_init();
  90. spi_flash_read(spif_firmware_offset, &fw_begin, 4, 0);
  91. const uint32_t crc_offset = USER_FLASH_CRC_ADDRESS - USER_FLASH_FIRST_PAGE_ADDRESS;
  92. uint32_t expected_crc;
  93. spi_flash_read(spif_firmware_offset + crc_offset, &expected_crc, 4, 0);
  94. bool present_firmware = (fw_begin != 0xFFFFFFFF) || (expected_crc != 0xFFFFFFFF);
  95. if (!present_firmware) {
  96. printf("ftp: no firmware-like data is present on the SPI flash\r\n");
  97. return;
  98. }
  99. // check CRC
  100. CRC->CR = 1;
  101. for (uint32_t offset = 0; offset < crc_offset; offset += 4) {
  102. uint32_t data;
  103. spi_flash_read(spif_firmware_offset + offset, &data, sizeof(data), 0);
  104. CRC->DR = data;
  105. }
  106. uint32_t calculated_crc = CRC->DR;
  107. if (expected_crc != calculated_crc) {
  108. printf("ftp: calculated CRC (%lx) doesn't match the expected CRC (%lx)!\r\n", calculated_crc, expected_crc);
  109. return;
  110. }
  111. printf("ftp: writing the stm32 flash\r\n");
  112. FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS);
  113. FLASH_If_Init(); // unlock it again
  114. uint8_t buf[1024];
  115. for (uint32_t offset = 0; offset < MAIN_FW_SIZE; offset += sizeof(buf)) {
  116. spi_flash_read(spif_firmware_offset + offset, buf, sizeof(buf), 0);
  117. uint8_t *addr = USER_FLASH_FIRST_PAGE_ADDRESS + offset;
  118. FLASH_If_Write(&addr, buf, sizeof(buf) / 4);
  119. }
  120. printf("ftp: erasing the SPI flash\r\n");
  121. for (int sec = 0; sec < FIRMWARE_UPDATE_SECTOR_COUNT; ++sec) {
  122. spi_flash_erase_sector(SPI_FLASH_SECTOR_SIZE * (FIRMWARE_UPDATE_SECTOR_OFFSET + sec), 0);
  123. }
  124. printf("ftp: update successful, rebooting...\r\n");
  125. SET_FWUPDATED_FLAG();
  126. CLEAR_FWINVALID_FLAG();
  127. RTC_WriteBackupRegister(RTC_BKP_DR1, 0); // loadMode
  128. NVIC_SystemReset();
  129. }
  130. #endif // FTP_ENABLE
  131. void main(void)
  132. {
  133. uint8_t bootTry;
  134. uint8_t loadMode;
  135. gpio_init();
  136. WDG_Init();
  137. InitUSART();
  138. #ifdef PRINTF_STDLIB
  139. setvbuf(stdin, NULL, _IONBF, 0);
  140. setvbuf(stdout, NULL, _IONBF, 0);
  141. setvbuf(stderr, NULL, _IONBF, 0);
  142. #endif
  143. /* Enable PWR peripheral clock */
  144. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  145. /* Allow access to BKP Domain */
  146. PWR_BackupAccessCmd(ENABLE);
  147. /* Включаем тактирование модуля CRC */
  148. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  149. /* Проверка флага, определяющего состояние устройства. */
  150. /* Флаг установлен - работает Bootloader */
  151. /* Флаг сброшен - запускается основная программа */
  152. SETTINGS_Load();
  153. /* Проверка флага bootTry. Если флаг установлен, значит произошел сбой в
  154. основной прошивке. Нужно загружать bootloader и ждать обновления ПО */
  155. loadMode = RTC_ReadBackupRegister(RTC_BKP_DR1);
  156. bootTry = RTC_ReadBackupRegister(RTC_BKP_DR2);
  157. fInvalidFw = RTC_ReadBackupRegister(RTC_BKP_DR7);
  158. printf("\r\nloadMode: %d\r\nbootTry: %d\r\n", loadMode, bootTry);
  159. printf("fInvalidFw: %s\r\n", fInvalidFw ? "true" : "false");
  160. if (bootTry > 1) {
  161. bootTry--;
  162. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  163. /* Check if valid stack address (RAM address) then jump to user application */
  164. if (CheckFWIsValid()) {
  165. CLEAR_FWINVALID_FLAG();
  166. /* Jump to user application */
  167. JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  168. Jump_To_App = (pFunction) JumpAdd;
  169. /* Initialize user application's Stack Pointer */
  170. __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
  171. Jump_To_App();
  172. } else {
  173. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  174. SET_FWINVALID_FLAG();
  175. }
  176. } else if (bootTry == 1) {
  177. fBootFailed = 1;
  178. printf("\r\nFW boot failed. Started bootloader\r\n");
  179. bootTry = 0;
  180. loadMode = 1;
  181. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  182. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  183. }
  184. /* Флаг не установлен прыгаем на основную программу */
  185. if (loadMode == 0) {
  186. printf("Run main FW\r\n");
  187. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS) = 0x%X\r\n", *(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS);
  188. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4) = 0x%X\r\n", *(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4));
  189. /* Set bootTry flag every time to ensure that
  190. * IAP will starts again if FW is corrupted */
  191. bootTry = BOOT_TRY;
  192. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  193. /* Check if valid stack address (RAM address) then jump to user application */
  194. if (CheckFWIsValid()) {
  195. CLEAR_FWINVALID_FLAG();
  196. /* Jump to user application */
  197. JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  198. Jump_To_App = (pFunction) JumpAdd;
  199. /* Initialize user application's Stack Pointer */
  200. __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
  201. Jump_To_App();
  202. }
  203. }
  204. /* Загружается Bootloader... */
  205. SysTick_Config(168000);//120000
  206. LED_Init();
  207. LED_On(LED_INIT_ERR);
  208. PRINT_USART("\n\rBootloader starting... \n\r");
  209. #ifdef LCD_ENABLE
  210. LCD_Init();
  211. LCD_PrintAligned(1, alignCENTER, "Обновление ПО");
  212. #endif
  213. /* Random number generator */
  214. RNG_Init();
  215. ETH_BSP_Config();
  216. LwIP_Init();
  217. IAP_httpd_init();
  218. CRC_Init();
  219. //Если нажата DEF начинаем обновление с sd
  220. if (IO_BtnDefaultPressed()) {
  221. #ifdef SD_ENABLE
  222. IAPviaETH = false;
  223. timer_AddFunction(500, &LED_Blinky_Red);
  224. SD_NVIC_Init();
  225. #endif
  226. } else {
  227. IAPviaETH = true;
  228. timer_AddFunction(500, &LED_Blinky_Red);
  229. }
  230. /* Check if valid stack address (RAM address) */
  231. if (((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000 && !fInvalidFw) {
  232. #if UPDATE_TIMEOUT != 0
  233. timer_AddFunction(1000, &UpdateTimeout_Handler);
  234. #endif
  235. } else {
  236. update_timeout = 0;
  237. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  238. SET_FWINVALID_FLAG();
  239. #ifdef LCD_ENABLE
  240. LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
  241. LCD_PrintAligned(7, alignCENTER, "Ошибка ПО");
  242. #endif
  243. }
  244. if (fBootFailed) {
  245. #ifdef LCD_ENABLE
  246. LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
  247. LCD_ClearRow(7);
  248. #endif
  249. }
  250. #ifdef FTP_ENABLE
  251. spi_flash_update();
  252. #endif // FTP_ENABLE
  253. while (1)
  254. {
  255. timer_Main();
  256. if (IAPviaETH) { // Обновление по ETH
  257. /* Handle received packets and periodic timers for LwIP */
  258. LwIP_Periodic_Handle(0);
  259. if (fDoneReset) {
  260. resetCounter++;
  261. if (resetCounter > 400000) {
  262. loadMode = 0;
  263. bootTry = BOOT_TRY;
  264. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  265. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  266. SET_FWUPDATED_FLAG();
  267. CLEAR_FWINVALID_FLAG();
  268. #ifdef SLAVEBRD_ENABLE
  269. /* Reboot daughter board */
  270. stmReboot();
  271. #endif
  272. /* Self reboot */
  273. NVIC_SystemReset();
  274. }
  275. }
  276. } else {
  277. #ifdef SD_ENABLE
  278. // Обновление с SD
  279. // Пробуем смонтировать SD
  280. if (mmc_mount()) {
  281. // Пробуем открыть файл с именем FW_FILE_NAME
  282. timer_Stop(&LED_Blinky_Yellow);
  283. LED_Off(RED1_INT);
  284. LED_Off(GREEN_INT);
  285. if (f_open(&fil_obj, FW_FILE_NAME, FA_READ | FA_OPEN_EXISTING) == FR_OK) { // открываем файл
  286. LED_On(GREEN_INT);
  287. if (startFlashing() < 0) {
  288. Error_Handler();
  289. }
  290. f_close(&fil_obj);
  291. // CRC посчитанная при сборке и записанная в последине 4 байта прошивки
  292. // Должна сойтись с CRC посчитанной на контроллере
  293. if (CRC_Read() == CRC_Calculate()) {
  294. loadMode = 0;
  295. bootTry = BOOT_TRY;
  296. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  297. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  298. #ifdef SLAVEBRD_ENABLE
  299. /* Reboot daughter board */
  300. stmReboot();
  301. #endif
  302. /* Self reboot */
  303. NVIC_SystemReset();
  304. } else {
  305. Error_Handler();
  306. }
  307. } else { // Файл не найден
  308. LED_On(RED1_INT);
  309. }
  310. }
  311. #endif
  312. }
  313. //Если нажата DEF переходим в основную прошивку
  314. if (IO_BtnDefaultPressed() || UpdateTimeoutFlag) {
  315. if (!fUpload && ((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) != 0xFFFFFFFF)) {
  316. printf("\r\nUpdate timeout... Return to main FW\r\n");
  317. loadMode = 0;
  318. bootTry = BOOT_TRY;
  319. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  320. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  321. #ifdef SLAVEBRD_ENABLE
  322. /* Reboot daughter board */
  323. stmReboot();
  324. #endif
  325. /* Self reboot */
  326. NVIC_SystemReset();
  327. }
  328. }
  329. }
  330. }
  331. /**
  332. * @brief Updates the system local time
  333. * @param None
  334. * @retval None
  335. */
  336. void Time_Update(void)
  337. {
  338. LocalTime += SYSTEMTICK_PERIOD_MS;
  339. }
  340. /**
  341. * @brief
  342. */
  343. u32_t sys_now(void) {
  344. return LocalTime;
  345. }
  346. /**
  347. * @brief Error handler
  348. * @param None
  349. * @retval None
  350. */
  351. void Error_Handler(void) {
  352. LED_Off(LED_INIT_ERR);
  353. LED_Off(LED_INIT_OK);
  354. timer_AddFunction(500, &LED_Blinky_Red);
  355. while (1)
  356. {
  357. timer_Main();
  358. }
  359. }
  360. /**
  361. * @brief
  362. */
  363. void UpdateTimeout_Handler(void)
  364. {
  365. if ((fUpload) || (fInvalidFw) || (fDoneReset)) {
  366. return;
  367. }
  368. if (update_timeout == 0) {
  369. UpdateTimeoutFlag = true;
  370. } else {
  371. #ifdef LCD_ENABLE
  372. static char lcdbuf[32] = {0};
  373. sprintf(lcdbuf, "Ожидание (%d) ", update_timeout);
  374. LCD_ClearRow(7);
  375. LCD_PrintAligned(7, alignCENTER, lcdbuf);
  376. #endif
  377. update_timeout--;
  378. }
  379. }