LPC1113/302 Secondary Bootloader based on AN10995

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

LPC1113/302 Secondary Bootloader based on AN10995

6,893 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Wed Feb 11 15:26:50 MST 2015
Hi guys, this is my first post. It's been a while since i'm trying to troubleshoot my situation here so i thought i should ask.
I'm using a LPC1113/302, LPC-link v1.1 jtag debugger and LPCXPRESSO v7.5 .
I'm trying to use a second bootloader , based on this application note : http://www.lpcware.com/content/nxpfile/an10995-lpc1100-secondary-bootloader-software-v13
I had to make some tweaks because the the AN10995 is aimed for lpc1114, so I changed the linker scripts AND the application example.
These are the changes that I made on application_Release_mem.ld

MEMORY
{
  /* Define each memory region */
  MFlash24 (rx) : ORIGIN = 0x1000, LENGTH = 0x5000 /* 20K bytes */
  RamLoc8 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x1FE0 /* 8K bytes */


}
  /* Define a symbol for the top of each memory region */
  __top_MFlash24 = 0x1000 + 0x5000;
  __top_RamLoc8 = 0x10000000 + 0x1FE0;



The application was changed to blink a led using SysTick_Handler():

int main(void)
{

    LPC_IOCON->PIO2_9 &= ~0x1F;         // PIO2_9, NO PULLUP/PULLDOW
    LPC_GPIO2->DIR |= (0x1 << 9);       // 1 - OUTPUT


    SysTick_Config(SystemCoreClock / 100000000UL);

    while(1);
    return 0 ;
}

void SysTick_Handler(void)
{
    if (u8LedOn)
    {
        (LPC_GPIO2->MASKED_ACCESS[(1 << 9)] = ((1) << 9));    }
    else
    {
        (LPC_GPIO2->MASKED_ACCESS[(1 << 9)] = ((0) << 9));
    }
    u8LedOn = !u8LedOn;
} 


I followed AN10995 instructions, flashed the bootloader at 0x0000 (apparently works fine) and flashed the Application.bin via IAP instructions on 0x1000 (through the bootloader and XMODEM-1k). The problem happens when the execution jumps from the bootloader to the application, following this code (from bootloader main):

                /* Load main stack pointer with application stack pointer initial value,
   stored at first location of application area */
                asm volatile("ldr r0, =0x1000");
asm volatile("ldr r0, [r0]");
asm volatile("mov sp, r0");

/* Load program counter with application reset vector address, located at
   second word of application area. */
asm volatile("ldr r0, =0x1004");
asm volatile("ldr r0, [r0]");
asm volatile("mov pc, r0");


I believe 0x1004 should contain the address to a ResetISR handler, but it seems to go to a place with no valid instructions.
I checked if the .bin I sent and the content in memory were identical and it seems that the content in memory is bigger, maybe some padding, i don't know...
The application vector table looks ok but the handling don't. I'm out of ideas , hope someone can help me =)! Heres the repo i'm storing the files : https://github.com/lucastakejame/mod-bootloader
标签 (1)
0 项奖励
回复
13 回复数

6,624 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Wed Feb 18 14:57:26 MST 2015
I think I found the problem, when I transfer using XMODEM protocol on minicon, the .bin was been sent in 128 bytes packets. There is this excerpt in bootloader main:

static uint32_t u32BootLoader_ProgramFlash(uint8_t *pu8Data, uint16_t u16Len)
{
uint32_t u32Result = 0;

static uint32_t u32NextFlashWriteAddr = APP_START_ADDR;

if ((pu8Data != 0) && (u16Len != 0))
{
/* Prepare the flash application sectors for reprogramming */
if (u32IAP_PrepareSectors(APP_START_SECTOR, APP_END_SECTOR) == IAP_STA_CMD_SUCCESS)
{
/* Ensure that amount of data written to flash is at minimum the
   size of a flash page */
if (u16Len < IAP_FLASH_PAGE_SIZE_BYTES)
{
u16Len = IAP_FLASH_PAGE_SIZE_BYTES;
}

/* Write the data to flash */
if (u32IAP_CopyRAMToFlash(u32NextFlashWriteAddr, (uint32_t)pu8Data, u16Len) == IAP_STA_CMD_SUCCESS)
{
/* Check that the write was successful */
if (u32IAP_Compare(u32NextFlashWriteAddr, (uint32_t)pu8Data, u16Len, 0) == IAP_STA_CMD_SUCCESS)
{
/* Write was successful */
u32NextFlashWriteAddr += u16Len;
u32Result = 1;
}
}
}
}
return (u32Result);
}


since u16len carried 128 (packet size) and IAP_FLASH_PAGE_SIZE_BYTES is 256, 256 would be assigned to u16len, making the flashing start address jump from  256 to 256 bytes, while only 128 of them contained info.
0 项奖励
回复

6,624 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Wed Feb 18 13:35:07 MST 2015
Hi again, thanks for your responses =)! I'm flashing the bootloader to 0x0000 via LPCXPRESSO, after that I used to send Application.bin by XMODEM-1k (using minicon on linux) to test the IAP functions from the example. Now I made a test flashing the Application.bin via LPCXPRESSO and it seems to work.... apparently there are some padding areas when the IAP function burns something in the flash, i have to study the example to see what can I do...

Also, I pasted those lines before the assembly code, but coudn't tell the difference
0 项奖励
回复

