Bootloader working in debugger only

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm working with the SAMS70 and want to get a bootloader going. I have an application that is working with an LCD display and when I debug through the bootloader I can see it jump to my application and the LCD initializes and displays information. Once I try to run the bootloader without the debugger it just hangs and the LCD is never initialized.

My bootloader is at: rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00010000

My application is at: rom (rx) : ORIGIN = 0x00410000, LENGTH = 0x00040000

Right now I just have the bootloader jumping to the application to test its funcationality, here is the code:

#define SW_Slot_A_Address		0x00410000 
#define SW_Slot_A_Reset_Address (SW_Slot_A_Address+4)


int main (void)
{
	uint8_t i;
	
	/* Ensure all priority bits are assigned as preemption priority bits. */
	NVIC_SetPriorityGrouping(__NVIC_PRIO_BITS);
	__set_BASEPRI(0);
	
	/** Disable interrupts */
	__disable_irq();
	/* Disable SysTick */
	SysTick->CTRL = 0;
	/* Disable IRQs & clear pending IRQs */
	for (i = 0; i < 8; i++)
	{
		NVIC->ICER[i] = 0xFFFFFFFF;
		NVIC->ICPR[i] = 0xFFFFFFFF;
	}
	/* Modify vector table location */
	__DSB();
	__ISB();
	/* set the stack pointer also to the start of the firmware */
	__set_MSP(*(int *)(SW_Slot_A_Address));
	/* offset the start of the vector table (first 6 bits must be zero) */
	/* The register containing the offset, from 0x00000000, is at 0xE000ED08
	 **/
	SCB->VTOR = ((uint32_t)SW_Slot_A_Address & SCB_VTOR_TBLOFF_Msk);
	__DSB();
	__ISB();
	__enable_irq();
	
	/* handler function, that is the value that is being pointed at position
	 * FIRMWARE_RESET_ADDRESS */
	void (*runFirmware)(void) = NULL;
	runFirmware = (void (*)(void))(*(uint32_t *)SW_Slot_A_Reset_Address);
	runFirmware();

	while (1) {
	}
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I do the same here with E70, don't know what is going wrong at your side. Maybe my code is working at your side too.


/**
 * \brief Function to start the application.
 */
static void start_application(uint32_t APP_START_ADDRESS)
{
	uint32_t app_start_address;

	/* Rebase the Stack Pointer */
	__set_MSP(*(uint32_t *) APP_START_ADDRESS);

	/* Rebase the vector table base address */
	SCB->VTOR = ((uint32_t) APP_START_ADDRESS & SCB_VTOR_TBLOFF_Msk);

	/* Load the Reset Handler address of the application */
	app_start_address = *(uint32_t *)(APP_START_ADDRESS + 4);

	/* Jump to application Reset Handler in the application */
	asm("bx %0"::"r"(app_start_address));
}
/**
 * Perform initialization and tests on flash.
 */
int main(void)
{
	sUserSignature_t sUserSignature;

	/* Initialize the SAM system */
	sysclk_init();
	board_init();

	/* Initialize the console uart */
	configure_console();

	/* Output example information */
	puts(STRING_HEADER);



	// read Signature area from flash into local buffer
	if( SignatureRead(&sUserSignature) )
		goto error;
#if 1
	if( sUserSignature.sExtFlashApplication.ulCheckSum != sUserSignature.sIntFlashApplication.ulCheckSum ) 
#endif
	{
		// firmware in external flash has been updated
		printf("Application firmware in external flash has been updated (ext chksum 0x%lx, int 0x%lx)\n", 
			sUserSignature.sExtFlashApplication.ulCheckSum, sUserSignature.sIntFlashApplication.ulCheckSum);
		
		// copy update from external to internal flash
		uint32_t ulPageCnt = sUserSignature.sExtFlashApplication.ulFileSize/IF_PAGE_SIZE;
		if( sUserSignature.sExtFlashApplication.ulFileSize%IF_PAGE_SIZE ){
			ulPageCnt++;
		}
		
//		uint8_t errorcode = ExtToIntFlashCopy(IF_MAINAPP_START_ADR, EF_MAINAPP_START_ADR, IF_MAINAPP_PAGES);
		uint8_t errorcode = ExtToIntFlashCopy(IF_MAINAPP_START_ADR, EF_MAINAPP_START_ADR, ulPageCnt);
		if(errorcode)
			blinkerror(errorcode);

		// write application update info in order to skip code copy on next reboot   
		sUserSignature.sIntFlashApplication = sUserSignature.sExtFlashApplication;

		// update signature area in flash
		if( SignatureWrite(&sUserSignature) )
			goto error;
}

	/* Switch on the LED */
	ioport_set_pin_level(LED0_GPIO, LED0_ACTIVE_LEVEL);

	printf("Start application in internal flash at adr 0x%lx...\n", *(uint32_t *)(IF_MAINAPP_START_ADR + 4));

	fflush(stdout);
	// start_application_with_reset();

	/* Disable the global interrupts */
	cpu_irq_disable();

	start_application(IF_MAINAPP_START_ADR);

error:
	printf("\nIt doesn't seem to have worked.\n");
	fflush(stdout);

	while (1);		/* Busy-wait forever */

}

 

SAME newbie

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I'm working on similar stuff and have partitioned my memory like this - 

bootloader is at: rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00010000

application is at: rom (rx) : ORIGIN = 0x00410000, LENGTH = 0x00040000
 

I'm using flash_read and flash_write functions from eefc to write to ROM locations and it doesn't allow me to do it.

Am I supposed to use different functions to read and write from rom than flash_read/flash_write?

NXA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using this (pseudo) code:

/* Initialize flash: 6 wait states for flash writing. */
ul_rc = flash_init(FLASH_ACCESS_MODE_128, 6);

/* Unlock pages */
ul_rc = flash_unlock(ulIfAdr, ulIfEndAdr, 0, 0);

/* erase affected sectors in internal flash */
for(uint32_t sector = 0; sector < ulSecCnt; sector++)
{
	/* Erase sector */
	ul_rc = flash_erase_sector(ulIfAdr);
}

/* copy application from SPI flash to internal flash */
for(uint32_t pagecnt = 0; pagecnt < ulIfPageCnt; pagecnt++)
{
	// Read x bytes of page size of internal Flash from SPI flash
	at25dfx_read(data_buff, IF_PAGE_SIZE, ulEfAdr);

	/* Write page */
	ul_rc = flash_write(ulIfAdr, data_buff,	IFLASH_PAGE_SIZE, 0);
}

 

SAME newbie

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Hangaround,

are you using different drivers than efc?

My flash_init function prototype is this - 

int32_t flash_init(struct flash_descriptor *flash, void *const hw)

also, I cannot see flash_erase_sector function anywhere.

NXA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I write to the embedded flash on the SAM4E, I use the "Flash - SAM Flash Service API (service)" and not "EEFC - Enhanced Embedded Flash Controller (driver)".  That may make a difference.

 

This "service" includes flash_efc.c which has functions relating to flash, you can take a look here: http://asf.atmel.com/docs/3.28.1...

 

If there's no example of how to write to flash for the SAMS70, or whichever board you use (I would assume there is), there is an example for the SAM4E Xplained Pro.  The example can be modified to write whatever you need to the board, such as an application image.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I adapted flash_efc.c to my requirements. I think it came with the ASF example FLASH_PROGRAM_EXAMPLE for the SAM4E16E evaluation board.

BTW Just found that there is a demo for E70 included in the ASF now which I didn't noticed.
 

SAME newbie

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

still couldn't figure out with the flash_efc drivers. It seems it can just read and write 512 bytes from 0x00000000 and 0x00003200 locations. If I try to read or write anything on 0x00410000, it fails. I get return value as - 13 which means INVALID_ARGS. When I debug ASF, it fails to consider 0x00410000 as valid address.

NXA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi regjoe and nrichard,

you guys are talking about ASF4 or ASF? I didn't see any flash programming example for ASF4. I am using ASF4 for my project.

NXA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, that might explain a few things.  The driver files I'm talking about are from ASF3.  I don't know what's available with ASF4.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ASF3.x Never tried ASF4.

SAME newbie

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

posting this msg so that people who are working with ASF4 should not face the same issue I did. I contacted Microchip directly and they got back to me with this msg - 

"Code generated using Atmel START issues command to Embedded Flash Controller (EEFC). In this case, the code sends EWP (Erase Write Program) command to EEFC.
Apparently, EWP is issued for non-8KByte sectors in SAM4 series. EWPis not applicable for SAM S70/E70/V70/V71 , instead Write (WP) command should be used..

We have modifed and tested the code to work.
Follow the instructions and make changes in your code :
-> Goto hpl_efc.c
->In that file goto _efc_write_page
->In that function replace the following part of code

hri_efc_write_EEFC_FCR_reg(hw, EEFC_FCR_FCMD_EWP | EEFC_FCR_FARG(page) | EEFC_FCR_FKEY_PASSWD);

with:
hri_efc_write_EEFC_FCR_reg(hw, EEFC_FCR_FCMD_WP | EEFC_FCR_FARG(page) | EEFC_FCR_FKEY_PASSWD);

We have informed this issue to our tools team and waiting for response."

NXA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good to hear that you found the problem and interesting to know that ASF4 is not better than ASF3.x although the version number is higher.

 

Excerpt from ASF 3.34.1 flash_program_example1 for E70:

 

 


#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAMG || SAM4CM || \
	 SAMV71 || SAMV70 || SAMS70 || SAME70)
	/* The EWP command is not supported for non-8KByte sectors in all devices
	 *  SAM4 series, so an erase command is requried before the write operation.
	 */
	ul_rc = flash_erase_sector(ul_test_page_addr);
	if (ul_rc != FLASH_RC_OK) {
		printf("-F- Flash programming error %lu\n\r", (UL)ul_rc);
		return 0;
	}

	ul_rc = flash_write(ul_test_page_addr, ul_page_buffer,
			IFLASH_PAGE_SIZE, 0);
#else
	ul_rc = flash_write(ul_test_page_addr, ul_page_buffer,
			IFLASH_PAGE_SIZE, 1);
#endif

 

SAME newbie