LPC11C24 bootloader interrupt redirecting/remapping

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

LPC11C24 bootloader interrupt redirecting/remapping

1,508 Views
harrienoorlande
Contributor I

Dear Community,

I seem to be having an issue with getting redirecting and/or remapping interrupts on a LPC11C24.

The used boot-loader is based on AN10995.

The problem is that I need to use interrupts in both the secondary boot-loader as well as in the application.

In order to jump from boot-loader to application I use the code below:

__disable_irq();
/* Load main stack pointer with application stack pointer initial value, stored at first location of application area */
asm volatile("ldr r0, =0x3000"); asm volatile("ldr r0, [r0]"); asm volatile("mov sp, r0");
__enable_irq();
/* Load program counter with application reset vector address, located at second word of application area. */
asm volatile("ldr r0, =0x3004"); asm volatile("ldr r0, [r0]"); asm volatile("mov pc, r0");
/* User application execution should now start and never return here.... */

When the boot-loader is not using interrupt, I can use the code below to relocate interrupt from boot-loader to application.

void UART_IRQHandler(void) __attribute__ (( naked ));

void UART_IRQHandler(void) {

asm volatile("ldr r0, =0x3094"); asm volatile("ldr r0, [r0]"); asm volatile("mov pc, r0");

}

Doing so, interrupt in the application are working fine, but the boot-loader is able to use interrupts.

To get interrupts in boot-loader, "__attribute__ (( naked ))" needs to be removed , to avoid getting compiler errors,

void UART_IRQHandler(void);

void UART_IRQHandler(void) {

/* handle interrupt <code> here */

}

Now interrupt are working fine in the boot-loader, however when the device gets an interrupt while in application, the interrupt is using the the interrupt handler from the boot-loader instead of it's own application interrupt handler.

In the threads below, multiple options have been proposed already, but I can not get them to work.

2nd bootloader - Requiring the same interrupt in bootloader and main application 

https://community.nxp.com/thread/422969 

Any suggestions to get interrupts in both boot-loader and application are welcome, but a working example is fine as well.

Kind regards.

Labels (1)
0 Kudos
5 Replies

744 Views
harrienoorlande
Contributor I

Dear LPCXpresso Support,

So far I stil havn't been able to solve this issue.

Is there perhaps some documentation available on how to proceed with 'indirect remapping of vectors'?

Kind regards,

Harrie

0 Kudos

744 Views
lpcxpresso_supp
NXP Employee
NXP Employee

So if the CAN peripheral is overwriting the lower RAM, that is certainly going to break things if the interrupt handlers are also being placed in that memory. I'm afraid that can't see any obvious straightforward way of working around this.

All I think of is using a further level of indirection and having your bootloader interrupt handlers look at a specific block of flash to see if those addresses contain "valid" address values for interrupt handlers provided by the application, and if they are valid - then read the address and branch off there.

 

Regards,

LPCXpresso Support

0 Kudos

744 Views
harrienoorlande
Contributor I

Dear LPCXpresso Support,

To bad that there isn't a straightforward way to solving this issue...

Would you be so king to provide an example on the suggested 'indirection' approach?

Kind regards,

H.W. Noorlander

0 Kudos

744 Views
lpcxpresso_supp
NXP Employee
NXP Employee

Unfortunately, the LPC11C24 uses a Cortex-M0 cpu which doesn't provide a VTOR register in its NVIC (interrupt controller) to allow you to relocate the vector table, as can be done on CM0+, CM3 and CM4 based parts.

However you should be able to use SYSMEMREMAP register to relocate the vector table for your application into RAM (which will mean that you need to copy the start of your image into RAM before enabling interrupts for it).

It sounds like you might have tried this. But what you don't say is the manner in which your setup doesn't work. If you can provide more details, it is more likely that someone could spot the issue for you.

One other thing to watch is that your application is located so that it starts on a flash sector boundary.

Note : there has been a bit of traffic about bootloaders recently in the LPC forum. If you haven't looked through those, it might be worth while doing so : LPC 

 

PS : You may find this old FAQ about debugging through a bootloader useful - DebugThroughBootloader - ** Code Red Support Site ** 

Regards,

LPCXpresso Support

0 Kudos

744 Views
harrienoorlande
Contributor I

Thank you for the input,

I tried using the SYSMEMREMAP register (see example below), here the vector table is copied and remapped to RAM.

uint32_t vector_in_ram[52] __attribute__ ((section ("vtable")));

int main(void) {

CAN_init();

__disable_irq();

uint8_t i;

uint32_t *p = (uint32_t *) 0x0000;                           // 0x0000 in booter and 0x3000 in application

for (i = 0; i < 52; i++) {

vector_in_ram[i] = (p + i);

}

LPC_SYSCON->SYSMEMREMAP = 0x1;
__enable_irq(); 

...

}

When using the SYSMEMREMAP approach, interrupts seem to be directed correctly to their own interrupt handler.

But unfortunately for CAN interrupt, this isn't the case...

  • while in boot-loader mode, the mcu halts.
  • while in application mode, the interrupt is ignored.

In UM10398 (17.4.1) is stated "On-chip RAM from address 0x1000 0050 to 0x1000 00B8 is used by the CAN API ... ".
Henceforward, I have been trying lots of different ways to exclude the aforementioned address section from remapping.

But, so far I have not been able to get the CAN interrupts to work successfully.

So,I think the question is, how to exclude the CAN API from remapping to RAM?

Kind regards,

H.W. Noorlander

0 Kudos