5 years, 11 months ago.

LPC1114FN28 InterruptIn Not Working And Its Fix And Manual Linker Script

/media/uploads/waiyung/lpc1114.ld How to recreate this problem?

1. Create a new project in mbed.org online for LPC1114FN28, ex. blinky
2. Use mbed-src instead of precompile mbed
3. Export to offline toolchain LPCXpresso
4. Import the exported project into LPCXpresso, as of today, I used LPCXpresso v7.9.2_493
5. Wire external components to LPC1114 DIP module, RYG LED, two active low push buttons
6. Build project in LPCXpresso as is, ie. without changing and project settings
7. Download the project to LPC1114FN DIP module
8. Program will not work, why?

#include "mbed.h"

DigitalOut  LedR (dp14);
DigitalOut  LedY (dp17);
DigitalOut  LedG (dp18);

InterruptIn Btn1 (dp26);
InterruptIn Btn2 (dp28);

void ISR_Btn1Fall () {LedR = 0; LedY = 0; LedG = 0;}
void ISR_Btn2Fall () {LedR = 1; LedY = 1; LedG = 1;}

int main ()
	LedR = 0;
	LedY = 0;
	LedG = 0;

	Btn1.mode (PullUp);
	Btn2.mode (PullUp);

	Btn1.fall (&ISR_Btn1Fall);
	Btn2.fall (&ISR_Btn2Fall);

    while (1)

There are THREE steps to fix this problem. Thank u Johannes Stratmann for pointing out the fix. Please read both text and screen capture. In summary,

A. In LPCXpresso, fix MCU memory, RAM setting to match mbed.org exported linker script
B. In LPCXpresso, DO NOT use managed linker script, use manual linker script instead
C. In LPCXpresso, use my linker script LPC1114.ld in place of mbed.org exported one.  Read comment in file

Screen capture for A /media/uploads/waiyung/lpc1114.fix1.jpg Screen capture for B /media/uploads/waiyung/lpc1114.fix2.jpg Manual linker script for C /media/uploads/waiyung/lpc1114.ld

After completing StepA, B, and C, please

1.   Clean project
2.   Build project
3.   Download project to LPC1114FN DIP module
4.   Everything is working now

1 Answer

5 years, 11 months ago.

different optimization sounds like you are using the exported project in LPCXpresso. If so, you should look for the managed linker script. When you don't use the mbed exported linker script and use the LPCXpresso generated, then you have to take care of the IntVector table at the beginning of the RAM. You need to modify the RAM settings in the MCU project settings, add the offset and change the length of the RAM : RamLoc8 (rwx) : ORIGIN = 0x100000C0, LENGTH = 0x0F40 /* 4k */ It took me also 2 days to find out because it results in real strange runtime behaviour...

Thank u. You are correct. I am using LPCXpresso. But I am using managed linker script.

posted by WAI YUNG 05 Jan 2016

Ok, when you have checked the option 'Manage linker script' in the linker settings then you have to modify the RAM settings. LPCXpresso will starting at RAM address 0 and that confilicts with the mbed IntVect table (verctors are copied to the begin of the RAM).

posted by Johannes Stratmann 05 Jan 2016

Yes, I have made updates to this post. Based on your feedback, I was able to fix it. So, I changed title of this post and included fix procedures. Thank u

posted by WAI YUNG 06 Jan 2016

You are welcome, I'm happy that I could help you. Some more comment on your solution: - with the MCU RAM modification like in (A), the setting 'Manage linker scriopt' must also work. This has the advantage that you can easily switch between the different runtime libs and also try the different linker settings. - in your linker script your are wasting 0xC0 Bytes of your RAM, change the line top_RamLoc8 = 0x10000000 + 0x0F40; to top_RamLoc8 = 0x100000C0 + 0x0F40;

posted by Johannes Stratmann 06 Jan 2016

This could be a dump question. Why is there a waste of RAM size 0xC0? Thank u

posted by WAI YUNG 06 Jan 2016

you have 4k RAM, 0x1000 Bytes. The symbol top_RamLoc8 marks the max. RAM address (+1). This is still 0x10001000. We have only to thell the linker that the range 0x10000000 to 0x100000C0 is not usable for our code. So the expression 'top_RamLoc8 = 0x10000000 + 0x1000' is also ok. top remains top, only the begin has the offset and so remaining size is less.

posted by Johannes Stratmann 06 Jan 2016