LPC11C24 IAP Flash Over CAN Hard Fault in Sector 0

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

LPC11C24 IAP Flash Over CAN Hard Fault in Sector 0

1,557 次查看
chrisfernam
Contributor I

Context: 

Currently I have a client application that sends CAN messages where 4 bytes of 8 bytes of data contain the HEX value of a new FW I would like to flash. In brief words, i'm sending 4 bytes of the new firmware over CAN, one message at a time, the LPC11C24 firmware keeps track of 256 byte segments and only then invoke this series of IAP commands in order:

1. Prepare Sector For Write Operation
2. Copy Ram To Flash 
3. Compare

Problem:In IAR Embedded Workbench IDE i can see the Flash addresses I specify update with the received data but this only seem to work with some sectors. I tried flashing in sector 0 or even 1 and i get hard faults. 

I have been stuck on this issue for weeks and would appreciate just about any recommendation. Thank you !

0 项奖励
回复
5 回复数

1,536 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Christian,

Pls refer to section 26.4.7 in UM10398.pdf, when you use IAP to erase/program flash, you have to disable all interrupt or put both the interrupt vector and ISR in SRAM.

26.4.7 Interrupts during IAP
The on-chip flash memory is not accessible during erase/write operations. When the user
application code starts executing the interrupt vectors from the user flash area are active.
Before making any IAP call, either disable the interrupts or ensure that the user interrupt
vectors are active in RAM and that the interrupt handlers reside in RAM. The IAP code
does not use or disable interrupts.

 

Hope it can help you

BR

XIangJun Rong

0 项奖励
回复

1,529 次查看
chrisfernam
Contributor I

Thanks for the swift response Xiangjun. 

 

Regarding 1st recommendation of ensuring to disable the interrupts before making any IAP call; I am currently doing this; please see the implementation below: 


IAP iap_entry;
iap_entry = (IAP)IAP_LOCATION;
uint32_t IAP_Command[5] = {0, 0, 0, 0, 0};
uint32_t IAP_Result[4] = {0, 0, 0, 0};


IAPCommands iap_command_to_execute = PREPARE_SECTOR_FOR_WRITE_OPERATION;
IAP_Command[0] = iap_command_to_execute;
IAP_Command[1] = SECTOR;
IAP_Command[2] = SECTOR;

__disable_irq();
iap_entry(IAP_Command, IAP_Result);
__enable_irq();

if(IAP_Result[0] != CMD_SUCCESS)
{
return FALSE;
}

 

iap_command_to_execute = COPY_RAM_TO_FLASH;
IAP_Command[0] = iap_command_to_execute;
IAP_Command[1] = (uint32_t)(SECTOR_ADDR + (BLOCK_NUM * FLASH_BUFFER_SIZE)); //(Offset % 256)
IAP_Command[2] = (uint32_t)buffer;
IAP_Command[3] = FLASH_BUFFER_SIZE;
IAP_Command[4] = CPU_CLK;

__disable_irq();
iap_entry(IAP_Command, IAP_Result);
__enable_irq();

if(IAP_Result[0] != CMD_SUCCESS)
{
return FALSE;
}

 

iap_command_to_execute = COMPARE;
IAP_Command[0] = iap_command_to_execute;
IAP_Command[1] = (uint32_t)(SECTOR_ADDR + (BLOCK_NUM * FLASH_BUFFER_SIZE));
IAP_Command[2] = (uint32_t)buffer;
IAP_Command[3] = FLASH_BUFFER_SIZE;

__disable_irq();
iap_entry(IAP_Command, IAP_Result);
__enable_irq();

if(IAP_Result[0] != CMD_SUCCESS)
{
return FALSE;
}

 

However, I have not tried the 2nd recommendation of ensuring both the interrupt vectors and the interrupt handlers are active in RAM. could you please shed some light as to how this may be verified, or accomplished? In IAR Workbench IDE, as I step through code I can see control executes from RAM addresses, but right after I erase sector 0 or 1 i can see control just navigate to some empty address which consequentially its when hard fault occurs. 

Thank you. 

0 项奖励
回复

1,522 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

If you disable all interrupt before calling IAP function, it is okay.

Regarding the flash address, pls check your application code map, and know total sectors the application code and constant data occupies, you can erase/program the sectors the application code/constant data do NOT occupy, otherwise, there is overlap, which will leads to hard-fault.

BTW, pls note that you have to erase the sector with api function before you program it.

Hope it can help you

BR

XiangJun Rong

标记 (1)
0 项奖励
回复

1,510 次查看
chrisfernam
Contributor I

Hi Xiangjun thank you very much for the recommendations. Since this is my first time learning to program such a chip, there are some terms I have been researching due to my unfamiliarity such as the application's code map. I looked into this inherited project's linkermap.icf (see below in bold), can you confirm if this is what you're referring to as application code map? 

 

It seems this config file assigns 32kB for flash, and 8kB for RAM storage. Indeed the application faults when flashing on top of sectors 0-3 which contain the currently running process. So what is your suggestion? Write to upper sectors (4-7), and then in one action copy those sectors to 0-3 and only then enable interrupts again? 

 

Your help is greatly appreciated. 

 

/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
/* Note that the CAN functions need to be reserved */
define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; //flash?
define symbol __ICFEDIT_region_ROM_end__ = 0x00008000;
define symbol __ICFEDIT_region_RAM_start__ = 0x10000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x10002000;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x400;
/**** End of ICF editor section. ###ICF###*/

0 项奖励
回复

1,501 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I suggest you disable all interrupt, and erase/program sector 7 with your constant data and check if it is okay. After the flash operation is complete, you can enable interrupt and run your other code.

BR

XiangJun Rong

0 项奖励
回复