main.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-02-12 RT-Thread first version
  9. */
  10. #include "main.h"
  11. #include "gpio.h"
  12. #include "rtc.h"
  13. #include "iap.h"
  14. #include "boot.h"
  15. #include "string.h"
  16. #include "wwdg.h"
  17. #include <board.h>
  18. #include <easyflash.h>
  19. #define Version "V1.33"
  20. #define MAX_DATA_SIZE 1024
  21. #define BL_Sta_Check RTC_BKP_DR3
  22. #define BAK_Boot_Sta RTC_BKP_DR4
  23. uint8_t info_change = 0; //是否有信息更改
  24. Bak_info bak_info = {0}; //存放各备份区信息
  25. BL_Para bl_par = {0}; //存放BL传递相关参数
  26. uint16_t Now_date = 0; //存放日期数据
  27. ///
  28. ///
  29. /// 在App中每次启动均会将app中的固件版本和时间传入
  30. /// 直接从flash中读出即可
  31. ///
  32. ///
  33. extern WWDG_HandleTypeDef hwwdg;
  34. extern RTC_HandleTypeDef hrtc;
  35. void Check_Rst(void)
  36. {
  37. rt_kprintf("CSR = %x\r\n", RCC->CSR);
  38. if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST) == 1)
  39. rt_kprintf("Option Byte Loader reset flag\r\n");
  40. if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) == 1)
  41. rt_kprintf("PIN reset flag\r\n");
  42. if (__HAL_RCC_GET_FLAG(RCC_FLAG_PWRRST) == 1)
  43. rt_kprintf("BOR or POR/PDR reset flag\r\n");
  44. if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) == 1)
  45. rt_kprintf("Software Reset flag\r\n");
  46. if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) == 1)
  47. rt_kprintf(" Window watchdog reset flag\r\n");
  48. if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) == 1)
  49. rt_kprintf("Low-Power reset flag\r\n");
  50. rt_kprintf("\r\n");
  51. }
  52. // void Check_Rst(void)
  53. //{
  54. // // rt_kprintf("CSR = %x\r\n", RCC->CSR);
  55. // if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST) == 1)
  56. // rt_kprintf("1\r\n");
  57. // if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) == 1)
  58. // rt_kprintf("2\r\n");
  59. // if (__HAL_RCC_GET_FLAG(RCC_FLAG_PWRRST) == 1)
  60. // rt_kprintf("3\r\n");
  61. // if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) == 1)
  62. // rt_kprintf("4\r\n");
  63. // if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) == 1)
  64. // rt_kprintf("5\r\n");
  65. // if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST) == 1)
  66. // rt_kprintf("6\r\n");
  67. //
  68. // rt_kprintf("\r\n");
  69. // }
  70. uint8_t easyflash_init_finsh = Zero;
  71. int main(void)
  72. {
  73. rt_kprintf("\nBL %s\n\n", Version);
  74. MX_GPIO_Init();
  75. MX_RTC_Init();
  76. Enadble_module(1);
  77. Check_Rst();
  78. if (check_flash_cfd() == One)
  79. {
  80. if (easyflash_init() == EF_NO_ERR)
  81. {
  82. easyflash_init_finsh = One;
  83. Read_Para();
  84. check_flag();
  85. }
  86. }
  87. else ///ef初始化条件不足 直接开启
  88. {
  89. easyflash_init_finsh = One;
  90. }
  91. if (info_change == 1)
  92. {
  93. info_change = 0;
  94. rt_kprintf("%d ", ef_set_env_blob("bak_info", &bak_info, sizeof(Bak_info)));
  95. }
  96. Reflash_BL_Sta_Check();
  97. Start_app();
  98. return RT_EOK;
  99. }
  100. //开机读取参数
  101. void Read_Para(void)
  102. {
  103. ///
  104. ///
  105. /// 第一步先给flash中存放bak信息的结构体拿出来
  106. /// bak_info 该结构体仅在BL中读写 App仅可修改IAP固件状态标记位
  107. ///
  108. ///
  109. // rt_kprintf("\r\n------ read para ------\r\n");
  110. ef_get_env_blob("bak_info", &bak_info, sizeof(bak_info), NULL);
  111. ///
  112. ///
  113. /// 然后是时间和固件版本以及升级标志和app启动标记位
  114. ///
  115. ///
  116. ef_get_env_blob("bl_par", &bl_par, sizeof(BL_Para), NULL);
  117. }
  118. void Enadble_module(uint8_t en)
  119. {
  120. if (en)
  121. {
  122. HAL_GPIO_WritePin(Flash_CTL_Port, Flash_CTL_Pin, GPIO_PIN_RESET); //开启Flash供电
  123. HAL_GPIO_WritePin(RUN_STATUS_GPIO_Port, RUN_STATUS_Pin, GPIO_PIN_SET); //开启led
  124. }
  125. }
  126. uint8_t check_flash_cfd(void)
  127. {
  128. uint8_t result = Zero;
  129. // rt_kprintf("A %04X \r\n", HAL_RTCEx_BKUPRead(&hrtc, BL_Sta_Check));
  130. if (HAL_RTCEx_BKUPRead(&hrtc, BL_Sta_Check) == 0x6969)
  131. {
  132. result = One;
  133. }
  134. __HAL_RCC_PWR_CLK_ENABLE(); //使能电源时钟PWR
  135. HAL_PWR_EnableBkUpAccess(); //取消备份区域写保护
  136. HAL_RTCEx_BKUPWrite(&hrtc, BL_Sta_Check, 0x0000);
  137. HAL_PWR_DisableBkUpAccess(); //开启备份区域写保护
  138. return result;
  139. }
  140. void Reflash_BL_Sta_Check(void)
  141. {
  142. __HAL_RCC_PWR_CLK_ENABLE(); //使能电源时钟PWR
  143. HAL_PWR_EnableBkUpAccess(); //取消备份区域写保护
  144. HAL_RTCEx_BKUPWrite(&hrtc, BL_Sta_Check, 0x6969);
  145. HAL_PWR_DisableBkUpAccess(); //开启备份区域写保护
  146. // rt_kprintf("B %04X \r\n", HAL_RTCEx_BKUPRead(&hrtc, BL_Sta_Check));
  147. }
  148. uint8_t check_flag(void)
  149. {
  150. /*
  151. *
  152. * 校验app开机情况
  153. *
  154. */
  155. ///
  156. ///
  157. /// DR4 是一个16位的寄存器
  158. /// 高8位放lora的flag
  159. /// 低八位放紧急情况下主机启动状态的备份器 为0x008A
  160. ///
  161. ///
  162. if (bl_par.boot_state > 0 && bl_par.boot_state % 10 == 0 && bl_par.boot_state < 150)
  163. {
  164. //启动正常
  165. }
  166. else if ((HAL_RTCEx_BKUPRead(&hrtc, BAK_Boot_Sta) & 0x00FF) == 0x8A)
  167. {
  168. rt_kprintf("rtc boot\n");
  169. bl_par.boot_state = 90;
  170. __HAL_RCC_PWR_CLK_ENABLE(); //使能电源时钟PWR
  171. HAL_PWR_EnableBkUpAccess(); //取消备份区域写保护
  172. HAL_RTCEx_BKUPWrite(&hrtc, BAK_Boot_Sta, (HAL_RTCEx_BKUPRead(&hrtc, BAK_Boot_Sta) & 0xFF00));
  173. HAL_PWR_DisableBkUpAccess(); //开启备份区域写保护
  174. }
  175. else if (bl_par.boot_state == 0)
  176. {
  177. // rt_kprintf("failed start %d\r\n", bl_par.iap_boot_state);
  178. if (bl_par.iap_boot_state == 0) //判断是不是因为升级或还原造成的启动失败
  179. {
  180. if (bak_info.Bak_sta[1] == One)
  181. {
  182. bl_par.upgrade_flag = 110;
  183. }
  184. else if (bak_info.Bak_sta[2] == One)
  185. {
  186. bl_par.upgrade_flag = 120;
  187. }
  188. else if (bak_info.Bak_sta[0] == One)
  189. {
  190. bl_par.upgrade_flag = 100;
  191. }
  192. else
  193. {
  194. bl_par.boot_state = 0;
  195. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  196. }
  197. }
  198. else
  199. {
  200. Failure_handling();
  201. }
  202. }
  203. rt_kprintf(" launch %d upgrade %d\n\n", bl_par.boot_state, bl_par.upgrade_flag);
  204. /*
  205. *
  206. * 校验App是否在正常运行
  207. *
  208. */
  209. ///
  210. ///
  211. ///
  212. /// iap_boot_state 该标记具有 两个作用
  213. ///
  214. /// 1是记录升级前的启动状态值 与后续进入bl中时的值对比 可判断出是否成功升级
  215. /// 2是记录升级时使用的哪个备份区域的固件进行的升级 若升级失败可回滚至后一个备份区域
  216. ///
  217. /// uint16_t iap_boot_state
  218. /// 高8位存放使用的哪个固件升级
  219. /// 低8位存放升级前的启动状态值
  220. ///
  221. ///
  222. ///
  223. if (bl_par.upgrade_flag == 100 || bl_par.upgrade_flag == 110 || bl_par.upgrade_flag == 120) //接下来有升级任务先记录此时的状态
  224. {
  225. bl_par.iap_boot_state = bl_par.upgrade_flag;
  226. bl_par.iap_boot_state = bl_par.iap_boot_state << 8;
  227. bl_par.iap_boot_state += bl_par.boot_state;
  228. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  229. // rt_kprintf("iap_boot_state already upgrade %d %d\r\n", bl_par.upgrade_flag, bl_par.iap_boot_state);
  230. }
  231. /*
  232. *
  233. * 检查是否有升级标记
  234. *
  235. */
  236. ///
  237. ///
  238. /// upgrade_flag 由app向BL传递指令的重要参数
  239. ///
  240. /// case 100 从IAP 备份区向App写入
  241. /// case 110 从BAK1备份区向App写入
  242. /// case 120 从BAK2备份区向App写入
  243. /// case 130 备份当前App固件到BAK1
  244. /// case 140 备份当前App固件到BAK2
  245. /// case 150 IAP升级后等待写入IAP信息的标记
  246. /// case 200 没有升级任务
  247. /// default 参数值异常 进行复位
  248. ///
  249. ///
  250. ///
  251. ///
  252. switch (bl_par.upgrade_flag)
  253. {
  254. ///
  255. ///
  256. /// 当 bl_par.upgrade_flag 赋值150
  257. /// 说明是使用了固件还原(IAP 或 BAK)
  258. /// 如果App开机了 会给这个150擦除
  259. ///
  260. case 100: ///将IAP空间的固件写入到单片机中
  261. write_app_from_bak(50);
  262. bl_par.upgrade_flag = 150;
  263. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  264. rt_kprintf("app upgrade √\n");
  265. break;
  266. case 110: ///将备份1中的固件写入到单片机中
  267. if (bak_info.Bak_sta[1] == One)
  268. {
  269. write_app_from_bak(100);
  270. bl_par.upgrade_flag = 150;
  271. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  272. rt_kprintf("bak1 --> app √\n");
  273. }
  274. break;
  275. case 120: ///将备份2中的固件写入到单片机中
  276. if (bak_info.Bak_sta[2] == One)
  277. {
  278. write_app_from_bak(200);
  279. bl_par.upgrade_flag = 150;
  280. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  281. rt_kprintf("bak2 --> app √\n");
  282. }
  283. break;
  284. case 130: ///备份当前固件到备份1空间中
  285. rt_kprintf("app --> bak1 %d\n\r", bl_par.upgrade_flag);
  286. copy_app_to_bak(100);
  287. bl_par.upgrade_flag = Zero;
  288. bak_info.Bak_sta[1] = One;
  289. bak_info.FW_Version[1] = bl_par.Now_Version;
  290. bak_info.FW_Ver_tim[1] = Now_date;
  291. info_change = 1;
  292. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  293. break;
  294. case 140: ///备份当前固件到备份2空间中
  295. if (bl_par.boot_state == 110 || bl_par.boot_state == 100)
  296. {
  297. rt_kprintf("app --> bak2 %d\n\r", bl_par.upgrade_flag);
  298. copy_app_to_bak(200);
  299. bl_par.upgrade_flag = Zero;
  300. bak_info.Bak_sta[2] = One;
  301. bak_info.FW_Version[2] = bl_par.Now_Version;
  302. bak_info.FW_Ver_tim[2] = Now_date;
  303. info_change = 1;
  304. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  305. }
  306. break;
  307. case 150: /// BL能进150 说明app启动异常 使用备份固件恢复
  308. Failure_handling();
  309. break;
  310. case 200: ///无升级任务的默认值
  311. break;
  312. default: ///参数异常时复位
  313. bl_par.upgrade_flag = Zero;
  314. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  315. break;
  316. }
  317. /*
  318. *
  319. * 校验各个备份固件的情况
  320. *
  321. */
  322. ////////// 检查 IAP 区域 //////////
  323. if (bak_info.Bak_sta[0] != One && bak_info.Bak_sta[0] != Zero)
  324. {
  325. bak_info.Bak_sta[0] = Zero;
  326. // rt_kprintf("Bak_sta[0] set def\r\n");
  327. info_change = 1;
  328. }
  329. else
  330. {
  331. if (bak_info.Bak_sta[0] == One)
  332. {
  333. rt_kprintf(" IAP FW V %d.%03d T %02d/%02d/%02d\r\n",
  334. bak_info.FW_Version[0] / 1000, bak_info.FW_Version[0] % 1000,
  335. ((bak_info.FW_Ver_tim[0] >> 8) & 0x00FF) / 12 + 21, //提取年
  336. ((bak_info.FW_Ver_tim[0] >> 8) & 0x00FF) % 12, //提取月
  337. bak_info.FW_Ver_tim[0] & 0x00FF //提取日
  338. );
  339. }
  340. // else
  341. // {
  342. //// rt_kprintf(" IAP FW doesn't exist\r\n");
  343. // }
  344. }
  345. ////////// 检查 BAK1 区域 //////////
  346. // bak_info.Bak_sta[2] = Zero;
  347. if (bak_info.Bak_sta[1] != One && bak_info.Bak_sta[1] != Zero)
  348. {
  349. bak_info.Bak_sta[1] = Zero;
  350. info_change = 1;
  351. }
  352. if (bak_info.Bak_sta[1] == One)
  353. {
  354. rt_kprintf(" BAK1 FW V %d.%03d T %02d/%02d/%02d\r\n",
  355. bak_info.FW_Version[1] / 1000, bak_info.FW_Version[1] % 1000,
  356. ((bak_info.FW_Ver_tim[1] >> 8) & 0x00FF) / 12 + 21, //提取年
  357. ((bak_info.FW_Ver_tim[1] >> 8) & 0x00FF) % 12, //提取月
  358. bak_info.FW_Ver_tim[1] & 0x00FF //提取日
  359. );
  360. }
  361. else
  362. {
  363. if (bl_par.boot_state == One || bl_par.boot_state == One + 10)
  364. {
  365. if (copy_app_to_bak(100) == 1)
  366. {
  367. bak_info.Bak_sta[1] = One;
  368. bak_info.FW_Version[1] = bl_par.Now_Version;
  369. bak_info.FW_Ver_tim[1] = Now_date;
  370. info_change = 1;
  371. rt_kprintf("app --> bak1 √ V %04X T %d\r\n", bak_info.FW_Ver_tim[1], bak_info.FW_Ver_tim[1]);
  372. }
  373. }
  374. }
  375. ////////// 检查 BAK2 区域 //////////
  376. if (bak_info.Bak_sta[2] != One && bak_info.Bak_sta[2] != Zero)
  377. {
  378. bak_info.Bak_sta[2] = Zero;
  379. info_change = 1;
  380. }
  381. if (bak_info.Bak_sta[2] == One)
  382. {
  383. rt_kprintf(" BAK2 FW V %d.%03d T %02d/%02d/%02d\r\n",
  384. bak_info.FW_Version[2] / 1000, bak_info.FW_Version[2] % 1000,
  385. ((bak_info.FW_Ver_tim[2] >> 8) & 0x00FF) / 12 + 21, //提取年
  386. ((bak_info.FW_Ver_tim[2] >> 8) & 0x00FF) % 12, //提取月
  387. bak_info.FW_Ver_tim[2] & 0x00FF //提取日
  388. );
  389. }
  390. else
  391. {
  392. if (bl_par.boot_state >= 30 && bl_par.boot_state % 10 == 0)
  393. {
  394. if (copy_app_to_bak(200) == 1)
  395. {
  396. bak_info.Bak_sta[2] = One;
  397. bak_info.FW_Version[2] = bl_par.Now_Version;
  398. bak_info.FW_Ver_tim[2] = Now_date;
  399. info_change = 1;
  400. rt_kprintf("app --> bak1 √ V %04X T %d\r\n", bak_info.FW_Ver_tim[2], bak_info.FW_Ver_tim[2]);
  401. }
  402. }
  403. }
  404. // rt_kprintf("\r\n------ BAK Firmware Sta Check ------\r\n\r\n");
  405. if (bl_par.boot_state != 0)
  406. {
  407. bl_par.boot_state -= 10;
  408. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  409. }
  410. rt_kprintf("\r\n");
  411. return bl_par.upgrade_flag;
  412. }
  413. //处理升级失败的情况
  414. void Failure_handling(void)
  415. {
  416. rt_kprintf("Failure...\r\n");
  417. bl_par.iap_boot_state &= 0xFF00;
  418. bl_par.iap_boot_state = bl_par.iap_boot_state >> 8;
  419. if (bl_par.iap_boot_state == 100) //当使用IAP固件升级失败时
  420. {
  421. rt_kprintf("IAP --> App ×\r\n");
  422. bak_info.Bak_sta[0] = Zero; //清除IAP固件标记位
  423. if (bak_info.Bak_sta[1] == One)
  424. {
  425. bl_par.upgrade_flag = 110;
  426. }
  427. else if (bak_info.Bak_sta[2] == One)
  428. {
  429. bl_par.upgrade_flag = 120;
  430. }
  431. }
  432. if (bl_par.iap_boot_state == 110) //当使用BAK1固件升级失败时
  433. {
  434. rt_kprintf("BAK1 --> App ×\r\n");
  435. bak_info.Bak_sta[1] = Zero; //清除BAK1固件标记位
  436. if (bak_info.Bak_sta[2] == One)
  437. {
  438. bl_par.upgrade_flag = 120;
  439. }
  440. else if (bak_info.Bak_sta[2] == One)
  441. {
  442. bl_par.upgrade_flag = 120;
  443. }
  444. }
  445. if (bl_par.iap_boot_state == 120) //当使用BAK2固件升级失败时
  446. {
  447. rt_kprintf("BAK2 --> App ×\r\n");
  448. bak_info.Bak_sta[2] = Zero; //清除BAK2固件标记位
  449. if (bak_info.Bak_sta[0] == One)
  450. {
  451. bl_par.upgrade_flag = 100;
  452. }
  453. else if (bak_info.Bak_sta[1] == One)
  454. {
  455. bl_par.upgrade_flag = 110;
  456. }
  457. else //当所有固件都无法开机时
  458. {
  459. // for (uint8_t i = 0; i < 100; i++)
  460. // {
  461. // HAL_GPIO_TogglePin(RUN_STATUS_GPIO_Port, RUN_STATUS_Pin); //开启led
  462. // rt_thread_mdelay(50);
  463. // }
  464. }
  465. }
  466. bl_par.iap_boot_state = 0;
  467. ef_set_env_blob("bak_info", &bak_info, sizeof(Bak_info));
  468. ef_set_env_blob("bl_par", &bl_par, sizeof(bl_par));
  469. }