6,624 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Wed Feb 18 13:35:04 MST 2015
Hi again, thanks for your responses =)! I'm flashing the bootloader to 0x0000 via LPCXPRESSO, after that I used to send Application.bin by XMODEM-1k (using minicon on linux) to test the IAP functions from the example. Now I made a test flashing the Application.bin via LPCXPRESSO and it seems to work.... apparently there are some padding areas when the IAP function burns something in the flash, i have to study the example to see what can I do...

Also, I pasted those lines before the assembly code, but coudn't tell the difference
0 项奖励
回复

6,624 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Fri Feb 13 11:02:50 MST 2015
To avoid problems with your (application) clock setup you can also switch back to IRC just before the jump:

[color=#f00]//slow jump: switch main clock to IRC
LPC_SYSCON->MAINCLKSEL  = 0;
LPC_SYSCON->MAINCLKUEN  = 0;
LPC_SYSCON->MAINCLKUEN  = 1;

[/color]/* Valid application located in the next sector(s) of flash so execute */

/* Load main stack pointer with application stack pointer initial value, stored at first location of application area */
asm volatile("ldr r0, =0x1000");
asm volatile("ldr r0, [r0]");
asm volatile("mov sp, r0");

/* Load program counter with application reset vector address, located at second word of application area. */
asm volatile("ldr r0, =0x1004");
asm volatile("ldr r0, [r0]");
asm volatile("mov pc, r0");
0 项奖励
回复

6,624 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Feb 12 14:09:21 MST 2015

Quote: lucastakejame
I did, with the 32 Stack offset. My SystemCoreClock is 50000000 (I saw at debugging on lpcxpresso), I changed that line to:
SysTick_Config(SystemCoreClock / 10000);/



I'm not sure how fast your eyes are, but

SysTick_Config(SystemCoreClock / 10);


is setting SysTick to 10Hz 


Quote: lucastakejame
But still, after that assembly code the execution jumps to Hardfault_handler



I'm not sure how you are flashing...

So just flash your application with LPCXpresso and after that flash your bootloader (which is doing nothing more than jump to application). Now you should see both in your memory...
0 项奖励
回复

6,624 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Thu Feb 12 13:54:41 MST 2015
I did, with the 32 Stack offset. My SystemCoreClock is 50000000 (I saw at debugging on lpcxpresso), I changed that line to:
SysTick_Config(SystemCoreClock / 10000);
But still, after that assembly code the execution jumps to Hardfault_handler :/
0 项奖励
回复

6,622 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Feb 12 13:29:41 MST 2015

Quote: lucastakejame
I tryed again, first time I didn't configured right i think, the memory configuration files are attached.
It went to the same place as before =/.



Did you enable 'Managed linker script'?

[img]http://www.lpcware.com/system/files/ML.PNG[/img]


Quote: lucastakejame
I didn't understand what you meant by change SysTick timer setup, when I tested the application isolated it worked...



No  :)

SysTick is a 24bit timer. With a 48MHz main clock you can't set the the reload counter to 48E6  :((
Your setup  (48E6 / 100E6 = 0) is setting the reload counter to 2^24 =  16,7E6. So your SysTick is running with 48E6/16,7E6 = 1/3 Hz  :)


0 项奖励
回复

6,621 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Thu Feb 12 13:01:13 MST 2015
I tryed again, first time I didn't configured right i think, the memory configuration files are attached.
It went to the same place as before =/. I didn't understand what you meant by change SysTick timer setup, when I tested the application isolated it worked...
This is my first project with a MCU so I'm kinda lost, thanks your response =)
0 项奖励
回复

6,621 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Feb 12 12:29:59 MST 2015

Quote: lucastakejame
I've already tryed that...



The try it again  :)

Delete the nops in your jump, change SysTick timer setup and your bootloader / app is working...
0 项奖励
回复

6,621 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Thu Feb 12 12:26:10 MST 2015
I've already tryed that (attached an image of the configuration), since it didn't work I kept trying with the linkerscript from the AN10995.
0 项奖励
回复

6,621 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Feb 12 12:13:05 MST 2015
First of all I would strongly recommend to use 'Managed linker script' and set your flash size (bootloader: 0- 0x1000, App: 0x1000-) in MCU settings->Memory details...

BTW: Your Systick setup is really funny   
  /* Setup SysTick Timer for 1 second interrupt  */
SysTick_Config(SystemCoreClock / 100000000UL);
0 项奖励
回复

6,621 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lucastakejame on Thu Feb 12 10:30:09 MST 2015
Here is the bin:
http://pastebin.com/L1fTJELb

And yes I debugged, I followed the execution until the jump to the address contained in 0x1004, it went to 0x10D5 (which when I put a "nop" after copying 10D5 to pc started to fall on hardfault_handler), after a hardfault_handle, it jumps to 113D and a error occurs:

15: Target error from Set break/watch
HW execution break may only be set below 0x20000000.

Last instruction it tryed to do was

asrs r5, r2, #5

with

r20x00000000
r50x0000050E

Anyway, it seems to me that the vector table values are incorrect somehow...

Thanks for the response :)
0 项奖励
回复

6,621 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Wed Feb 11 16:03:37 MST 2015

Quote: lucastakejame
I checked if the .bin...
The application vector table looks ok...



Could be useful if post this bin...

Did you debug this 'it seems to go to a place with no valid instructions' ?
0 项奖励
回复