6464#define BOOTMGR_HASH_SIZE 32
6565#define BOOTMGR_BUFF_SIZE 512
6666
67- #define BOOTMGR_WAIT_SAFE_MODE_MS 2400
68- #define BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS 400
67+ #define BOOTMGR_WAIT_SAFE_MODE_0_MS 3000
68+ #define BOOTMGR_WAIT_SAFE_MODE_0_BLINK_MS 500
6969
70- #define BOOTMGR_SAFE_MODE_ENTER_MS 1600
71- #define BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS 160
70+ #define BOOTMGR_WAIT_SAFE_MODE_1_MS 3000
71+ #define BOOTMGR_WAIT_SAFE_MODE_1_BLINK_MS 250
72+
73+ #define BOOTMGR_WAIT_SAFE_MODE_2_MS 1500
74+ #define BOOTMGR_WAIT_SAFE_MODE_2_BLINK_MS 100
7275
7376//*****************************************************************************
7477// Exported functions declarations
@@ -79,9 +82,10 @@ extern void bootmgr_run_app (_u32 base);
7982// Local functions declarations
8083//*****************************************************************************
8184static void bootmgr_board_init (void );
82- static bool bootmgr_verify (void );
85+ static bool bootmgr_verify (_u8 * image );
8386static void bootmgr_load_and_execute (_u8 * image );
84- static bool safe_mode_boot (void );
87+ static bool wait_while_blinking (uint32_t wait_time , uint32_t period , bool force_wait );
88+ static void wait_for_safe_boot (sBootInfo_t * psBootInfo );
8589static void bootmgr_image_loader (sBootInfo_t * psBootInfo );
8690
8791//*****************************************************************************
@@ -140,14 +144,14 @@ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
140144//! Board Initialization & Configuration
141145//*****************************************************************************
142146static void bootmgr_board_init (void ) {
143- // Set vector table base
147+ // set the vector table base
144148 MAP_IntVTableBaseSet ((unsigned long )& g_pfnVectors [0 ]);
145149
146- // Enable Processor Interrupts
150+ // enable processor interrupts
147151 MAP_IntMasterEnable ();
148152 MAP_IntEnable (FAULT_SYSTICK );
149153
150- // Mandatory MCU Initialization
154+ // mandatory MCU initialization
151155 PRCMCC3200MCUInit ();
152156
153157 mperror_bootloader_check_reset_cause ();
@@ -157,10 +161,10 @@ static void bootmgr_board_init(void) {
157161 antenna_init0 ();
158162#endif
159163
160- // Enable the Data Hashing Engine
164+ // enable the data hashing engine
161165 CRYPTOHASH_Init ();
162166
163- // Init the system led and the system switch
167+ // init the system led and the system switch
164168 mperror_init0 ();
165169
166170 // clear the safe boot flag, since we can't trust its content after reset
@@ -170,15 +174,15 @@ static void bootmgr_board_init(void) {
170174//*****************************************************************************
171175//! Verifies the integrity of the new application binary
172176//*****************************************************************************
173- static bool bootmgr_verify (void ) {
177+ static bool bootmgr_verify (_u8 * image ) {
174178 SlFsFileInfo_t FsFileInfo ;
175179 _u32 reqlen , offset = 0 ;
176180 _i32 fHandle ;
177181
178182 // open the file for reading
179- if (0 == sl_FsOpen (( _u8 * ) IMG_UPDATE , FS_MODE_OPEN_READ , NULL , & fHandle )) {
183+ if (0 == sl_FsOpen (image , FS_MODE_OPEN_READ , NULL , & fHandle )) {
180184 // get the file size
181- sl_FsGetInfo (( _u8 * ) IMG_UPDATE , 0 , & FsFileInfo );
185+ sl_FsGetInfo (image , 0 , & FsFileInfo );
182186
183187 if (FsFileInfo .FileLen > BOOTMGR_HASH_SIZE ) {
184188 FsFileInfo .FileLen -= BOOTMGR_HASH_SIZE ;
@@ -242,47 +246,72 @@ static void bootmgr_load_and_execute (_u8 *image) {
242246}
243247
244248//*****************************************************************************
245- //! Check for the safe mode pin
249+ //! Wait while the safe mode pin is being held high and blink the system led
250+ //! with the specified period
246251//*****************************************************************************
247- static bool safe_mode_boot ( void ) {
248- _u32 count = 0 ;
249- while ( MAP_GPIOPinRead (MICROPY_SAFE_BOOT_PORT , MICROPY_SAFE_BOOT_PORT_PIN ) &&
250- (( BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS * count ++ ) < BOOTMGR_WAIT_SAFE_MODE_MS ) ) {
252+ static bool wait_while_blinking ( uint32_t wait_time , uint32_t period , bool force_wait ) {
253+ _u32 count ;
254+ for ( count = 0 ; ( force_wait || MAP_GPIOPinRead (MICROPY_SAFE_BOOT_PORT , MICROPY_SAFE_BOOT_PORT_PIN ) ) &&
255+ (( period * count ) < wait_time ); count ++ ) {
251256 // toogle the led
252257 MAP_GPIOPinWrite (MICROPY_SYS_LED_PORT , MICROPY_SYS_LED_PORT_PIN , ~MAP_GPIOPinRead (MICROPY_SYS_LED_PORT , MICROPY_SYS_LED_PORT_PIN ));
253- UtilsDelay (UTILS_DELAY_US_TO_COUNT (BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS * 1000 ));
258+ UtilsDelay (UTILS_DELAY_US_TO_COUNT (period * 1000 ));
254259 }
255- mperror_deinit_sfe_pin ();
256260 return MAP_GPIOPinRead (MICROPY_SAFE_BOOT_PORT , MICROPY_SAFE_BOOT_PORT_PIN ) ? true : false;
257261}
258262
259263//*****************************************************************************
260- //! Load the proper image based on information from boot info and executes it.
264+ //! Check for the safe mode pin
265+ //*****************************************************************************
266+ static void wait_for_safe_boot (sBootInfo_t * psBootInfo ) {
267+ if (wait_while_blinking (BOOTMGR_WAIT_SAFE_MODE_0_MS , BOOTMGR_WAIT_SAFE_MODE_0_BLINK_MS , false)) {
268+ // go back one step in time
269+ psBootInfo -> ActiveImg = psBootInfo -> PrevImg ;
270+ if (wait_while_blinking (BOOTMGR_WAIT_SAFE_MODE_1_MS , BOOTMGR_WAIT_SAFE_MODE_1_BLINK_MS , false)) {
271+ // go back directly to the factory image
272+ psBootInfo -> ActiveImg = IMG_ACT_FACTORY ;
273+ wait_while_blinking (BOOTMGR_WAIT_SAFE_MODE_2_MS , BOOTMGR_WAIT_SAFE_MODE_2_BLINK_MS , true);
274+ }
275+ // turn off the system led
276+ MAP_GPIOPinWrite (MICROPY_SYS_LED_PORT , MICROPY_SYS_LED_PORT_PIN , 0 );
277+ // request a safe boot to the application
278+ PRCMRequestSafeBoot ();
279+ }
280+ // uninit the safe boot pin
281+ mperror_deinit_sfe_pin ();
282+ }
283+
284+ //*****************************************************************************
285+ //! Load the proper image based on the information from the boot info
286+ //! and launch it.
261287//*****************************************************************************
262288static void bootmgr_image_loader (sBootInfo_t * psBootInfo ) {
263289 _i32 fhandle ;
264- if (safe_mode_boot ()) {
265- _u32 count = 0 ;
266- while ((BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS * count ++ ) < BOOTMGR_SAFE_MODE_ENTER_MS ) {
267- // toogle the led
268- MAP_GPIOPinWrite (MICROPY_SYS_LED_PORT , MICROPY_SYS_LED_PORT_PIN , ~MAP_GPIOPinRead (MICROPY_SYS_LED_PORT , MICROPY_SYS_LED_PORT_PIN ));
269- UtilsDelay (UTILS_DELAY_US_TO_COUNT (BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS * 1000 ));
270- }
271- psBootInfo -> ActiveImg = IMG_ACT_FACTORY ;
272- // turn the led off
273- MAP_GPIOPinWrite (MICROPY_SYS_LED_PORT , MICROPY_SYS_LED_PORT_PIN , 0 );
274- // request a safe boot to the application
275- PRCMRequestSafeBoot ();
290+ _u8 * image ;
291+
292+ // search for the active image
293+ switch (psBootInfo -> ActiveImg ) {
294+ case IMG_ACT_UPDATE1 :
295+ image = (unsigned char * )IMG_UPDATE1 ;
296+ break ;
297+ case IMG_ACT_UPDATE2 :
298+ image = (unsigned char * )IMG_UPDATE2 ;
299+ break ;
300+ default :
301+ image = (unsigned char * )IMG_FACTORY ;
302+ break ;
276303 }
277- // do we have a new update image that needs to be verified?
278- else if ((psBootInfo -> ActiveImg == IMG_ACT_UPDATE ) && (psBootInfo -> Status == IMG_STATUS_CHECK )) {
279- if (!bootmgr_verify ()) {
280- // delete the corrupted file
281- sl_FsDel ((_u8 * )IMG_UPDATE , 0 );
282- // switch to the factory image
283- psBootInfo -> ActiveImg = IMG_ACT_FACTORY ;
304+
305+ // do we have a new image that needs to be verified?
306+ if ((psBootInfo -> ActiveImg != IMG_ACT_FACTORY ) && (psBootInfo -> Status == IMG_STATUS_CHECK )) {
307+ if (!bootmgr_verify (image )) {
308+ // verification failed, delete the broken file
309+ sl_FsDel (image , 0 );
310+ // switch to the previous image
311+ psBootInfo -> ActiveImg = psBootInfo -> PrevImg ;
312+ psBootInfo -> PrevImg = IMG_ACT_FACTORY ;
284313 }
285- // in any case, set the status as "READY"
314+ // in any case, change the status to "READY"
286315 psBootInfo -> Status = IMG_STATUS_READY ;
287316 // write the new boot info
288317 if (!sl_FsOpen ((unsigned char * )IMG_BOOT_INFO , FS_MODE_OPEN_WRITE , NULL , & fhandle )) {
@@ -292,24 +321,34 @@ static void bootmgr_image_loader(sBootInfo_t *psBootInfo) {
292321 }
293322 }
294323
295- // now boot the active image
296- if (IMG_ACT_UPDATE == psBootInfo -> ActiveImg ) {
297- bootmgr_load_and_execute ((unsigned char * )IMG_UPDATE );
298- }
299- else {
300- bootmgr_load_and_execute ((unsigned char * )IMG_FACTORY );
324+ // this one might modify the boot info hence it MUST be called after
325+ // bootmgr_verify! (so that the changes are not saved to flash)
326+ wait_for_safe_boot (psBootInfo );
327+
328+ // select the active image again, since it might have changed
329+ switch (psBootInfo -> ActiveImg ) {
330+ case IMG_ACT_UPDATE1 :
331+ image = (unsigned char * )IMG_UPDATE1 ;
332+ break ;
333+ case IMG_ACT_UPDATE2 :
334+ image = (unsigned char * )IMG_UPDATE2 ;
335+ break ;
336+ default :
337+ image = (unsigned char * )IMG_FACTORY ;
338+ break ;
301339 }
340+ bootmgr_load_and_execute (image );
302341}
303342
304343//*****************************************************************************
305344//! Main function
306345//*****************************************************************************
307346int main (void ) {
308- sBootInfo_t sBootInfo = { .ActiveImg = IMG_ACT_FACTORY , .Status = IMG_STATUS_READY };
347+ sBootInfo_t sBootInfo = { .ActiveImg = IMG_ACT_FACTORY , .Status = IMG_STATUS_READY , . PrevImg = IMG_ACT_FACTORY };
309348 bool bootapp = false;
310349 _i32 fhandle ;
311350
312- // Board Initialization
351+ // board setup
313352 bootmgr_board_init ();
314353
315354 // start simplelink since we need it to access the sflash
@@ -322,12 +361,13 @@ int main (void) {
322361 }
323362 sl_FsClose (fhandle , 0 , 0 , 0 );
324363 }
364+ // boot info file not present (or read failed)
325365 if (!bootapp ) {
326366 // create a new boot info file
327367 _u32 BootInfoCreateFlag = _FS_FILE_OPEN_FLAG_COMMIT | _FS_FILE_PUBLIC_WRITE | _FS_FILE_PUBLIC_READ ;
328368 if (!sl_FsOpen ((unsigned char * )IMG_BOOT_INFO , FS_MODE_OPEN_CREATE ((2 * sizeof (sBootInfo_t )),
329369 BootInfoCreateFlag ), NULL , & fhandle )) {
330- // Write the default boot info.
370+ // write the default boot info.
331371 if (sizeof (sBootInfo_t ) == sl_FsWrite (fhandle , 0 , (unsigned char * )& sBootInfo , sizeof (sBootInfo_t ))) {
332372 bootapp = true;
333373 }
@@ -343,14 +383,14 @@ int main (void) {
343383 // stop simplelink
344384 sl_Stop (SL_STOP_TIMEOUT );
345385
346- // if we've reached this point, then it means a fatal error occurred and the application
347- // could not be loaded, so, loop forever and signal the crash to the user
386+ // if we've reached this point, then it means that a fatal error has occurred and the
387+ // application could not be loaded, so, loop forever and signal the crash to the user
348388 while (true) {
349389 // keep the bld on
350390 MAP_GPIOPinWrite (MICROPY_SYS_LED_PORT , MICROPY_SYS_LED_PORT_PIN , MICROPY_SYS_LED_PORT_PIN );
351- __asm volatile (" dsb \n"
352- " isb \n"
353- " wfi \n" );
391+ __asm volatile (" dsb \n"
392+ " isb \n"
393+ " wfi \n" );
354394 }
355395}
356396
0 commit comments