LPC11C24 - vector remap generates HardFault

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC11C24 - vector remap generates HardFault

892 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bomba82 on Fri Jan 31 01:47:26 MST 2014
Hello,
  I am trying to implement a solution for upgrading firmware using a CAN second bootloader approach.
To do so I need to remap vectors for the application firmware. Since bootloader fits in 2 pages, my application executes from address 0x2000 and then I need to use vector remapping to RAM.

I had success in my first attempt to upgrade firmware with a simple blinky project. The problems arose when I tried to add CAN communication to that simple project: I get a HardFault error after I make the first call to "can_transmit" function.

To simplify things I tried to execute the project in debug configuration from address 0x0000.
If I execute the project without remapping everything is ok.
If I execute the same project trying to remap vectors from 0x0000 to 0x10000000 (SYSMEMREMAP=1) I get that HardFault error. (there is no sense to do that remapping, but it's just to test remapping in the easiest way)

I read the user manual and many threads on this forum but I can't figure out what I am doing wrong. Does someone have any suggestions?

I attach the BlinkyCAN project. It's very simple to view the problem:
1) try to execute the project as provided. It should execute correctly on a LPC11C24 LPCXpresso Board. The LED should blink.
2) Set the "EXCLUDE_CAN" macro to 0. The HardFault problem arises.

Original Attachment has been moved to: BlinkyCAN.zip

Labels (1)
0 Kudos
6 Replies

681 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bomba82 on Wed Feb 05 06:53:19 MST 2014
Dodigl,
  after implementing the version with jumps in the ISRs I discivered that the only ISR that caused me problems was CAN ISR. I then followed your suggestion and implemented a version with polling and now everything works fine.

I can't still understand why I can't use the CAN ISR, since in this last implementation I can't see address conflicts.

Thank you very much for your help! But if you know why I can't use that interrupt, please let me know. I want to understand why.
0 Kudos

681 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bomba82 on Mon Feb 03 09:39:25 MST 2014
I am using eclipse, but I think it was a bad idea.

Now I understand what you said and I agree that it's not possible to make things work as I proposed.
That's why I switched back to the solution with jumps to application ISRs. I can use the same ISR for bootloader and application, so I don't redirect CAN ISR.

I did a first attempt with the simple blinky project and I had success. Just a note: I had to write
  LPC_SYSCON->SYSMEMREMAP = 0x2;
  __enable_irq(); // enable interrupts

at the beginning of application main. Otherwise blinky project does not execute correctly.

Second attempt: blinky with CAN. I can't make things work. After launching the target application something goes wrong. I can see a message correctly transmitted on the network, but then it doesn't reply to my CAN messages and even the LED doesn't blink. This time I don't even know how I can debug it.

Does someone have a suggestion? What's wrong this time?
0 Kudos

681 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DodigI on Fri Jan 31 10:04:09 MST 2014
What tool are you using?

In Keil it is very easy via the provided GUI configuration (no scatter file modification).

I'm 99.99999% sure that it is not possible to make it work the way you proposed, because the RAM region for CCAN is right in the middle of the vector table. CPU loads ISRs automatically, this cannot be controlled by software.

I understand you problem, my bootloader uses only CCAN ISR which is the same for the application also. Maybe you should try pooling instead of using interrupts in the bootloader.

Another option is to switch to LPC1300 which is pin compatible with LPC1100 but you lose CAN PHY. LPC1300 has a Cortex M3 which can remap vector table to another location in flash.

Good luck.
0 Kudos

681 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bomba82 on Fri Jan 31 04:13:00 MST 2014
I'd want to try a workaround, but I don't know how to implement it.

My idea is as follows.
I should exclude CAN reserved RAM from remapping, and I can simply do it with subsequent code:
int i = 0;
__disable_irq();
int32_t *p = (int32_t *) RELOC_ADDR;
// copy the interrupt vector table on base RAM
for (i=0;i<(MEMREMAP_SIZE >> 2);i++)
{
if ( &vector_in_ram < ((int32_t *)0x10000050) || &vector_in_ram > ((int32_t *)0x100000B8) )
{
vector_in_ram = *p;
}
p++;
}
LPC_SYSCON->SYSMEMREMAP = 0x1;  // remap the interrupt vectors to ram
__enable_irq(); // enable interrupts


Now the problem would be that I am not copying a part of my code in flash. But what if I fill that range (0x0050 to 0x00B8) of unuseful code? My problem now is that I don't know how to do that. In the linker script I can define the flash region for the code, but I don't know how to define an unusable hole.

Does someone know? Or does someone know if it's a bad idea?
0 Kudos

681 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bomba82 on Fri Jan 31 03:46:10 MST 2014
Hi Dodigl and thanks for the response.

I started my adventure with second bootloader reading AN10995. The problem is that I changed my approach to vector remapping beacuse implementing jumps seemed to be unusable in my case. I need to use ISRs in the bootloader, for example SSP ISR.
Am I wrong taking this assumption? There are some threads asking if it's possible to implement a bootloader and use ISRs, but I couldn't find a final response to the question. I thought the right solution was remapping, but maybe it is not...  :(
0 Kudos

681 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DodigI on Fri Jan 31 02:42:21 MST 2014
Hi.

Unfortunately you cannot remap vector table to RAM and use CCAN drivers at the same time. The reason being is that CCAN driver use absolute addresses in that RAM region which you MUST specify in the linker configuration.

On-chip RAM from address 0x1000 0050 to 0x1000 00B8 is used by the CAN API. This address
range should not be used by the application. For applications using the on-chip CAN API,
the linker control file should be modified appropriately to prevent usage of this area for
application’s variable storage.


There is another way by implementing jumps in the bootloader interrupts. I have modified the startup.s file with some additional assembly code. There is an application note for this, please see AN10995 from NXP.

Enjoy
0 Kudos