bl_main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "user.h"
  22. extern const uint32_t __isr_start_address;
  23. extern const uint32_t __os_heap_start;
  24. uint32_t SystemCoreClock;
  25. #define FW_UPGRADE_START_TIME 300
  26. #define FW_UPGRADE_ALL_TIME 5000
  27. #define FW_UPGRADE_DATA_TIME 50
  28. #define FW_OTA_FLASH_BUF_LEN 4096
  29. enum
  30. {
  31. FW_UPGRADE_STATE_IDLE,
  32. FW_UPGRADE_STATE_START,
  33. FW_UPGRADE_STATE_RUN,
  34. FW_UPGRADE_STATE_WAIT_END,
  35. };
  36. typedef struct
  37. {
  38. Buffer_Struct FWDataBuffer;
  39. uint32_t Data[16 * 1024];
  40. uint32_t FWStartAddress;
  41. uint32_t FWTotalLen;
  42. uint32_t FWCRC32;
  43. uint32_t FinishLen;
  44. uint32_t NextAddress;
  45. uint32_t NextEraseAddress;
  46. uint8_t State;
  47. uint8_t ForceOut;
  48. }BL_CtrlStuct;
  49. #define BL_DBG DBG_INFO
  50. //#define BL_DBG(X, Y...)
  51. typedef void (*pFunction)(void);
  52. static uint32_t CRC32_Table[256];
  53. static BL_CtrlStuct prvBL;
  54. void Jump_AppRun(uint32_t Address)
  55. {
  56. /* Jump to user application */
  57. pFunction Jump_To_Application;
  58. uint32_t JumpAddress;
  59. __disable_irq();
  60. DBG_INFO("\r\njump to 0x%x !", Address);
  61. JumpAddress = *(__IO uint32_t*) (Address + 4);
  62. Jump_To_Application = (pFunction) JumpAddress;
  63. /* Initialize user application's Stack Pointer */
  64. __set_MSP(*(__IO uint32_t*) Address);
  65. /* Jump to application */
  66. Jump_To_Application();
  67. }
  68. uint8_t BL_CheckFlashPage(uint32_t Page, uint32_t Address)
  69. {
  70. uint32_t EndAddress = Page * __FLASH_SECTOR_SIZE__ ;
  71. if (Address >= EndAddress)
  72. {
  73. return 1;
  74. }
  75. else
  76. {
  77. return 0;
  78. }
  79. }
  80. uint32_t BL_GetFlashPage(uint32_t Address)
  81. {
  82. return Address/__FLASH_SECTOR_SIZE__;
  83. }
  84. void BL_UnlockFlash(void)
  85. {
  86. }
  87. void BL_LockFlash(void)
  88. {
  89. }
  90. void BL_EraseSector(uint32_t address)
  91. {
  92. Flash_EraseSector(address, 1);
  93. // BL_DBG("%x", address);
  94. // FLASH_EraseSector(address);
  95. // CACHE_CleanAll(CACHE);
  96. }
  97. void BL_ProgramData(uint32_t address, uint32_t *Data, uint32_t Len)
  98. {
  99. Flash_ProgramData(address, Data, Len, 1);
  100. // BL_DBG("%x", address);
  101. // FLASH_ProgramPage(address, Len, Data);
  102. // CACHE_CleanAll(CACHE);
  103. }
  104. void FileSystem_Init(void)
  105. {
  106. }
  107. int32_t BL_StartNewDownload(uint32_t Address, uint32_t TotalLen, uint32_t CRC32)
  108. {
  109. if (prvBL.State != FW_UPGRADE_STATE_IDLE)
  110. {
  111. return -1;
  112. }
  113. prvBL.FWStartAddress = Address;
  114. prvBL.FWTotalLen = TotalLen;
  115. prvBL.FWCRC32 = CRC32;
  116. prvBL.State = FW_UPGRADE_STATE_START;
  117. prvBL.NextAddress = Address;
  118. return 0;
  119. }
  120. int BL_DownloadAddData(uint32_t PacketSn, uint8_t *Data, uint32_t Len, uint32_t *NextPacketSn)
  121. {
  122. if (prvBL.NextAddress != PacketSn)
  123. {
  124. *NextPacketSn = prvBL.NextAddress;
  125. return -1;
  126. }
  127. else
  128. {
  129. Buffer_StaticWrite(&prvBL.FWDataBuffer, Data, Len);
  130. prvBL.NextAddress += Len;
  131. *NextPacketSn = prvBL.NextAddress;
  132. return prvBL.FWDataBuffer.Pos;
  133. }
  134. }
  135. uint8_t BL_DownloadEnd(void)
  136. {
  137. if (prvBL.State != FW_UPGRADE_STATE_RUN)
  138. {
  139. return ERROR_OPERATION_FAILED;
  140. }
  141. prvBL.State = FW_UPGRADE_STATE_WAIT_END;
  142. return ERROR_NONE;
  143. }
  144. uint8_t BL_RunAPP(void)
  145. {
  146. prvBL.ForceOut = 1;
  147. }
  148. void Local_Upgrade(void)
  149. {
  150. uint8_t PageData[256];
  151. uint32_t ProgramLen, CRC32;
  152. uint64_t AllToTick = GetSysTick() + FW_UPGRADE_START_TIME * CORE_TICK_1MS;
  153. uint64_t DataToTick = GetSysTick() + FW_UPGRADE_DATA_TIME * CORE_TICK_1MS;
  154. uint8_t ConnectCnt = 0;
  155. DBG_Response(DBG_DEVICE_FW_UPGRADE_READY, ERROR_NONE, &ConnectCnt, 1);
  156. while(!prvBL.ForceOut)
  157. {
  158. WDT_Feed();
  159. switch(prvBL.State)
  160. {
  161. case FW_UPGRADE_STATE_IDLE:
  162. if (DataToTick <= GetSysTick())
  163. {
  164. ConnectCnt++;
  165. DataToTick = GetSysTick() + FW_UPGRADE_DATA_TIME * CORE_TICK_1MS;
  166. DBG_Response(DBG_DEVICE_FW_UPGRADE_READY, ERROR_NONE, &ConnectCnt, 1);
  167. }
  168. break;
  169. case FW_UPGRADE_STATE_START:
  170. AllToTick = GetSysTick() + FW_UPGRADE_ALL_TIME * CORE_TICK_1MS;
  171. BL_EraseSector(prvBL.FWStartAddress);
  172. prvBL.NextEraseAddress = prvBL.FWStartAddress + __FLASH_SECTOR_SIZE__;
  173. prvBL.FinishLen = 0;
  174. prvBL.State = FW_UPGRADE_STATE_RUN;
  175. break;
  176. case FW_UPGRADE_STATE_RUN:
  177. case FW_UPGRADE_STATE_WAIT_END:
  178. if (prvBL.FinishLen < prvBL.FWTotalLen)
  179. {
  180. if ((prvBL.FWDataBuffer.Pos + prvBL.FinishLen) >= prvBL.FWTotalLen)
  181. {
  182. AllToTick = GetSysTick() + FW_UPGRADE_ALL_TIME * CORE_TICK_1MS;
  183. if ((prvBL.FWStartAddress + prvBL.FinishLen) >= prvBL.NextEraseAddress)
  184. {
  185. BL_EraseSector(prvBL.NextEraseAddress);
  186. prvBL.NextEraseAddress += __FLASH_SECTOR_SIZE__;
  187. }
  188. ProgramLen = (prvBL.FWDataBuffer.Pos >= __FLASH_PAGE_SIZE__)?__FLASH_PAGE_SIZE__:prvBL.FWDataBuffer.Pos;
  189. __disable_irq();
  190. memcpy(PageData, prvBL.FWDataBuffer.Data, ProgramLen);
  191. OS_BufferRemove(&prvBL.FWDataBuffer, ProgramLen);
  192. __enable_irq();
  193. BL_ProgramData(prvBL.FWStartAddress + prvBL.FinishLen, PageData, ProgramLen);
  194. prvBL.FinishLen += ProgramLen;
  195. }
  196. else if (prvBL.FWDataBuffer.Pos >= __FLASH_PAGE_SIZE__)
  197. {
  198. AllToTick = GetSysTick() + FW_UPGRADE_ALL_TIME * CORE_TICK_1MS;
  199. if ((prvBL.FWStartAddress + prvBL.FinishLen) >= prvBL.NextEraseAddress)
  200. {
  201. BL_EraseSector(prvBL.NextEraseAddress);
  202. prvBL.NextEraseAddress += __FLASH_SECTOR_SIZE__;
  203. }
  204. ProgramLen = __FLASH_PAGE_SIZE__;
  205. __disable_irq();
  206. memcpy(PageData, prvBL.FWDataBuffer.Data, ProgramLen);
  207. OS_BufferRemove(&prvBL.FWDataBuffer, ProgramLen);
  208. __enable_irq();
  209. BL_ProgramData(prvBL.FWStartAddress + prvBL.FinishLen, PageData, ProgramLen);
  210. prvBL.FinishLen += ProgramLen;
  211. }
  212. }
  213. else
  214. {
  215. CRC32 = CRC32_Cal(CRC32_Table, prvBL.FWStartAddress, prvBL.FWTotalLen, CRC32_START);
  216. if (CRC32 != prvBL.FWCRC32)
  217. {
  218. DBG_Response(DBG_DEVICE_FW_UPGRADE_RESULT, ERROR_PROTOCL, &CRC32, 4);
  219. }
  220. else
  221. {
  222. DBG_Response(DBG_DEVICE_FW_UPGRADE_RESULT, ERROR_NONE, &CRC32, 4);
  223. }
  224. AllToTick = GetSysTick() + FW_UPGRADE_START_TIME * CORE_TICK_1MS;
  225. prvBL.State = FW_UPGRADE_STATE_IDLE;
  226. DataToTick = GetSysTick() + FW_UPGRADE_DATA_TIME * CORE_TICK_1MS;
  227. }
  228. break;
  229. default:
  230. break;
  231. }
  232. if (AllToTick <= GetSysTick())
  233. {
  234. prvBL.ForceOut = 1;
  235. DBG_Response(DBG_DEVICE_FW_UPGRADE_RESULT, ERROR_TIMEOUT, &ConnectCnt, 1);
  236. }
  237. }
  238. }
  239. typedef struct
  240. {
  241. uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
  242. uint32_t CRC32; //后续字节的CRC32校验,所有CRC32规则与ZIP压缩一致
  243. uint32_t Param; //升级参数,其中byte0升级类型,byte1升级包存放位置
  244. uint32_t DataStartAddress;//升级包在flash中的起始地址
  245. uint32_t DataLen;
  246. uint32_t DataCRC32;//整包的CRC32
  247. char FilePath[128];//升级包在文件系统中的绝对路径
  248. }CoreUpgrade_HeadStruct;
  249. static int32_t BL_OTAReadDataInFlash(void *pData, void *pParam)
  250. {
  251. Buffer_Struct *pBuffer = (Buffer_Struct *)pParam;
  252. memcpy(pBuffer->Data, pData, pBuffer->Pos);
  253. return 0;
  254. }
  255. static int32_t BL_OTAReadDataInSpiFlash(void *pData, void *pParam)
  256. {
  257. Buffer_Struct *pBuffer = (Buffer_Struct *)pParam;
  258. }
  259. static int32_t BL_OTAReadDataInFS(void *pData, void *pParam)
  260. {
  261. Buffer_Struct *pBuffer = (Buffer_Struct *)pParam;
  262. }
  263. static void BL_OTAErase(uint32_t Address, uint32_t Len)
  264. {
  265. uint32_t Pos = 0;
  266. while(Pos < Len)
  267. {
  268. Flash_EraseSector(Address + Pos, 0);
  269. Pos += __FLASH_SECTOR_SIZE__;
  270. }
  271. }
  272. static void BL_OTAWrite(uint32_t Address, uint8_t *Data, uint32_t Len)
  273. {
  274. uint32_t Pos = 0;
  275. while(Pos < Len)
  276. {
  277. if ((Len - Pos) > __FLASH_PAGE_SIZE__)
  278. {
  279. Flash_ProgramData(Address + Pos, Data + Pos, __FLASH_PAGE_SIZE__, 0);
  280. Pos += __FLASH_PAGE_SIZE__;
  281. }
  282. else
  283. {
  284. Flash_ProgramData(Address + Pos, Data + Pos, Len - Pos, 0);
  285. Pos += Len - Pos;
  286. }
  287. }
  288. }
  289. void Remote_Upgrade(void)
  290. {
  291. CoreUpgrade_HeadStruct Head;
  292. Buffer_Struct ReadBuffer;
  293. CBFuncEx_t pReadFunc;
  294. PV_Union uPV;
  295. uint32_t Check;
  296. uint32_t DoneLen;
  297. int32_t Result;
  298. uint8_t Reboot = 0;
  299. uint8_t FlashData[FW_OTA_FLASH_BUF_LEN];
  300. Buffer_StaticInit(&ReadBuffer, FlashData, FW_OTA_FLASH_BUF_LEN);
  301. memcpy(&Head, __FLASH_OTA_INFO_ADDR__, sizeof(CoreUpgrade_HeadStruct));
  302. Check = CRC32_Cal(CRC32_Table, &Head.Param, sizeof(Head) - 8, 0xffffffff);
  303. if (Head.MaigcNum != __APP_START_MAGIC__)
  304. {
  305. DBG_INFO("no ota info");
  306. return;
  307. }
  308. if (Check != Head.CRC32)
  309. {
  310. DBG_INFO("ota info error");
  311. return;
  312. }
  313. uPV.u32 = Head.Param;
  314. switch(uPV.u8[1])
  315. {
  316. case CORE_OTA_IN_FLASH:
  317. Check = CRC32_Cal(CRC32_Table, Head.DataStartAddress, Head.DataLen, 0xffffffff);
  318. if (Check != Head.DataCRC32)
  319. {
  320. DBG_INFO("ota file CRC32: %x,%x", Check, Head.DataCRC32);
  321. goto OTA_END;
  322. }
  323. pReadFunc = BL_OTAReadDataInFlash;
  324. break;
  325. default:
  326. DBG_INFO("core ota storage mode %u not support", uPV.u8[1]);
  327. return;
  328. break;
  329. }
  330. switch(uPV.u8[0])
  331. {
  332. case CORE_OTA_MODE_FULL:
  333. goto OTA_FULL;
  334. break;
  335. default:
  336. DBG_INFO("core ota mode %u not support", uPV.u8[0]);
  337. return;
  338. break;
  339. }
  340. goto OTA_END;
  341. OTA_FULL:
  342. DoneLen = 0;
  343. while(DoneLen < Head.DataLen)
  344. {
  345. ReadBuffer.Pos = ((Head.DataLen - DoneLen) > ReadBuffer.MaxLen)?ReadBuffer.MaxLen:(Head.DataLen - DoneLen);
  346. Result = pReadFunc(Head.DataStartAddress + DoneLen, &ReadBuffer);
  347. if (Result < 0)
  348. {
  349. Reboot = 1;
  350. DBG_INFO("core ota read data fail");
  351. goto OTA_END;
  352. }
  353. if (memcmp(__FLASH_APP_START_ADDR__ + DoneLen, ReadBuffer.Data, ReadBuffer.Pos))
  354. {
  355. BL_OTAErase(__FLASH_APP_START_ADDR__ + DoneLen, ReadBuffer.Pos);
  356. BL_OTAWrite(__FLASH_APP_START_ADDR__ + DoneLen, ReadBuffer.Data, ReadBuffer.Pos);
  357. }
  358. DoneLen += ReadBuffer.Pos;
  359. }
  360. Check = CRC32_Cal(CRC32_Table, __FLASH_APP_START_ADDR__, Head.DataLen, 0xffffffff);
  361. if (Head.DataCRC32 != Check)
  362. {
  363. Reboot = 1;
  364. DBG_INFO("core ota final check crc32 fail %x %x", Check, Head.DataCRC32);
  365. goto OTA_END;
  366. }
  367. goto OTA_END;
  368. OTA_DIFF:
  369. goto OTA_END;
  370. OTA_END:
  371. if (Reboot)
  372. {
  373. NVIC_SystemReset();
  374. while(1){;}
  375. }
  376. else
  377. {
  378. BL_EraseSector(__FLASH_OTA_INFO_ADDR__);
  379. }
  380. }
  381. void SystemInit(void)
  382. {
  383. SYSCTRL->LDO25_CR = (1 << 5);
  384. SCB->VTOR = (uint32_t)(&__isr_start_address);
  385. #ifdef __USE_XTL__
  386. SYSCTRL->FREQ_SEL = 0x20000000 | SYSCTRL_FREQ_SEL_HCLK_DIV_1_2 | (1 << 13) | SYSCTRL_FREQ_SEL_CLOCK_SOURCE_EXT | SYSCTRL_FREQ_SEL_XTAL_192Mhz;
  387. #else
  388. SYSCTRL->FREQ_SEL = 0x20000000 | SYSCTRL_FREQ_SEL_HCLK_DIV_1_2 | (1 << 13) | SYSCTRL_FREQ_SEL_CLOCK_SOURCE_INC | SYSCTRL_FREQ_SEL_XTAL_192Mhz;
  389. #endif
  390. WDT_SetTimeout(__WDT_TO_MS__);
  391. WDT_ModeConfig(WDT_Mode_Interrupt);
  392. WDT_Enable();
  393. // QSPI->DEVICE_PARA = (QSPI->DEVICE_PARA & 0xFFFF) | (68 << 16);
  394. #if (__FPU_PRESENT) && (__FPU_USED == 1)
  395. SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11*2));
  396. #endif
  397. SYSCTRL->CG_CTRL1 = SYSCTRL_APBPeriph_UART0|SYSCTRL_APBPeriph_GPIO|SYSCTRL_APBPeriph_TIMM0;
  398. SYSCTRL->CG_CTRL2 = SYSCTRL_AHBPeriph_DMA|SYSCTRL_AHBPeriph_USB;
  399. SYSCTRL->LOCK_R &= ~SYSCTRL_USB_RESET;
  400. SYSCTRL->SOFT_RST2 |= SYSCTRL_USB_RESET;
  401. QSPI->DEVICE_PARA = (QSPI->DEVICE_PARA & 0x0000fff0) | (16 << 16) |(0x0a);
  402. // QSPI_Init(NULL);
  403. // QSPI_SetLatency(0);
  404. }
  405. void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
  406. {
  407. SystemCoreClock = HSE_VALUE * (((SYSCTRL->FREQ_SEL & SYSCTRL_FREQ_SEL_XTAL_Mask) >> SYSCTRL_FREQ_SEL_XTAL_Pos) + 1);
  408. }
  409. int main(void)
  410. {
  411. uint32_t AppInfo[4];
  412. CRC32_CreateTable(CRC32_Table, CRC32_GEN);
  413. __NVIC_SetPriorityGrouping(7 - __NVIC_PRIO_BITS);//对于freeRTOS必须这样配置
  414. SystemCoreClockUpdate();
  415. CoreTick_Init();
  416. cm_backtrace_init(NULL, NULL, NULL);
  417. Uart_GlobalInit();
  418. DMA_GlobalInit();
  419. DBG_Init(0);
  420. FileSystem_Init();
  421. Buffer_StaticInit(&prvBL.FWDataBuffer, prvBL.Data, sizeof(prvBL.Data));
  422. LOCAL_UPGRADE_START:
  423. Local_Upgrade();
  424. Uart_ChangeBR(DBG_UART_ID, DBG_UART_BR);
  425. #ifndef __RAMRUN__
  426. DBG_INFO("check core ota!");
  427. Remote_Upgrade();
  428. // __disable_irq();
  429. BL_LockFlash();
  430. memcpy(AppInfo, __FLASH_APP_START_ADDR__, sizeof(AppInfo));
  431. if (__APP_START_MAGIC__ == AppInfo[0])
  432. {
  433. #ifdef __DEBUG__
  434. DBG_INFO("\r\nbootloader build debug %s %s %x!", __DATE__, __TIME__, QSPI->DEVICE_PARA);
  435. #else
  436. DBG_INFO("\r\nbootloader build release %s %s!", __DATE__, __TIME__, QSPI->DEVICE_PARA);
  437. #endif
  438. Jump_AppRun(__FLASH_APP_START_ADDR__ + AppInfo[1]);
  439. }
  440. else
  441. {
  442. goto LOCAL_UPGRADE_START;
  443. }
  444. // i = i / j; //只是测试一下backtrace功能
  445. #endif
  446. NVIC_SystemReset();
  447. }