How to jump to my Application from my bootloader

Discussion around product based on ARM Cortex M4 core.

Moderators: nferre, ncollot

gabrielcuellar
Posts: 12
Joined: Tue Apr 28, 2015 4:55 pm

How to jump to my Application from my bootloader

Mon Apr 11, 2016 7:27 pm

Hi, I am built my bootloader but I have a problem and I can jump to the address of my App.
The idea of this bootloader is only write in the ROM a code store in some vars, that is equal to the content of a file .bin of a project simple blinky and then run this code.
The write is work perfectly, but the jump I can`t perform.

Code: Select all

#include <asf.h>


/// Cortex-M3 Code region start
#define CM4_CODE_START      0x00400000
/// Cortex-M3 Code region end
#define CM4_CODE_END        0x1FFFFFFF
/// Cortex-M3 SRAM region end
#define CM4_SRAM_START      0x20000000
/// Cortex-M3 SRAM region end
#define CM4_SRAM_END        0x20400000
/**
 * Jump to CM3 vector table
 */
#if defined   ( __CC_ARM   ) /* Keil µVision 4 */
__asm__ void _binExec (void * l_code_addr)
{
    mov   r1, r0
    ldr   r0, [r1, #4]
    ldr   sp, [r1]
    /*msr   msp, [r1]*/
    blx   r0
}
#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
void _binExec (void * l_code_addr)
{
      __asm ("mov     r1, r0        \n"
             "ldr     r0, [r1, #4]  \n"
             "ldr     sp, [r1]      \n"
             /*"msr     msp, [r1]     \n"*/
             "blx     r0"
      );
}
#elif defined (  __GNUC__  ) /* GCC CS3 2009q3-68 */
void _binExec (void * l_code_addr)
{
    __asm__ ("mov   r1, r0        \n"
             "ldr   r0, [r1, #4]  \n"
             "ldr   sp, [r1]      \n"
             "blx   r0"
             );
}
#else /* General C, no stack reset */
void _binExec (void * l_code_addr)
{
    void (*pFct)(void) = NULL;
    // Point on __main address located in the second word in vector table
    pFct = (void (*)(void))(*(uint32_t *)((uint32_t)l_code_addr + 4));
    pFct();
}
#endif

int binary_exec(void * vStart)
{
	int i;

	// -- Check parameters
	// Should be at least 32 words aligned
	if ((uint32_t)vStart & 0x7F)
	return 1;
	// Should in code or sram region
	if ((uint32_t)vStart > CM4_SRAM_END)
	return 2;

	// -- Disable interrupts
	// Disable IRQ
	__disable_irq();
	// Disable IRQs
	for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF;
	// Clear pending IRQs
	for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF;

	// -- Modify vector table location
	// Barriars
	__DSB();
	__ISB();
	/* set the stack pointer also to the start of the firmware */
	__set_MSP(*(int *)(vStart));
	// Change the vector table
	SCB->VTOR = ((uint32_t)vStart & SCB_VTOR_TBLOFF_Msk);
	// Barriars
	__DSB();
	__ISB();

	// -- Enable interrupts
	__enable_irq();

	// -- Load Stack & PC
	//_binExec(vStart);

	return 0;
}


uint32_t Firmware_Blinky[128]={
	0x20003460,0x00400435,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00400431,
	0x00400431,0x00000000,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x00400431,0x00400431,
	0x00400431,0x00400431,0x4c05b510,0xb9337823,
	0xb1134b04,0xf3af4804,0x23018000,0xbd107023,
	0x20000440,0x00000000,0x0040083c,0x4b06b508,
	0x4806b11b,0xf3af4906,0x48068000,0xb1136803,
	0xb1034b05,0xbd084798,0x00000000,0x0040083c,
	0x20000444,0x0040083c,0x00000000,0x480eb510,
	0x47984b0e,0x213e2000,0x47984b0d,0x47a04c0d,
	0xd0fc2800,0x47984b0c,0x4b0d4a0c,0x4c0d629a,
	0x280047a0,0x2010d0fc,0x47984b0b,0x47984b0b,
	0x4b02480b,0xbd104798,0x07270e00,0x00400619,
	0x00400355,0x004003a9,0x004003b9,0x200f3f01,
	0x400e0400,0x004003c9,0x004002f1,0x00400509,
	0x05b8d800,0xf44fb510,0x4b494200,0x2009605a,
	0x47a04c48,0x47a0200a,0x47a0200b,0x47a0200c,
	0x47a0200d,0x22014b44,0xf8c3611a,0x631a20a0,
	0xf44f4942,0x610a1280,0x20a0f8c1,0xf44f630a,
	0x61081000,0x00a0f8c1,0xf44f6308,0x61592100
};
uint32_t Firmware_Blinky_2[128]={
	0x10a0f8c3,0xf8c36659,0x65591090,0xf8c36219,
	0x6f181084,0x2000f420,0x6f586718,0x2000f420,
	0xf8c36758,0xf8c310c0,0xf8c310d4,0x615a10b0,
	0x20a0f8c3,0xf8c3665a,0x655a2090,0xf8c3621a,
	0x6f192084,0x1180f421,0x6f596719,0x1180f421,
	0xf8c36759,0xf8c320c0,0xf8c320d0,0x220220b0,
	0xf8c3615a,0x665a20a0,0x2090f8c3,0x621a655a,
	0x2084f8c3,0xf0216f19,0x67190102,0xf0216f59,
	0x67590102,0x20b4f8c3,0x615a2204,0x20a0f8c3,
	0xf8c3665a,0x655a2090,0xf8c3621a,0x6f192084,
	0x0104f021,0x6f596719,0x0104f021,0xf8c36759,
	0xf8c320c0,0xf8c320d4,0xf44f20b0,0x661a62c0,
	0x2090f8c3,0x625a655a,0x2080f8c3,0xf4216f19,
	0x671961c0,0xf4216f59,0x675961c0,0xbd10605a,
	0x400e1850,0x004003d9,0x400e0e00,0x400e1400,
	0x6b1a4b17,0x0270f022,0x63184310,0xf0136e9b,
	0xd1090f08,0x6300f44f,0xe0014911,0xd0193b01,
	0xf0126e8a,0xd0f90f08,0x6b1a4b0d,0x0203f022,
	0x0202f042,0x6e98631a,0x0008f010,0xf44fd10c,
	0x49076300,0x3b01e001,0x6e8ad008,0x0f08f012,
	0x4770d0f9,0x47702001,0x47702000,0x47702001,
	0x400e0400,0x4911b138,0x4a116a0b,0x4b11401a,
	0x620b4313,0x4a0d4770,0xf4236a13,0xf023135c,
	0xf4430303,0xf043135c,0x02090301,0x430bb289,
	0x6e936213,0x0f01f013,0x4a04d0fb,0xf0436a13,
	0xf443739b,0x62133380,0xbf004770,0x400e0400,
	0xfec8fffc,0x01370002,0x6e984b02,0x3080f400,
	0xbf004770,0x400e0400,0x5200f04f,0x629a4b01,
	0xbf004770,0x400e0400,0x6e984b02,0x0002f000,
	0xbf004770,0x400e0400,0xd820282f,0xd80d281f,
	0x699a4b12,0x40832301,0x4293401a,0x2301d019,
	0xf000fa03,0x61184b0d,0x47702000,0xf8d34b0b
};
uint32_t Firmware_Blinky_3[128]={	
	0x38202108,0x40832301,0x4293401a,0x2301d00b,
	0xf000fa03,0xf8c34b05,0x20000100,0x20014770,
	0x20004770,0x20004770,0xbf004770,0x400e0400,
	0xbf00e7fe,0x4b25b510,0x429a4a25,0x4b25d003,
	0x429a4a22,0x4b24d304,0x429a4a24,0xe01ad30f,
	0x4c244b23,0xf0241ae4,0x34040403,0x481b2300,
	0x585a491b,0x3304501a,0xd1fa42a3,0x4b1ee7eb,
	0x1ac9491e,0x0103f021,0x44111d1a,0xf8432200,
	0x428b2f04,0x4b1ad1fb,0xf0224a1a,0x609a027f,
	0x8210f3ef,0xf3bfb672,0x21008f5f,0x70194b16,
	0x68194b16,0x0170f441,0xf3bf6019,0xf3bf8f4f,
	0xb92a8f6f,0x4b102201,0xf3bf701a,0xb6628f5f,
	0x47984b0f,0x47984b0f,0xbf00e7fe,0x20000000,
	0x0040083c,0x20000440,0x2000045c,0x20000440,
	0x20000004,0x20000443,0x2000043c,0x20000457,
	0xe000ed00,0x00400000,0x2000000c,0xe000ed88,
	0x004006c9,0x0040068d,0x6b1b4b3c,0x0303f003,
	0xd00f2b01,0x2b02b113,0xe057d029,0x695b4b38,
	0x0f80f013,0xf44fbf14,0xf44f4200,0x4b3542fa,
	0xe04b601a,0x6a1b4b31,0x7f80f013,0x4a32d003,
	0x601a4b30,0x4a31e042,0x601a4b2e,0x6a1b4b2b,
	0x0370f003,0xd0022b10,0xd0042b20,0x4a2ce036,
	0x601a4b28,0x4a28e032,0x601a4b26,0x4b23e02e,
	0xf0136a1b,0xd0037f80,0x4b224a23,0xe012601a,
	0x4b204a22,0x4b1d601a,0xf0036a1b,0x2b100370,
	0x2b20d002,0xe006d004,0x4b1a4a1d,0xe002601a,
	0x4b184a19,0x4b15601a,0xf0036b1b,0x2b020303,
	0x4b12d10c,0x6a996a98,0xf3c04b12,0x681a400a,
	0x2202fb00,0xfbb2b2c9,0x601af2f1,0x6b1b4b0b,
	0x0370f003,0xd1072b70,0x681a4b0a,0xfba1490d,
	0x08520202,0x4770601a,0x6b194b04,0xf3c14b05,
	0x681a1102,0x601a40ca,0xbf004770,0x400e0400
};
uint32_t Firmware_Blinky_4[128]={
	0x400e1810,0x20000010,0x00b71b00,0x003d0900,
	0x007a1200,0xaaaaaaab,0x42984b12,0xf04fd804,
	0x4b116280,0x4770601a,0x42984b10,0x4a10d803,
	0x601a4b0d,0x4b0f4770,0xd8034298,0x4b0a4a0e,
	0x4770601a,0x42984b0d,0x4a0dd803,0x601a4b06,
	0x4b0c4770,0xbf944298,0x2204f04f,0x4b024a0a,
	0x4770601a,0x01312cff,0x400e0a00,0x026259ff,
	0x04000100,0x039386ff,0x04000200,0x04c4b3ff,
	0x04000300,0x05f5e0ff,0x04000500,0x4b09b508,
	0x4b094798,0x4c094798,0x4d0a4e09,0xf4136be3,
	0xf44f1f00,0xbf141300,0x63236363,0x47a84630,
	0xbf00e7f4,0x0040014d,0x004001b5,0x400e1400,
	0x0029da4a,0x20000001,0x4e0fb570,0x1b764d0f,
	0xd00710b6,0x24003d04,0xf8553401,0x47983f04,
	0xd1f942a6,0x4d0b4e0a,0xf0001b76,0x10b6f895,
	0x3d04d008,0x34012400,0x3f04f855,0x42a64798,
	0xbd70d1f9,0xbf00bd70,0x00400824,0x00400824,
	0x0040082c,0x00400824,0xb1134b02,0xf0004802,
	0x4770b805,0x00000000,0x00400739,0x20004601,
	0x46034602,0xb818f000,0x4d09b538,0x1b644c09,
	0xbf1810a4,0x0584eb05,0x3c01d005,0x3d04f855,
	0x2c004798,0xe8bdd1f9,0xf0004038,0xbf00b867,
	0x00400838,0x0040083c,0x4c27b5f0,0xf8d66826,
	0xb0854148,0x2c004607,0x6865d041,0xdd1e2d1f,
	0xb9184822,0x30fff04f,0xbdf0b005,0x70c8f44f,
	0x92029103,0xf3af9301,0x99038000,0x9b019a02,
	0x28004604,0xf8d6d0ee,0x60255148,0x60602000,
	0xf8c64605,0xf8c44148,0xf8c40188,0xb93f018c,
	0x20001cab,0x60653501,0x1023f844,0xbdf0b005,
	0x0085eb04,0x0c01f04f,0x2088f8c0,0x6188f8d4,
	0xf205fa0c,0x2f024316,0x6188f8c4,0x3108f8c0,
	0xf8d4d1e6,0x431a318c,0x218cf8c4,0xf506e7e0
};
uint32_t Firmware_Blinky_5[128]={
	0xf8c674a6,0xe7b84148,0x00400814,0x00000000,
	0x00000043,0x20000018,0xbf00b5f8,0xbc08bcf8,
	0x4770469e,0x00400719,0x0040011d,0xbf00b5f8,
	0xbc08bcf8,0x4770469e,0x004000f9,0x8f5ff3bf,
	0xd1fb3801,0xbf004770,0x00000001,0x003d0900,
	0x00000000,0x00000000,0x20000304,0x2000036c,
	0x200003d4,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00400810,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000001,
	0x00000000,0xabcd330e,0xe66d1234,0x0005deec,
	0x0000000b,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000,
	0x00000000,0x00000000,0x00000000,0x00000000
};
int main (void)
{
	//sysclk_init();
	//board_init();
	uint32_t ul_test_page_addr = (IFLASH_ADDR + IFLASH_SIZE - IFLASH_PAGE_SIZE * 5);
	uint32_t *pul_test_page = (uint32_t *) ul_test_page_addr;
	uint32_t ul_rc;
	uint32_t ul_idx;
	
	uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
	
	
	
	
	flash_init(FLASH_ACCESS_MODE_128, 6);
	
	
	/** Informacion de la Flash */	
	uint32_t ul_flash_descriptor[8];
	volatile uint32_t ul_page_count;
	volatile uint32_t ul_page_count_per_region;
	volatile uint32_t ul_region_count;

	/* Get the flash descriptor */
	flash_get_descriptor(IFLASH_ADDR, ul_flash_descriptor, 8);//IROM_ADDR

	ul_page_count = flash_get_page_count(ul_flash_descriptor);

	/* Validate the get page count function */
	//test_assert_true(test, ul_page_count == DEFAULT_PAGE_COUNT,
	//		"Test flash information:get page count error!");

	/* Read the page count number in one region */
	ul_page_count_per_region =
			flash_get_page_count_per_region(ul_flash_descriptor);

	/* Validate the get page count per region function */
	//test_assert_true(test, (ul_page_count_per_region == IFLASH_NB_OF_PAGES),
	//		"Test flash information:get page count per region error!");

	/* Get the region number */
	ul_region_count = flash_get_region_count(ul_flash_descriptor);

	/* Validate the get region count function */
	//test_assert_true(test, (ul_region_count == DEFAULT_REGION_COUNT),
	//		"Test flash information:get region count error!");
	/** Fin Informacion Flash*/
			
	
	flash_unlock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	flash_erase_sector(ul_test_page_addr);
	flash_write(ul_test_page_addr, Firmware_Blinky,IFLASH_PAGE_SIZE, 0);
	
        ul_test_page_addr += 0x200;	
        flash_write(ul_test_page_addr, Firmware_Blinky_2,IFLASH_PAGE_SIZE, 0);

	
	ul_test_page_addr += 0x200;	
	flash_write(ul_test_page_addr, Firmware_Blinky_3,IFLASH_PAGE_SIZE, 0);
	
	ul_test_page_addr += 0x200;	
	flash_write(ul_test_page_addr, Firmware_Blinky_4,IFLASH_PAGE_SIZE, 0);
	
	ul_test_page_addr += 0x200;
        flash_write(ul_test_page_addr, Firmware_Blinky_5,IFLASH_PAGE_SIZE, 0);
	
	
	/** Comparar lo escrito*/
	flash_lock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);

	/* Protege contra la lectura el micro
	flash_enable_security_bit();*/
	binary_exec(pul_test_page);
	

        /*Here perform the jump but that never happen*/
        /*I need jump to the address   pul_test_page  */
	void (*runFirmware)(void) = NULL;
	runFirmware = (void (*)(void))(*(uint32_t *)pul_test_page);
	runFirmware();
	return 0;
}
Please some advice?
gabrielcuellar
Posts: 12
Joined: Tue Apr 28, 2015 4:55 pm

Re: How to jump to my Application from my bootloader

Tue Apr 12, 2016 7:31 pm

I been reading, about the instruction set ASM and I just can find about the STACK POINTER and link register, maybe the PC when it`s running in some place match with a POP instruction, and this is apparently the problem, but I can`t resolve this.
I try download the stack with POP and load in the register Link with the address of my app, and then the same address, in the stack pointer, and then BLX address here realize the jump but in some point is PC jump to somewhere without control.
tsvoipio
Posts: 53
Joined: Wed Aug 19, 2015 9:44 pm

Re: How to jump to my Application from my bootloader

Tue Apr 12, 2016 8:48 pm

The blx instruction is OK for a transfer to client code, but a bx will also do. For the Cortex Thumb, you need to be sure that the contents of the register containing the address is odd (lowest bit = 1).

1. Which addresses is your loader using?

2. Which addresses is your blinky program using?

If you have the linker maps or ELF files of the programs, it should be easy to get the address ranges in use.

The GNU linker produces the link map with -Map=mapfile, or given to GCC -WL,-Map=mapfile.
You can list the memory sections in an ELF file with the objdump utility:
arm-none-elf-objdump -h myfilename.elf
gabrielcuellar
Posts: 12
Joined: Tue Apr 28, 2015 4:55 pm

Re: How to jump to my Application from my bootloader

Wed Apr 13, 2016 3:12 pm

Hi thanks for the replay, my app begins in the address 0x4FE200 and finish in (0x004FEC00 -1), I have this in a pointer called
pul_test_page = 0x4FE200
my function "binary_exec(void * vStart)" is in address 0x400504

to resolve this the pointer must be 0x4FE201?
tsvoipio
Posts: 53
Joined: Wed Aug 19, 2015 9:44 pm

Re: How to jump to my Application from my bootloader

Wed Apr 13, 2016 3:56 pm

gabrielcuellar wrote:Hi thanks for the replay, my app begins in the address 0x4FE200 and finish in (0x004FEC00 -1), I have this in a pointer called
pul_test_page = 0x4FE200
my function "binary_exec(void * vStart)" is in address 0x400504

to resolve this the pointer must be 0x4FE201?
1. Did you look at the link maps of a) the boot loader and b) the application?

2. No. The start address is picked from the vector at the start of your binary.
As it is in the code you showed, the code pointer is correctly odd, but far
from the address you say it should point at.

The start pointer in your firmware image is 0x00400435, which is a Thumb
vector to address 0x00400434. I suspect that you're attempting to jump
into the middle of your boot loader instead of the target code.

The ARM/Thumb code cannot moved to a different location from the place
it was located into by the linker. There are exceptions in position-independent
code, but I did not see your code as such.
gabrielcuellar
Posts: 12
Joined: Tue Apr 28, 2015 4:55 pm

Re: How to jump to my Application from my bootloader

Wed Apr 13, 2016 5:25 pm

tsvoipio wrote:
gabrielcuellar wrote:Hi thanks for the replay, my app begins in the address 0x4FE200 and finish in (0x004FEC00 -1), I have this in a pointer called
pul_test_page = 0x4FE200
my function "binary_exec(void * vStart)" is in address 0x400504

to resolve this the pointer must be 0x4FE201?
1. Did you look at the link maps of a) the boot loader and b) the application?

2. No. The start address is picked from the vector at the start of your binary.
As it is in the code you showed, the code pointer is correctly odd, but far
from the address you say it should point at.

The start pointer in your firmware image is 0x00400435, which is a Thumb
vector to address 0x00400434. I suspect that you're attempting to jump
into the middle of your boot loader instead of the target code.

The ARM/Thumb code cannot moved to a different location from the place
it was located into by the linker. There are exceptions in position-independent
code, but I did not see your code as such.
Maybe you mean this ?

bootloader.elf: file format elf32-little

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000008e4 00400000 00400000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .relocate 00000eb8 20000000 004008e4 00010000 2**3
CONTENTS, ALLOC, LOAD, CODE
2 .bss 0000021c 20000eb8 0040179c 00010eb8 2**2
ALLOC
3 .stack 00003004 200010d4 004019b8 00010eb8 2**0
ALLOC
4 .ARM.attributes 0000002e 00000000 00000000 00010eb8 2**0
CONTENTS, READONLY
5 .comment 0000005b 00000000 00000000 00010ee6 2**0
CONTENTS, READONLY
6 .debug_info 00002cdc 00000000 00000000 00010f41 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_abbrev 000009eb 00000000 00000000 00013c1d 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_loc 00001e18 00000000 00000000 00014608 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_aranges 00000200 00000000 00000000 00016420 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_ranges 000001a0 00000000 00000000 00016620 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_macro 000034aa 00000000 00000000 000167c0 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_line 00003ab4 00000000 00000000 00019c6a 2**0
CONTENTS, READONLY, DEBUGGING
13 .debug_str 0005aa12 00000000 00000000 0001d71e 2**0
CONTENTS, READONLY, DEBUGGING
14 .debug_frame 00000584 00000000 00000000 00078130 2**2
CONTENTS, READONLY, DEBUGGING

blinky.elf: file format elf32-little

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000083c 00400000 00400000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .relocate 00000440 20000000 0040083c 00010000 2**3
CONTENTS, ALLOC, LOAD, CODE
2 .bss 0000001c 20000440 00400c7c 00010440 2**2
ALLOC
3 .stack 00003004 2000045c 00400c98 00010440 2**0
ALLOC
4 .ARM.attributes 0000002e 00000000 00000000 00010440 2**0
CONTENTS, READONLY
5 .comment 0000005b 00000000 00000000 0001046e 2**0
CONTENTS, READONLY
6 .debug_info 0000451a 00000000 00000000 000104c9 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_abbrev 00000d2a 00000000 00000000 000149e3 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_aranges 00000308 00000000 00000000 0001570d 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_ranges 00000290 00000000 00000000 00015a15 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_macro 00013e4f 00000000 00000000 00015ca5 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_line 00005531 00000000 00000000 00029af4 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_str 00059fae 00000000 00000000 0002f025 2**0
CONTENTS, READONLY, DEBUGGING
13 .debug_frame 00000640 00000000 00000000 00088fd4 2**2
CONTENTS, READONLY, DEBUGGING
14 .debug_loc 00000c4d 00000000 00000000 00089614 2**0
CONTENTS, READONLY, DEBUGGING

The fact is like you say the jump is realize to in midlle of my bootloader code, and is not the intention, I want jump to the address 0x004FF200 because I wrote the bin(blinky) there. when I jump using r0=0x004ff200 and then blx r0 the PC Jump there but my app no execute. In some moment the PC return of the _binExec()
tsvoipio
Posts: 53
Joined: Wed Aug 19, 2015 9:44 pm

Re: How to jump to my Application from my bootloader

Wed Apr 13, 2016 6:49 pm

Now your situation is:

-boot: 0x00400000 - 0x0040179b
-blinky: 0x00400000 - 0x00400c7b,

so your blinky is located completely on top of the boot code. As it is now, the blinky code cannot run in any other location than starting at 0x00400000.

You have to select two different flash areas for the boot and run codes. I'm starting boot code at 0x00400000 and the run code at 0x00410000, which is comfortably out of the flash erase segment of the boot code, and there is enough space for the boot to include TCP/IP network boot code (BOOTP + TFTP).

The code location is given to the linker (ld) in the linker script. You have to use two different linker scripts for the boot and run code.
gabrielcuellar
Posts: 12
Joined: Tue Apr 28, 2015 4:55 pm

Re: How to jump to my Application from my bootloader

Wed Apr 13, 2016 9:24 pm

tsvoipio wrote:Now your situation is:

-boot: 0x00400000 - 0x0040179b
-blinky: 0x00400000 - 0x00400c7b,

so your blinky is located completely on top of the boot code. As it is now, the blinky code cannot run in any other location than starting at 0x00400000.

You have to select two different flash areas for the boot and run codes. I'm starting boot code at 0x00400000 and the run code at 0x00410000, which is comfortably out of the flash erase segment of the boot code, and there is enough space for the boot to include TCP/IP network boot code (BOOTP + TFTP).

The code location is given to the linker (ld) in the linker script. You have to use two different linker scripts for the boot and run code.
Aja!!! I got it. Thank you, now I understand how it work this.
I been wrong when I use the address test in the bootloader different to the original app, set in the linker script of the app to run.

Here is the code working for me :D


Linker script flash.id(bootloader)

Code: Select all

 rom (rx)  : ORIGIN = 0x00400000, LENGTH = 0x00010000
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
main.c bootloader

Code: Select all

/**
 * Jump to CM3 vector table
 */
#if defined   ( __CC_ARM   ) /* Keil µVision 4 */
__asm__ void _binExec (void * l_code_addr)
{
    mov   r1, r0
    ldr   r0, [r1, #4]
    ldr   sp, [r1]
    /*msr   msp, [r1]*/
    blx   r0
}
#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
void _binExec (void * l_code_addr)
{
      __asm ("mov     r1, r0        \n"
             "ldr     r0, [r1, #4]  \n"
             "ldr     sp, [r1]      \n"
             /*"msr     msp, [r1]     \n"*/
             "blx     r0"
      );
}
#elif defined (  __GNUC__  ) /* GCC CS3 2009q3-68 */
void _binExec (void * l_code_addr)
{
    __asm__ ("mov   r1, r0        \n"
             "ldr   r0, [r1, #4]  \n"
             "ldr   sp, [r1]      \n"
             "blx   r0"
             );
}
#else /* General C, no stack reset */
void _binExec (void * l_code_addr)
{
    void (*pFct)(void) = NULL;
    // Point on __main address located in the second word in vector table
    pFct = (void (*)(void))(*(uint32_t *)((uint32_t)l_code_addr + 4));
    pFct();
}
#endif

int binary_exec(void * vStart)
{
   int i;

   // -- Check parameters
   // Should be at least 32 words aligned
   if ((uint32_t)vStart & 0x7F)
   return 1;
   // Should in code or sram region
   if ((uint32_t)vStart > CM4_SRAM_END)
   return 2;

   // -- Disable interrupts
   // Disable IRQ
   __disable_irq();
   // Disable IRQs
   for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF;
   // Clear pending IRQs
   for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF;

   // -- Modify vector table location
   // Barriars
   __DSB();
   __ISB();
   /* set the stack pointer also to the start of the firmware */
   __set_MSP(*(int *)(vStart));
   // Change the vector table
   SCB->VTOR = ((uint32_t)vStart & SCB_VTOR_TBLOFF_Msk);
   // Barriars
   __DSB();
   __ISB();

   // -- Enable interrupts
   __enable_irq();

   // -- Load Stack & PC
   _binExec(vStart);

   return 0;
}



uint32_t Firmware_Blinky[128]={
	0x20003460, 0x00410435, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00410431,
	0x00410431, 0x00000000, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x00410431, 0x00410431,
	0x00410431, 0x00410431, 0x4c05b510, 0xb9337823,
	0xb1134b04, 0xf3af4804, 0x23018000, 0xbd107023,
	0x20000440, 0x00000000, 0x0041083c, 0x4b06b508,
	0x4806b11b, 0xf3af4906, 0x48068000, 0xb1136803,
	0xb1034b05, 0xbd084798, 0x00000000, 0x0041083c,
	0x20000444, 0x0041083c, 0x00000000, 0x480eb510,
	0x47984b0e, 0x213e2000, 0x47984b0d, 0x47a04c0d,
	0xd0fc2800, 0x47984b0c, 0x4b0d4a0c, 0x4c0d629a,
	0x280047a0, 0x2010d0fc, 0x47984b0b, 0x47984b0b,
	0x4b02480b, 0xbd104798, 0x07270e00, 0x00410619,
	0x00410355, 0x004103a9, 0x004103b9, 0x200f3f01,
	0x400e0400, 0x004103c9, 0x004102f1, 0x00410509,
	0x05b8d800, 0xf44fb510, 0x4b494200, 0x2009605a,
	0x47a04c48, 0x47a0200a, 0x47a0200b, 0x47a0200c,
	0x47a0200d, 0x22014b44, 0xf8c3611a, 0x631a20a0,
	0xf44f4942, 0x610a1280, 0x20a0f8c1, 0xf44f630a,
	0x61081000, 0x00a0f8c1, 0xf44f6308, 0x61592100
};
uint32_t Firmware_Blinky_2[128]={
	0x10a0f8c3, 0xf8c36659, 0x65591090, 0xf8c36219,
	0x6f181084, 0x2000f420, 0x6f586718, 0x2000f420,
	0xf8c36758, 0xf8c310c0, 0xf8c310d4, 0x615a10b0,
	0x20a0f8c3, 0xf8c3665a, 0x655a2090, 0xf8c3621a,
	0x6f192084, 0x1180f421, 0x6f596719, 0x1180f421,
	0xf8c36759, 0xf8c320c0, 0xf8c320d0, 0x220220b0,
	0xf8c3615a, 0x665a20a0, 0x2090f8c3, 0x621a655a,
	0x2084f8c3, 0xf0216f19, 0x67190102, 0xf0216f59,
	0x67590102, 0x20b4f8c3, 0x615a2204, 0x20a0f8c3,
	0xf8c3665a, 0x655a2090, 0xf8c3621a, 0x6f192084,
	0x0104f021, 0x6f596719, 0x0104f021, 0xf8c36759,
	0xf8c320c0, 0xf8c320d4, 0xf44f20b0, 0x661a62c0,
	0x2090f8c3, 0x625a655a, 0x2080f8c3, 0xf4216f19,
	0x671961c0, 0xf4216f59, 0x675961c0, 0xbd10605a,
	0x400e1850, 0x004103d9, 0x400e0e00, 0x400e1400,
	0x6b1a4b17, 0x0270f022, 0x63184310, 0xf0136e9b,
	0xd1090f08, 0x6300f44f, 0xe0014911, 0xd0193b01,
	0xf0126e8a, 0xd0f90f08, 0x6b1a4b0d, 0x0203f022,
	0x0202f042, 0x6e98631a, 0x0008f010, 0xf44fd10c,
	0x49076300, 0x3b01e001, 0x6e8ad008, 0x0f08f012,
	0x4770d0f9, 0x47702001, 0x47702000, 0x47702001,
	0x400e0400, 0x4911b138, 0x4a116a0b, 0x4b11401a,
	0x620b4313, 0x4a0d4770, 0xf4236a13, 0xf023135c,
	0xf4430303, 0xf043135c, 0x02090301, 0x430bb289,
	0x6e936213, 0x0f01f013, 0x4a04d0fb, 0xf0436a13,
	0xf443739b, 0x62133380, 0xbf004770, 0x400e0400,
	0xfec8fffc, 0x01370002, 0x6e984b02, 0x3080f400,
	0xbf004770, 0x400e0400, 0x5200f04f, 0x629a4b01,
	0xbf004770, 0x400e0400, 0x6e984b02, 0x0002f000,
	0xbf004770, 0x400e0400, 0xd820282f, 0xd80d281f,
	0x699a4b12, 0x40832301, 0x4293401a, 0x2301d019,
	0xf000fa03, 0x61184b0d, 0x47702000, 0xf8d34b0b

};
uint32_t Firmware_Blinky_3[128]={	
	0x38202108, 0x40832301, 0x4293401a, 0x2301d00b,
	0xf000fa03, 0xf8c34b05, 0x20000100, 0x20014770,
	0x20004770, 0x20004770, 0xbf004770, 0x400e0400,
	0xbf00e7fe, 0x4b25b510, 0x429a4a25, 0x4b25d003,
	0x429a4a22, 0x4b24d304, 0x429a4a24, 0xe01ad30f,
	0x4c244b23, 0xf0241ae4, 0x34040403, 0x481b2300,
	0x585a491b, 0x3304501a, 0xd1fa42a3, 0x4b1ee7eb,
	0x1ac9491e, 0x0103f021, 0x44111d1a, 0xf8432200,
	0x428b2f04, 0x4b1ad1fb, 0xf0224a1a, 0x609a027f,
	0x8210f3ef, 0xf3bfb672, 0x21008f5f, 0x70194b16,
	0x68194b16, 0x0170f441, 0xf3bf6019, 0xf3bf8f4f,
	0xb92a8f6f, 0x4b102201, 0xf3bf701a, 0xb6628f5f,
	0x47984b0f, 0x47984b0f, 0xbf00e7fe, 0x20000000,
	0x0041083c, 0x20000440, 0x2000045c, 0x20000440,
	0x20000004, 0x20000443, 0x2000043c, 0x20000457,
	0xe000ed00, 0x00410000, 0x2000000c, 0xe000ed88,
	0x004106c9, 0x0041068d, 0x6b1b4b3c, 0x0303f003,
	0xd00f2b01, 0x2b02b113, 0xe057d029, 0x695b4b38,
	0x0f80f013, 0xf44fbf14, 0xf44f4200, 0x4b3542fa,
	0xe04b601a, 0x6a1b4b31, 0x7f80f013, 0x4a32d003,
	0x601a4b30, 0x4a31e042, 0x601a4b2e, 0x6a1b4b2b,
	0x0370f003, 0xd0022b10, 0xd0042b20, 0x4a2ce036,
	0x601a4b28, 0x4a28e032, 0x601a4b26, 0x4b23e02e,
	0xf0136a1b, 0xd0037f80, 0x4b224a23, 0xe012601a,
	0x4b204a22, 0x4b1d601a, 0xf0036a1b, 0x2b100370,
	0x2b20d002, 0xe006d004, 0x4b1a4a1d, 0xe002601a,
	0x4b184a19, 0x4b15601a, 0xf0036b1b, 0x2b020303,
	0x4b12d10c, 0x6a996a98, 0xf3c04b12, 0x681a400a,
	0x2202fb00, 0xfbb2b2c9, 0x601af2f1, 0x6b1b4b0b,
	0x0370f003, 0xd1072b70, 0x681a4b0a, 0xfba1490d,
	0x08520202, 0x4770601a, 0x6b194b04, 0xf3c14b05,
	0x681a1102, 0x601a40ca, 0xbf004770, 0x400e0400
};
uint32_t Firmware_Blinky_4[128]={
	0x400e1810, 0x20000010, 0x00b71b00, 0x003d0900,
	0x007a1200, 0xaaaaaaab, 0x42984b12, 0xf04fd804,
	0x4b116280, 0x4770601a, 0x42984b10, 0x4a10d803,
	0x601a4b0d, 0x4b0f4770, 0xd8034298, 0x4b0a4a0e,
	0x4770601a, 0x42984b0d, 0x4a0dd803, 0x601a4b06,
	0x4b0c4770, 0xbf944298, 0x2204f04f, 0x4b024a0a,
	0x4770601a, 0x01312cff, 0x400e0a00, 0x026259ff,
	0x04000100, 0x039386ff, 0x04000200, 0x04c4b3ff,
	0x04000300, 0x05f5e0ff, 0x04000500, 0x4b09b508,
	0x4b094798, 0x4c094798, 0x4d0a4e09, 0xf4136be3,
	0xf44f1f00, 0xbf141300, 0x63236363, 0x47a84630,
	0xbf00e7f4, 0x0041014d, 0x004101b5, 0x400e1400,
	0x0029da4a, 0x20000001, 0x4e0fb570, 0x1b764d0f,
	0xd00710b6, 0x24003d04, 0xf8553401, 0x47983f04,
	0xd1f942a6, 0x4d0b4e0a, 0xf0001b76, 0x10b6f895,
	0x3d04d008, 0x34012400, 0x3f04f855, 0x42a64798,
	0xbd70d1f9, 0xbf00bd70, 0x00410824, 0x00410824,
	0x0041082c, 0x00410824, 0xb1134b02, 0xf0004802,
	0x4770b805, 0x00000000, 0x00410739, 0x20004601,
	0x46034602, 0xb818f000, 0x4d09b538, 0x1b644c09,
	0xbf1810a4, 0x0584eb05, 0x3c01d005, 0x3d04f855,
	0x2c004798, 0xe8bdd1f9, 0xf0004038, 0xbf00b867,
	0x00410838, 0x0041083c, 0x4c27b5f0, 0xf8d66826,
	0xb0854148, 0x2c004607, 0x6865d041, 0xdd1e2d1f,
	0xb9184822, 0x30fff04f, 0xbdf0b005, 0x70c8f44f,
	0x92029103, 0xf3af9301, 0x99038000, 0x9b019a02,
	0x28004604, 0xf8d6d0ee, 0x60255148, 0x60602000,
	0xf8c64605, 0xf8c44148, 0xf8c40188, 0xb93f018c,
	0x20001cab, 0x60653501, 0x1023f844, 0xbdf0b005,
	0x0085eb04, 0x0c01f04f, 0x2088f8c0, 0x6188f8d4,
	0xf205fa0c, 0x2f024316, 0x6188f8c4, 0x3108f8c0,
	0xf8d4d1e6, 0x431a318c, 0x218cf8c4, 0xf506e7e0
};
uint32_t Firmware_Blinky_5[128]={
	0xf8c674a6, 0xe7b84148, 0x00410814, 0x00000000,
	0x00000043, 0x20000018, 0xbf00b5f8, 0xbc08bcf8,
	0x4770469e, 0x00410719, 0x0041011d, 0xbf00b5f8,
	0xbc08bcf8, 0x4770469e, 0x004100f9, 0x8f5ff3bf,
	0xd1fb3801, 0xbf004770, 0x00000001, 0x003d0900,
	0x00000000, 0x00000000, 0x20000304, 0x2000036c,
	0x200003d4, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00410810, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000001,
	0x00000000, 0xabcd330e, 0xe66d1234, 0x0005deec,
	0x0000000b, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000,
	0x00000000, 0x00000000, 0x00000000, 0x00000000
};
//uint32_t Firmware_Blinky_6[128]={};

int main (void)
{
	//sysclk_init();
	//board_init();
	uint32_t ul_test_page_addr = 0x00410000;//This is the address where the app to run was compiled and set in the linker script
	uint32_t *pul_test_page = (uint32_t *) ul_test_page_addr;
	uint32_t ul_rc;
	uint32_t ul_idx;
	
	uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
	
	
	
	NVIC_SetPriorityGrouping(__NVIC_PRIO_BITS);
	__set_BASEPRI(0);
	
	
	flash_init(FLASH_ACCESS_MODE_128, 6);
	
	
	/** Informacion de la Flash */	
	uint32_t ul_flash_descriptor[8];
	volatile uint32_t ul_page_count;
	volatile uint32_t ul_page_count_per_region;
	volatile uint32_t ul_region_count;

	/* Get the flash descriptor */
	flash_get_descriptor(IFLASH_ADDR, ul_flash_descriptor, 8);//IROM_ADDR

	ul_page_count = flash_get_page_count(ul_flash_descriptor);

	/* Validate the get page count function */
	//test_assert_true(test, ul_page_count == DEFAULT_PAGE_COUNT,
	//		"Test flash information:get page count error!");

	/* Read the page count number in one region */
	ul_page_count_per_region =
			flash_get_page_count_per_region(ul_flash_descriptor);

	/* Validate the get page count per region function */
	//test_assert_true(test, (ul_page_count_per_region == IFLASH_NB_OF_PAGES),
	//		"Test flash information:get page count per region error!");

	/* Get the region number */
	ul_region_count = flash_get_region_count(ul_flash_descriptor);

	/* Validate the get region count function */
	//test_assert_true(test, (ul_region_count == DEFAULT_REGION_COUNT),
	//		"Test flash information:get region count error!");
	/** Fin Informacion Flash*/
			
	
	flash_unlock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	flash_erase_sector(ul_test_page_addr);
	flash_write(ul_test_page_addr, Firmware_Blinky,IFLASH_PAGE_SIZE, 0);
	//flash_lock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	
	
	ul_test_page_addr += 0x200;
	//flash_unlock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	//flash_erase_sector(ul_test_page_addr);
	flash_write(ul_test_page_addr, Firmware_Blinky_2,IFLASH_PAGE_SIZE, 0);
	//flash_lock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	
	ul_test_page_addr += 0x200;
	//flash_unlock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	//flash_erase_sector(ul_test_page_addr);
	flash_write(ul_test_page_addr, Firmware_Blinky_3,IFLASH_PAGE_SIZE, 0);
	
	ul_test_page_addr += 0x200;
	//flash_unlock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	//flash_erase_sector(ul_test_page_addr);
	flash_write(ul_test_page_addr, Firmware_Blinky_4,IFLASH_PAGE_SIZE, 0);
	
	ul_test_page_addr += 0x200;
	//flash_unlock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	//flash_erase_sector(ul_test_page_addr);
	flash_write(ul_test_page_addr, Firmware_Blinky_5,IFLASH_PAGE_SIZE, 0);
	
	
	/** Comparar lo escrito*/
	flash_lock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);

	/* Protege contra la lectura el micro
	flash_enable_security_bit();*/
	//while(1){}
	
	binary_exec(pul_test_page);
	
	//void (*runFirmware)(void) = NULL;
	//runFirmware = (void (*)(void))(*(uint32_t *)pul_test_page);
	//runFirmware();
	//return (int)pul_test_page;
}
linker script flash.id(app blinky)

Code: Select all

  rom (rx)  : ORIGIN = 0x00410000, LENGTH = 0x000f0000
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
main.c app blinky

Code: Select all

#include <asf.h>

int main (void)
{
	sysclk_init();
	board_init();
	
	while(1)
	{
		ioport_toggle_pin_level(LED2_GPIO);
		delay_ms(400);
	}


}

Return to “SAM4 Cortex-M4 MCU”

Who is online

Users browsing this forum: No registered users and 3 guests