| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 | #include "stm32f4xx.h"#include "common_config.h"#include "main.h"#include "led.h"#include "systick.h"#include "usart.h"#include "httpserver.h"#include "flash_if.h"#include "settings_api.h"#include "gpio_io.h"#include "crc.h"#include "wdg.h"#include "tinystdio.h"#include "time.h"#include "string.h"#include "stm32f4x7_eth.h"#include "netconf.h"/* Секция размещения СRC прошивки */#if defined ( __GNUC__ )uint32_t crc __attribute__ ((section (".crc"))) = 0xAABBCCDD;#endifbool IAPviaETH = false;uint8_t fDoneReset = 0;uint8_t fErrorReset = 0;uint8_t fUpload = 0;uint8_t fInvalidFw = 0;uint8_t fBootFailed = 0;uint32_t resetCounter = 0;bool UpdateTimeoutFlag = false;/* this variable is used to create a time reference incremented by 10ms */__IO uint32_t LocalTime = 0; pFunction Jump_To_App;uint32_t JumpAdd;/**  * @brief  Общая структура настроек  */extern SETTINGS_t sSettings;void UpdateTimeout_Handler(void);void main(void){  	uint8_t bootTry;  	uint8_t loadMode;    WDG_Init();    IO_Init();    InitUSART();  /* Enable PWR peripheral clock */  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);  /* Allow access to BKP Domain */  PWR_BackupAccessCmd(ENABLE);  /* Включаем тактирование модуля CRC */  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);    /* Проверка флага, определяющего состояние устройства. */  /* Флаг установлен - работает Bootloader               */  /* Флаг сброшен - запускается основная программа       */  SETTINGS_Load();    /* Проверка флага bootTry. Если флаг установлен, значит произошел сбой в      основной прошивке. Нужно загружать bootloader и ждать обновления ПО */  /* TODO remove if tested */  //bootTry = sSettings.bootParams.bootTry;  loadMode = RTC_ReadBackupRegister(RTC_BKP_DR1);  bootTry = RTC_ReadBackupRegister(RTC_BKP_DR2);  printf("loadMode: %d\r\nbootTry: %d\r\n", loadMode, bootTry);    if (bootTry > 1)  {    bootTry--;    RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);    /* Check if valid stack address (RAM address) then jump to user application */    if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)    {        JumpAdd = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);        Jump_To_App = (pFunction) JumpAdd;        __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);        Jump_To_App();    }    else {        /* Флеш пустая, нечего загружать, висим в аварийном режиме */        fInvalidFw = 1;        PRINT_USART("\n\rFW empty. Started bootloader\n\r");    }  }  else if (bootTry == 1)  {    fBootFailed = 1;    PRINT_USART("\n\rFW boot failed. Started bootloader\n\r");    bootTry = 0;    loadMode = 1;    RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);    RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);  }  /* Флаг не установлен прыгаем на основную программу */  if (loadMode == 0)  {      printf("Run main FW\n\r");      //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS) = 0x%X\n\r", *(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS);      //printf("*(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4) = 0x%X\n\r", *(__IO uint32_t*)(USER_FLASH_FIRST_PAGE_ADDRESS + 4));      /* Set bootTry flag every time to ensure that       * IAP will starts again if FW is corrupted */      bootTry = BOOT_TRY;      RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);    /* Check if valid stack address (RAM address) then jump to user application */    if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)    {      /* Jump to user application */      JumpAdd = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);      Jump_To_App = (pFunction) JumpAdd;      /* Initialize user application's Stack Pointer */      __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);      Jump_To_App();    }  }    /* Загружается Bootloader... */    SysTick_Config(120000);  LED_Init();  PRINT_USART("\n\rBootloader starting...   \n\r");  LED_On(RED_STATUS);  ETH_BSP_Config();  LwIP_Init();  IAP_httpd_init();  CRC_Init();  //Если нажата DEF начинаем обновление с sd  if (IO_BtnDefaultPressed())   {//	IAPviaETH = false;//    timer_AddFunction(500, &LED_Blinky_Yellow);//    SD_NVIC_Init();  } else {    IAPviaETH = true;    timer_AddFunction(500, &LED_Blinky_Red);  }    /* Check if valid stack address (RAM address) */  if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000) {      timer_AddFunction(1000, &UpdateTimeout_Handler);  }  else {      /* Флеш пустая, нечего загружать, висим в аварийном режиме */      fInvalidFw = 1;  }  while (1)  {    timer_Main();    if (IAPviaETH) { // Обновление по ETH      /* check if any packet received */      if (ETH_CheckFrameReceived())      {         /* process received ethernet packet */        LwIP_Pkt_Handle();      }      /* handle periodic timers for LwIP */      LwIP_Periodic_Handle(LocalTime);		  if (fDoneReset)	  {		resetCounter++;	    if (resetCounter > 100000)		{  	      loadMode = 0;	      bootTry = BOOT_TRY;	      RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);	      RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);	      /* Set FW update flag */	      RTC_WriteBackupRegister(RTC_BKP_DR3, 1);          NVIC_SystemReset();		}  	  }		  if (fErrorReset)	  {		resetCounter++;	    if (resetCounter > 100000) {          NVIC_SystemReset();	    }	  }    }    //Если нажата DEF переходим в основную прошивку    if (IO_BtnDefaultPressed() || UpdateTimeoutFlag)    {      if (!fUpload && ((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) != 0xFFFFFFFF)) {          PRINT_USART("\n\rUpdate timeout... Return to main FW\n\r");          loadMode = 0;          bootTry = BOOT_TRY;          RTC_WriteBackupRegister(RTC_BKP_DR1, loadMode);          RTC_WriteBackupRegister(RTC_BKP_DR2, bootTry);		  NVIC_SystemReset();      }    }  }}/**  * @brief  Updates the system local time  * @param  None  * @retval None  */void Time_Update(void){  LocalTime += SYSTEMTICK_PERIOD_MS;}/**  * @brief  */u32_t sys_now(void) {    return LocalTime;}/**  * @brief  Error handler  * @param  None  * @retval None  */void Error_Handler(void) {  LED_Off(RED_STATUS);  LED_Off(GREEN_STATUS);  timer_AddFunction(500, &LED_Blinky_Red);  while (1)  {    timer_Main();  }}/**  * @brief  */void UpdateTimeout_Handler(void){    static char lcdbuf[32] = {0};    static uint8_t time = UPDATE_TIMEOUT;    if ((fUpload) || (fInvalidFw)) return;    if (time == 0) {        UpdateTimeoutFlag = true;    }    else {        time--;    }}
 |