This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

bootloader_app_start() doesn't run newly flashed app

Hi,

i'm doing my own bootloader and i want to use external flash to download image trough a spi. Now it almost works. But after an app image has been successfully transferred to nrf52 flash and the bootloader reaches bootloader_app_start(DFU_BANK_0_REGION_START), the app is hanged. It seems the bootloader_app_start() works fine, crash occurred in the app at ble_stack_init(), but ONLY once after burning. Pin reset makes newly flashed app to run normal way. So i suppose something wrong in bootloader's SD init\deinit or wrong pstorage_store() callback handling.

My code flow:

static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data)
{
	pstorage_is_busy = (result != NRF_SUCCESS);
}


// copied from bootloader.c\wait_for_events(void) 77
// this one used for wait pstorage_store() completion
static void pstorage_wait(void)
{
	pstorage_is_busy = true;
	while (pstorage_is_busy)
	{
		// Wait in low power state for any events.
		uint32_t err_code = sd_app_evt_wait();
		APP_ERROR_CHECK(err_code);
		// Event received. Process it from the scheduler.
		app_sched_execute();
	}
}

// END OF BOOTLOADER MAIN FUNC
if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))
{
	err_code = dfu_init();
	APP_ERROR_CHECK(err_code);
	FlashSpiInit();
	dfu_register_callback(dfu_cb_handler);
	start_data_process(FW_RST_APP_ADDRESS); // load start packet from external flash
	 // load init packet from external flash, uses pstorage_wait();
	init_data_process();
	// load image packet from external flash, uses pstorage_wait();
	app_data_process(); 
	err_code = dfu_image_validate();
	APP_ERROR_CHECK(err_code);
	err_code = dfu_image_activate();
	APP_ERROR_CHECK(err_code);
	wait_for_events();
}

if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress())
{
    bootloader_app_start(DFU_BANK_0_REGION_START);
}

NVIC_SystemReset();

i use wait_for_events(); directly from example library bootloader.c (remove the static key).

Any help appreciated.

Parents
  • The problem is solved. The source of bug was spi init\deinit procedure. The NRF_SPIM1 module is used by either bootloade and app, so spi deinit is necessary for bootloader, but calling nrf_drv_spi_uninit() it seems was not enough. Subsequent call of spi_init() in app hangs CPU. Adding manual spi event reset solves the problem.

    	FlashSpiReadStop();
    	nrf_drv_spi_uninit(&AuxSpi);
    	NRF_SPIM1->EVENTS_END = 0;
    	NRF_SPIM1->EVENTS_ENDRX = 0;
    	NRF_SPIM1->EVENTS_ENDTX = 0;
    	NRF_SPIM1->EVENTS_STARTED = 0;
    	NRF_SPIM1->EVENTS_STOPPED = 0;
    

    May be the same behavior should be added in nrf_drv_spi.c

Reply
  • The problem is solved. The source of bug was spi init\deinit procedure. The NRF_SPIM1 module is used by either bootloade and app, so spi deinit is necessary for bootloader, but calling nrf_drv_spi_uninit() it seems was not enough. Subsequent call of spi_init() in app hangs CPU. Adding manual spi event reset solves the problem.

    	FlashSpiReadStop();
    	nrf_drv_spi_uninit(&AuxSpi);
    	NRF_SPIM1->EVENTS_END = 0;
    	NRF_SPIM1->EVENTS_ENDRX = 0;
    	NRF_SPIM1->EVENTS_ENDTX = 0;
    	NRF_SPIM1->EVENTS_STARTED = 0;
    	NRF_SPIM1->EVENTS_STOPPED = 0;
    

    May be the same behavior should be added in nrf_drv_spi.c

Children
No Data
Related