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;
}