| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2022-02-12 RT-Thread first version
- */
- #include "main.h"
- #include "gpio.h"
- #include "rtc.h"
- #include "iap.h"
- #include "boot.h"
- #include "string.h"
- #include "wwdg.h"
- #include <board.h>
- #include <easyflash.h>
- #define Version "V1.33"
- #define MAX_DATA_SIZE 1024
- #define BL_Sta_Check RTC_BKP_DR3
- #define BAK_Boot_Sta RTC_BKP_DR4
- uint8_t info_change = 0; //是否有信息更改
- Bak_info bak_info = {0}; //存放各备份区信息
- BL_Para bl_par = {0}; //存放BL传递相关参数
- uint16_t Now_date = 0; //存放日期数据
- ///
- ///
- /// 在App中每次启动均会将app中的固件版本和时间传入
- /// 直接从flash中读出即可
- ///
- ///
- extern WWDG_HandleTypeDef hwwdg;
- extern RTC_HandleTypeDef hrtc;
- void Check_Rst(void)
- {
- rt_kprintf("CSR = %x\r\n", RCC->CSR);
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST) == 1)
- rt_kprintf("Option Byte Loader reset flag\r\n");
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) == 1)
- rt_kprintf("PIN reset flag\r\n");
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_PWRRST) == 1)
- rt_kprintf("BOR or POR/PDR reset flag\r\n");
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) == 1)
- rt_kprintf("Software Reset flag\r\n");
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) == 1)
- rt_kprintf(" Window watchdog reset flag\r\n");
- if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) == 1)
- rt_kprintf("Low-Power reset flag\r\n");
- rt_kprintf("\r\n");
- }
- // void Check_Rst(void)
- //{
- // // rt_kprintf("CSR = %x\r\n", RCC->CSR);
- // if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST) == 1)
- // rt_kprintf("1\r\n");
- // if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) == 1)
- // rt_kprintf("2\r\n");
- // if (__HAL_RCC_GET_FLAG(RCC_FLAG_PWRRST) == 1)
- // rt_kprintf("3\r\n");
- // if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) == 1)
- // rt_kprintf("4\r\n");
- // if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) == 1)
- // rt_kprintf("5\r\n");
- // if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) == 1)
- // rt_kprintf("6\r\n");
- //
- // rt_kprintf("\r\n");
- // }
- uint8_t easyflash_init_finsh = Zero;
- int main(void)
- {
- rt_kprintf("\nBL %s\n\n", Version);
- MX_GPIO_Init();
- MX_RTC_Init();
- Enadble_module(1);
- Check_Rst();
- if (check_flash_cfd() == One)
- {
- if (easyflash_init() == EF_NO_ERR)
- {
- easyflash_init_finsh = One;
- Read_Para();
- check_flag();
- }
- }
- else ///ef初始化条件不足 直接开启
- {
- easyflash_init_finsh = One;
- }
- if (info_change == 1)
- {
- info_change = 0;
- rt_kprintf("%d ", ef_set_env_blob("bak_info", &bak_info, sizeof(Bak_info)));
- }
- Reflash_BL_Sta_Check();
- Start_app();
- return RT_EOK;
- }
- //开机读取参数
- void Read_Para(void)
- {
- ///
- ///
- /// 第一步先给flash中存放bak信息的结构体拿出来
- /// bak_info 该结构体仅在BL中读写 App仅可修改IAP固件状态标记位
- ///
- ///
- // rt_kprintf("\r\n------ read para ------\r\n");
- ef_get_env_blob("bak_info", &bak_info, sizeof(bak_info), NULL);
- ///
- ///
- /// 然后是时间和固件版本以及升级标志和app启动标记位
- ///
- ///
- ef_get_env_blob("bl_par", &bl_par, sizeof(BL_Para), NULL);
- }
- void Enadble_module(uint8_t en)
- {
- if (en)
- {
- HAL_GPIO_WritePin(Flash_CTL_Port, Flash_CTL_Pin, GPIO_PIN_RESET); //开启Flash供电
- HAL_GPIO_WritePin(RUN_STATUS_GPIO_Port, RUN_STATUS_Pin, GPIO_PIN_SET); //开启led
- }
- }
- uint8_t check_flash_cfd(void)
- {
- uint8_t result = Zero;
- // rt_kprintf("A %04X \r\n", HAL_RTCEx_BKUPRead(&hrtc, BL_Sta_Check));
- if (HAL_RTCEx_BKUPRead(&hrtc, BL_Sta_Check) == 0x6969)
- {
- result = One;
- }
- __HAL_RCC_PWR_CLK_ENABLE(); //使能电源时钟PWR
- HAL_PWR_EnableBkUpAccess(); //取消备份区域写保护
- HAL_RTCEx_BKUPWrite(&hrtc, BL_Sta_Check, 0x0000);
- HAL_PWR_DisableBkUpAccess(); //开启备份区域写保护
- return result;
- }
- void Reflash_BL_Sta_Check(void)
- {
- __HAL_RCC_PWR_CLK_ENABLE(); //使能电源时钟PWR
- HAL_PWR_EnableBkUpAccess(); //取消备份区域写保护
- HAL_RTCEx_BKUPWrite(&hrtc, BL_Sta_Check, 0x6969);
- HAL_PWR_DisableBkUpAccess(); //开启备份区域写保护
- // rt_kprintf("B %04X \r\n", HAL_RTCEx_BKUPRead(&hrtc, BL_Sta_Check));
- }
- uint8_t check_flag(void)
- {
- /*
- *
- * 校验app开机情况
- *
- */
- ///
- ///
- /// DR4 是一个16位的寄存器
- /// 高8位放lora的flag
- /// 低八位放紧急情况下主机启动状态的备份器 为0x008A
- ///
- ///
- if (bl_par.boot_state > 0 && bl_par.boot_state % 10 == 0 && bl_par.boot_state < 150)
- {
- //启动正常
- }
- else if ((HAL_RTCEx_BKUPRead(&hrtc, BAK_Boot_Sta) & 0x00FF) == 0x8A)
- {
- rt_kprintf("rtc boot\n");
- bl_par.boot_state = 90;
- __HAL_RCC_PWR_CLK_ENABLE(); //使能电源时钟PWR
- HAL_PWR_EnableBkUpAccess(); //取消备份区域写保护
- HAL_RTCEx_BKUPWrite(&hrtc, BAK_Boot_Sta, (HAL_RTCEx_BKUPRead(&hrtc, BAK_Boot_Sta) & 0xFF00));
- HAL_PWR_DisableBkUpAccess(); //开启备份区域写保护
- }
- else if (bl_par.boot_state == 0)
- {
- // rt_kprintf("failed start %d\r\n", bl_par.iap_boot_state);
- if (bl_par.iap_boot_state == 0) //判断是不是因为升级或还原造成的启动失败
- {
- if (bak_info.Bak_sta[1] == One)
- {
- bl_par.upgrade_flag = 110;
- }
- else if (bak_info.Bak_sta[2] == One)
- {
- bl_par.upgrade_flag = 120;
- }
- else if (bak_info.Bak_sta[0] == One)
- {
- bl_par.upgrade_flag = 100;
- }
- else
- {
- bl_par.boot_state = 0;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- }
- }
- else
- {
- Failure_handling();
- }
- }
- rt_kprintf(" launch %d upgrade %d\n\n", bl_par.boot_state, bl_par.upgrade_flag);
- /*
- *
- * 校验App是否在正常运行
- *
- */
- ///
- ///
- ///
- /// iap_boot_state 该标记具有 两个作用
- ///
- /// 1是记录升级前的启动状态值 与后续进入bl中时的值对比 可判断出是否成功升级
- /// 2是记录升级时使用的哪个备份区域的固件进行的升级 若升级失败可回滚至后一个备份区域
- ///
- /// uint16_t iap_boot_state
- /// 高8位存放使用的哪个固件升级
- /// 低8位存放升级前的启动状态值
- ///
- ///
- ///
- if (bl_par.upgrade_flag == 100 || bl_par.upgrade_flag == 110 || bl_par.upgrade_flag == 120) //接下来有升级任务先记录此时的状态
- {
- bl_par.iap_boot_state = bl_par.upgrade_flag;
- bl_par.iap_boot_state = bl_par.iap_boot_state << 8;
- bl_par.iap_boot_state += bl_par.boot_state;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- // rt_kprintf("iap_boot_state already upgrade %d %d\r\n", bl_par.upgrade_flag, bl_par.iap_boot_state);
- }
- /*
- *
- * 检查是否有升级标记
- *
- */
- ///
- ///
- /// upgrade_flag 由app向BL传递指令的重要参数
- ///
- /// case 100 从IAP 备份区向App写入
- /// case 110 从BAK1备份区向App写入
- /// case 120 从BAK2备份区向App写入
- /// case 130 备份当前App固件到BAK1
- /// case 140 备份当前App固件到BAK2
- /// case 150 IAP升级后等待写入IAP信息的标记
- /// case 200 没有升级任务
- /// default 参数值异常 进行复位
- ///
- ///
- ///
- ///
- switch (bl_par.upgrade_flag)
- {
- ///
- ///
- /// 当 bl_par.upgrade_flag 赋值150
- /// 说明是使用了固件还原(IAP 或 BAK)
- /// 如果App开机了 会给这个150擦除
- ///
- case 100: ///将IAP空间的固件写入到单片机中
- write_app_from_bak(50);
- bl_par.upgrade_flag = 150;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- rt_kprintf("app upgrade √\n");
- break;
- case 110: ///将备份1中的固件写入到单片机中
- if (bak_info.Bak_sta[1] == One)
- {
- write_app_from_bak(100);
- bl_par.upgrade_flag = 150;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- rt_kprintf("bak1 --> app √\n");
- }
- break;
- case 120: ///将备份2中的固件写入到单片机中
- if (bak_info.Bak_sta[2] == One)
- {
- write_app_from_bak(200);
- bl_par.upgrade_flag = 150;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- rt_kprintf("bak2 --> app √\n");
- }
- break;
- case 130: ///备份当前固件到备份1空间中
- rt_kprintf("app --> bak1 %d\n\r", bl_par.upgrade_flag);
- copy_app_to_bak(100);
- bl_par.upgrade_flag = Zero;
- bak_info.Bak_sta[1] = One;
- bak_info.FW_Version[1] = bl_par.Now_Version;
- bak_info.FW_Ver_tim[1] = Now_date;
- info_change = 1;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- break;
- case 140: ///备份当前固件到备份2空间中
- if (bl_par.boot_state == 110 || bl_par.boot_state == 100)
- {
- rt_kprintf("app --> bak2 %d\n\r", bl_par.upgrade_flag);
- copy_app_to_bak(200);
- bl_par.upgrade_flag = Zero;
- bak_info.Bak_sta[2] = One;
- bak_info.FW_Version[2] = bl_par.Now_Version;
- bak_info.FW_Ver_tim[2] = Now_date;
- info_change = 1;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- }
- break;
- case 150: /// BL能进150 说明app启动异常 使用备份固件恢复
- Failure_handling();
- break;
- case 200: ///无升级任务的默认值
- break;
- default: ///参数异常时复位
- bl_par.upgrade_flag = Zero;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- break;
- }
- /*
- *
- * 校验各个备份固件的情况
- *
- */
- ////////// 检查 IAP 区域 //////////
- if (bak_info.Bak_sta[0] != One && bak_info.Bak_sta[0] != Zero)
- {
- bak_info.Bak_sta[0] = Zero;
- // rt_kprintf("Bak_sta[0] set def\r\n");
- info_change = 1;
- }
- else
- {
- if (bak_info.Bak_sta[0] == One)
- {
- rt_kprintf(" IAP FW V %d.%03d T %02d/%02d/%02d\r\n",
- bak_info.FW_Version[0] / 1000, bak_info.FW_Version[0] % 1000,
- ((bak_info.FW_Ver_tim[0] >> 8) & 0x00FF) / 12 + 21, //提取年
- ((bak_info.FW_Ver_tim[0] >> 8) & 0x00FF) % 12, //提取月
- bak_info.FW_Ver_tim[0] & 0x00FF //提取日
- );
- }
- // else
- // {
- //// rt_kprintf(" IAP FW doesn't exist\r\n");
- // }
- }
- ////////// 检查 BAK1 区域 //////////
- // bak_info.Bak_sta[2] = Zero;
- if (bak_info.Bak_sta[1] != One && bak_info.Bak_sta[1] != Zero)
- {
- bak_info.Bak_sta[1] = Zero;
- info_change = 1;
- }
- if (bak_info.Bak_sta[1] == One)
- {
- rt_kprintf(" BAK1 FW V %d.%03d T %02d/%02d/%02d\r\n",
- bak_info.FW_Version[1] / 1000, bak_info.FW_Version[1] % 1000,
- ((bak_info.FW_Ver_tim[1] >> 8) & 0x00FF) / 12 + 21, //提取年
- ((bak_info.FW_Ver_tim[1] >> 8) & 0x00FF) % 12, //提取月
- bak_info.FW_Ver_tim[1] & 0x00FF //提取日
- );
- }
- else
- {
- if (bl_par.boot_state == One || bl_par.boot_state == One + 10)
- {
- if (copy_app_to_bak(100) == 1)
- {
- bak_info.Bak_sta[1] = One;
- bak_info.FW_Version[1] = bl_par.Now_Version;
- bak_info.FW_Ver_tim[1] = Now_date;
- info_change = 1;
- rt_kprintf("app --> bak1 √ V %04X T %d\r\n", bak_info.FW_Ver_tim[1], bak_info.FW_Ver_tim[1]);
- }
- }
- }
- ////////// 检查 BAK2 区域 //////////
- if (bak_info.Bak_sta[2] != One && bak_info.Bak_sta[2] != Zero)
- {
- bak_info.Bak_sta[2] = Zero;
- info_change = 1;
- }
- if (bak_info.Bak_sta[2] == One)
- {
- rt_kprintf(" BAK2 FW V %d.%03d T %02d/%02d/%02d\r\n",
- bak_info.FW_Version[2] / 1000, bak_info.FW_Version[2] % 1000,
- ((bak_info.FW_Ver_tim[2] >> 8) & 0x00FF) / 12 + 21, //提取年
- ((bak_info.FW_Ver_tim[2] >> 8) & 0x00FF) % 12, //提取月
- bak_info.FW_Ver_tim[2] & 0x00FF //提取日
- );
- }
- else
- {
- if (bl_par.boot_state >= 30 && bl_par.boot_state % 10 == 0)
- {
- if (copy_app_to_bak(200) == 1)
- {
- bak_info.Bak_sta[2] = One;
- bak_info.FW_Version[2] = bl_par.Now_Version;
- bak_info.FW_Ver_tim[2] = Now_date;
- info_change = 1;
- rt_kprintf("app --> bak1 √ V %04X T %d\r\n", bak_info.FW_Ver_tim[2], bak_info.FW_Ver_tim[2]);
- }
- }
- }
- // rt_kprintf("\r\n------ BAK Firmware Sta Check ------\r\n\r\n");
- if (bl_par.boot_state != 0)
- {
- bl_par.boot_state -= 10;
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- }
- rt_kprintf("\r\n");
- return bl_par.upgrade_flag;
- }
- //处理升级失败的情况
- void Failure_handling(void)
- {
- rt_kprintf("Failure...\r\n");
- bl_par.iap_boot_state &= 0xFF00;
- bl_par.iap_boot_state = bl_par.iap_boot_state >> 8;
- if (bl_par.iap_boot_state == 100) //当使用IAP固件升级失败时
- {
- rt_kprintf("IAP --> App ×\r\n");
- bak_info.Bak_sta[0] = Zero; //清除IAP固件标记位
- if (bak_info.Bak_sta[1] == One)
- {
- bl_par.upgrade_flag = 110;
- }
- else if (bak_info.Bak_sta[2] == One)
- {
- bl_par.upgrade_flag = 120;
- }
- }
- if (bl_par.iap_boot_state == 110) //当使用BAK1固件升级失败时
- {
- rt_kprintf("BAK1 --> App ×\r\n");
- bak_info.Bak_sta[1] = Zero; //清除BAK1固件标记位
- if (bak_info.Bak_sta[2] == One)
- {
- bl_par.upgrade_flag = 120;
- }
- else if (bak_info.Bak_sta[2] == One)
- {
- bl_par.upgrade_flag = 120;
- }
- }
- if (bl_par.iap_boot_state == 120) //当使用BAK2固件升级失败时
- {
- rt_kprintf("BAK2 --> App ×\r\n");
- bak_info.Bak_sta[2] = Zero; //清除BAK2固件标记位
- if (bak_info.Bak_sta[0] == One)
- {
- bl_par.upgrade_flag = 100;
- }
- else if (bak_info.Bak_sta[1] == One)
- {
- bl_par.upgrade_flag = 110;
- }
- else //当所有固件都无法开机时
- {
- // for (uint8_t i = 0; i < 100; i++)
- // {
- // HAL_GPIO_TogglePin(RUN_STATUS_GPIO_Port, RUN_STATUS_Pin); //开启led
- // rt_thread_mdelay(50);
- // }
- }
- }
- bl_par.iap_boot_state = 0;
- ef_set_env_blob("bak_info", &bak_info, sizeof(Bak_info));
- ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
- }
|