main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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("\r\nloadMode: %d\r\nbootTry: %d\r\n", loadMode, bootTry);
  106. printf("fInvalidFw: %s\r\n", fInvalidFw ? "true" : "false");
  107. if (bootTry > 1) {
  108. bootTry--;
  109. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  110. /* Check if valid stack address (RAM address) then jump to user application */
  111. if (CheckFWIsValid()) {
  112. CLEAR_FWINVALID_FLAG();
  113. /* Jump to user application */
  114. JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  115. Jump_To_App = (pFunction) JumpAdd;
  116. /* Initialize user application's Stack Pointer */
  117. __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
  118. Jump_To_App();
  119. } else {
  120. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  121. SET_FWINVALID_FLAG();
  122. printf("\r\nFW empty. Started bootloader\r\n");
  123. }
  124. } else if (bootTry == 1) {
  125. fBootFailed = 1;
  126. printf("\r\nFW boot failed. Started bootloader\r\n");
  127. bootTry = 0;
  128. loadMode = 1;
  129. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  130. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  131. }
  132. /* Флаг не установлен прыгаем на основную программу */
  133. if (loadMode == 0) {
  134. printf("Run main FW\r\n");
  135. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS) = 0x%X\r\n", *(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS);
  136. //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4) = 0x%X\r\n", *(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4));
  137. /* Set bootTry flag every time to ensure that
  138. * IAP will starts again if FW is corrupted */
  139. bootTry = BOOT_TRY;
  140. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  141. /* Check if valid stack address (RAM address) then jump to user application */
  142. if (CheckFWIsValid()) {
  143. CLEAR_FWINVALID_FLAG();
  144. /* Jump to user application */
  145. JumpAdd = *(__IO uint32_t *) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
  146. Jump_To_App = (pFunction) JumpAdd;
  147. /* Initialize user application's Stack Pointer */
  148. __set_MSP(*(__IO uint32_t *) USER_FLASH_FIRST_PAGE_ADDRESS);
  149. Jump_To_App();
  150. }
  151. }
  152. /* Загружается Bootloader... */
  153. SysTick_Config(168000);//120000
  154. LED_Init();
  155. LED_On(LED_INIT_ERR);
  156. PRINT_USART("\n\rBootloader starting... \n\r");
  157. #ifdef LCD_ENABLE
  158. LCD_Init();
  159. LCD_PrintAligned(1, alignCENTER, "Обновление ПО");
  160. #endif
  161. /* Random number generator */
  162. RNG_Init();
  163. ETH_BSP_Config();
  164. LwIP_Init();
  165. IAP_httpd_init();
  166. CRC_Init();
  167. //Если нажата DEF начинаем обновление с sd
  168. if (IO_BtnDefaultPressed()) {
  169. #ifdef SD_ENABLE
  170. IAPviaETH = false;
  171. timer_AddFunction(500, &LED_Blinky_Red);
  172. SD_NVIC_Init();
  173. #endif
  174. } else {
  175. IAPviaETH = true;
  176. timer_AddFunction(500, &LED_Blinky_Red);
  177. }
  178. /* Check if valid stack address (RAM address) */
  179. if (((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000 && !fInvalidFw) {
  180. #if UPDATE_TIMEOUT != 0
  181. timer_AddFunction(1000, &UpdateTimeout_Handler);
  182. #endif
  183. } else {
  184. update_timeout = 0;
  185. /* Флеш пустая, нечего загружать, висим в аварийном режиме */
  186. SET_FWINVALID_FLAG();
  187. #ifdef LCD_ENABLE
  188. LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
  189. LCD_PrintAligned(7, alignCENTER, "Ошибка ПО");
  190. #endif
  191. }
  192. if (fBootFailed) {
  193. #ifdef LCD_ENABLE
  194. LCD_PrintAligned(5, alignCENTER, "Аварийный режим");
  195. LCD_ClearRow(7);
  196. #endif
  197. }
  198. while (1)
  199. {
  200. timer_Main();
  201. if (IAPviaETH) { // Обновление по ETH
  202. /* Handle received packets and periodic timers for LwIP */
  203. LwIP_Periodic_Handle(0);
  204. if (fDoneReset) {
  205. resetCounter++;
  206. if (resetCounter > 400000) {
  207. loadMode = 0;
  208. bootTry = BOOT_TRY;
  209. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  210. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  211. SET_FWUPDATED_FLAG();
  212. CLEAR_FWINVALID_FLAG();
  213. #ifdef SLAVEBRD_ENABLE
  214. /* Reboot daughter board */
  215. stmReboot();
  216. #endif
  217. /* Self reboot */
  218. NVIC_SystemReset();
  219. }
  220. }
  221. } else {
  222. #ifdef SD_ENABLE
  223. // Обновление с SD
  224. // Пробуем смонтировать SD
  225. if (mmc_mount()) {
  226. // Пробуем открыть файл с именем FW_FILE_NAME
  227. timer_Stop(&LED_Blinky_Yellow);
  228. LED_Off(RED1_INT);
  229. LED_Off(GREEN_INT);
  230. if (f_open(&fil_obj, FW_FILE_NAME, FA_READ | FA_OPEN_EXISTING) == FR_OK) { // открываем файл
  231. LED_On(GREEN_INT);
  232. if (startFlashing() < 0) {
  233. Error_Handler();
  234. }
  235. f_close(&fil_obj);
  236. // CRC посчитанная при сборке и записанная в последине 4 байта прошивки
  237. // Должна сойтись с CRC посчитанной на контроллере
  238. if (CRC_Read() == CRC_Calculate()) {
  239. loadMode = 0;
  240. bootTry = BOOT_TRY;
  241. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  242. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  243. #ifdef SLAVEBRD_ENABLE
  244. /* Reboot daughter board */
  245. stmReboot();
  246. #endif
  247. /* Self reboot */
  248. NVIC_SystemReset();
  249. } else {
  250. Error_Handler();
  251. }
  252. } else { // Файл не найден
  253. LED_On(RED1_INT);
  254. }
  255. }
  256. #endif
  257. }
  258. //Если нажата DEF переходим в основную прошивку
  259. if (IO_BtnDefaultPressed() || UpdateTimeoutFlag) {
  260. if (!fUpload && ((*(__IO uint32_t *)USER_FLASH_FIRST_PAGE_ADDRESS) != 0xFFFFFFFF)) {
  261. printf("\r\nUpdate timeout... Return to main FW\r\n");
  262. loadMode = 0;
  263. bootTry = BOOT_TRY;
  264. RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);
  265. RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);
  266. #ifdef SLAVEBRD_ENABLE
  267. /* Reboot daughter board */
  268. stmReboot();
  269. #endif
  270. /* Self reboot */
  271. NVIC_SystemReset();
  272. }
  273. }
  274. }
  275. }
  276. /**
  277. * @brief Updates the system local time
  278. * @param None
  279. * @retval None
  280. */
  281. void Time_Update(void)
  282. {
  283. LocalTime += SYSTEMTICK_PERIOD_MS;
  284. }
  285. /**
  286. * @brief
  287. */
  288. u32_t sys_now(void) {
  289. return LocalTime;
  290. }
  291. /**
  292. * @brief Error handler
  293. * @param None
  294. * @retval None
  295. */
  296. void Error_Handler(void) {
  297. LED_Off(LED_INIT_ERR);
  298. LED_Off(LED_INIT_OK);
  299. timer_AddFunction(500, &LED_Blinky_Red);
  300. while (1)
  301. {
  302. timer_Main();
  303. }
  304. }
  305. /**
  306. * @brief
  307. */
  308. void UpdateTimeout_Handler(void)
  309. {
  310. if ((fUpload) || (fInvalidFw) || (fDoneReset)) {
  311. return;
  312. }
  313. if (update_timeout == 0) {
  314. UpdateTimeoutFlag = true;
  315. } else {
  316. #ifdef LCD_ENABLE
  317. static char lcdbuf[32] = {0};
  318. sprintf(lcdbuf, "Ожидание (%d) ", update_timeout);
  319. LCD_ClearRow(7);
  320. LCD_PrintAligned(7, alignCENTER, lcdbuf);
  321. #endif
  322. update_timeout--;
  323. }
  324. }