Skip to content

Commit e955089

Browse files
author
Daniel Campora
committed
cc3200: Implement new OTA mechanism with 2 firmware update slots.
1 parent 9309e60 commit e955089

File tree

8 files changed

+200
-85
lines changed

8 files changed

+200
-85
lines changed

cc3200/bootmgr/bootloader.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ BOOT_CPPDEFINES = -Dgcc -DBOOTLOADER -DTARGET_IS_CC3200 -DSL_TINY
1919
BOOT_HAL_SRC_C = $(addprefix hal/,\
2020
cpu.c \
2121
interrupt.c \
22+
gpio.c \
2223
pin.c \
2324
prcm.c \
2425
shamd5.c \

cc3200/bootmgr/flc.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ extern "C"
4343
*******************************************************************************/
4444
#define IMG_BOOT_INFO "/sys/bootinfo.bin"
4545
#define IMG_FACTORY "/sys/factimg.bin"
46-
#define IMG_UPDATE "/sys/updtimg.bin"
46+
#define IMG_UPDATE1 "/sys/updtimg1.bin"
47+
#define IMG_UPDATE2 "/sys/updtimg2.bin"
48+
#define IMG_PREFIX "/sys/updtimg"
4749

4850
#define IMG_SRVPACK "/sys/servicepack.ucf"
4951
#define SRVPACK_SIGN "/sys/servicepack.sig"
@@ -55,7 +57,7 @@ extern "C"
5557
/******************************************************************************
5658
Special file sizes
5759
*******************************************************************************/
58-
#define IMG_SIZE (232 * 1024) /* 16KB are reserved for the bootloader and at least 8KB for the heap*/
60+
#define IMG_SIZE (192 * 1024) /* 16KB are reserved for the bootloader and at least 48KB for the heap*/
5961
#define SRVPACK_SIZE (16 * 1024)
6062
#define SIGN_SIZE (2 * 1024)
6163
#define CA_KEY_SIZE (4 * 1024)
@@ -64,21 +66,22 @@ extern "C"
6466
Active Image
6567
*******************************************************************************/
6668
#define IMG_ACT_FACTORY 0
67-
#define IMG_ACT_UPDATE 1
69+
#define IMG_ACT_UPDATE1 1
70+
#define IMG_ACT_UPDATE2 2
6871

6972
#define IMG_STATUS_CHECK 0
7073
#define IMG_STATUS_READY 1
7174

7275
/******************************************************************************
7376
Boot Info structure
7477
*******************************************************************************/
75-
typedef struct sBootInfo
78+
typedef struct _sBootInfo_t
7679
{
7780
_u8 ActiveImg;
7881
_u8 Status;
82+
_u8 PrevImg;
7983
_u8 : 8;
80-
_u8 : 8;
81-
}sBootInfo_t;
84+
} sBootInfo_t;
8285

8386

8487
/******************************************************************************

cc3200/bootmgr/main.c

Lines changed: 96 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,14 @@
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
//*****************************************************************************
8184
static void bootmgr_board_init (void);
82-
static bool bootmgr_verify (void);
85+
static bool bootmgr_verify (_u8 *image);
8386
static 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);
8589
static void bootmgr_image_loader (sBootInfo_t *psBootInfo);
8690

8791
//*****************************************************************************
@@ -140,14 +144,14 @@ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
140144
//! Board Initialization & Configuration
141145
//*****************************************************************************
142146
static 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
//*****************************************************************************
262288
static 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
//*****************************************************************************
307346
int 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

cc3200/ftp/ftp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static void ftp_process_cmd (void) {
764764
ftp_send_reply(150, NULL);
765765
}
766766
else {
767+
// to unlock the updater
768+
updater_finnish();
767769
ftp_data.state = E_FTP_STE_END_TRANSFER;
768770
ftp_send_reply(550, NULL);
769771
}

0 commit comments

Comments
 (0)