main.c 13 KB

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