Tuesday, 6 October 2015

Importing mbed libraries to Em::Blocks - do not get caught by RTTI and "undefined reference to typeinfo" !

Ok, so you got some project that you have taken from mbed online compiler and imported to Em::Blocks. It's compiling fine.

And then you decide, oh yeah I need another library from mbed, so I'll just download it and add the files into my project in Em::Blocks.

Easy, right ? WRONG !!!

If you have any virtual functions i.e. polymorphic C++ classes, you will run into this:

.objs\~#\adafruit-gfx-library\adafruit_gfx.o:(.rodata._ZTI12Adafruit_GFX+0x8)||undefined reference to `typeinfo for mbed::Stream'|

Namely, you will run into "undefined reference to typeinfo' error given by the linker.

And you will be scratching your head.

And you will be reading up on your knowledge of polymorhism. Speaking of which, this is the most through and informative description I have ever seen: http://www.drbio.cornell.edu/pl47/programming/TICPP-2nd-ed-Vol-one-html/Chapter15.html  

Ok back to the story.

And you will be wondering what on earth is going wrong. Some inherited classes with virtual functions work, while others do not. What on earth could it be ? Malformed destructors ? Missing definitions ? Missing RTTI ?

... can't be RTTI. RTTI was deprecated in mbed a long time ago. 

... can't be RTTI. I am already building mbed libs from source, not the ready-built binaries.

So it can't be RTTI, right ? WRONG BUDDY, IT IS THE *¤%# RTTI.

(Sorry for outburst, took me a _while_ to find this problem)

Why ? Because imported files get different settings than files that were within the original .eix exported from mbed.

When importing an .EIX file every c++ file is given it’s own properties section in the .ebp file, where as the regular c-files relies on global options. If I add a c++ file after the import, this file doesn’t get its own section of options. It has to rely on the global options, which are for gnu99 c and not gnu++98.
Long story short. Turn RTTI generation off (-fno-rtti) in global settings, and your project will compile.









Monday, 28 September 2015

New toy: LPC11U68 (Cortex-M0, 256KB of Flash, 36 KB RAM)

This is a very interesting device. Low-power Cortex-M0 but with plenty of program and RAM memory. Unfortunately, I didn't instantly find a dev board that I liked, so I built my own.

Its running but ... external oscillator PLL lock fails. Maybe its just that the oscillator is poorly placed (long legs etc).

On internal RC runs 100% like it should (yes, MBED blinky example works, led is blinking in pin PIO1_13). Unfortunately, that means that USBPLL can't be used (the accuracy of the IRC is not enough = USBPLL lock fails).

Any advice on debugging PLL lock problems and external oscillator considerations are welcome.



 

Tuesday, 4 August 2015

Looking for code examples ? LPC1343 and LPC1347 are not siblings !

Just a little heads up for anyone starting to work with LPC1347.

Although you could *think* by the naming that LPC1347 is similar to LPC1343, looking at LPC1343 code samples is going to be a waste of your time.

LPC1347 is a Cortex-M3 version of the LPC11U24 (Cortex-M0). LPC1347 is NOT a RAM-expanded version of LPC1343.

Microbuilder.eu sums it up in this sentence:
The new GPIO block (of LPC1347) is the same one used in the similar ARM Cortex M0-based LPC11U24, which makes it easy to optimize for cost later and switch between the two devices, but it’s also unfortunately a breaking change compared to the 1343. All pins are now based on two GPIO block – PIO0[0..31] and PIO1[0..31] – rather than the previous four GPIO blocks on the LPC1343. This is potentially the biggest change from a SW migration point of view.
Why does this matter ?

Code examples for LPC1347 are relatively rare. If you are struggling to find good code examples for LPC1347, here's my advice: search for LPC11U24 or LPC11U35 instead. With high probability you will find example code that works with small (or no) changes also on the LPC1347.

For further study of how LPC1343 and LPC1347 differ, take a look at the CMSIS header files:

LPC13xx.h (for LPC1343)
LPC13Uxx.h (for LPC1347)

And also the similarity of LPC1347 to the LPC11Uxx.h ...

LPC11Uxx.h (for LPC11U24 and LPC11U35)


Thursday, 30 July 2015

Why your binary will not run on LPC1347 - the missing checksum

So, you've compiled your code and now you have a binary. You've dropped that binary into your LPC1347 / EzSBC2 board, and it won't run. In fact, you get the Mass Storage Controller bootloader popping up.

This is because the bootloader that runs from ROM checks to see if a valid user program is present in flash.

The way it does it is as follows (from LPC1315/16/17/45/46/47 User manual):

21.7 Criterion for Valid User Code
The reserved ARM Cortex-M3 exception vector location 7 (offset 0x0000 001C in the vector table) should contain the 2’s complement of the check-sum of table entries 0 through 6. This causes the checksum of the first 8 table entries to be 0. The bootloader code checksums the first 8 locations in sector 0 of the flash. If the result is 0, then execution control is transferred to the user code
If the aforementioned checksum is not valid, your code won't run. When you compile in EmBlocks, it does not put in that checksum.

An easy fix to the problem is a command line tool called LPCRC that will calculate and correct the checksum in your binary. I found it in the tools/ section of the Microbuilder LPC11U/LPC13U Code Base, which is an excellent resource for programming your LPC1347.

Wednesday, 22 July 2015

Debugging in EmBlocks part 1: LPC1347 core speed and .SVD files

I now have my Jlink up and running and debugging the EzSBC2 in EmBlocks. Since I am a bit suspicious how the mbed library handles things, I wanted to check the core clock speed from the debugger.

Checking the core speed from System Registers


However, when I tried to look at the System Registers debug window to verify that my LPC1347 is indeed running at the correct MHz, the window was empty.

What we need is a so-called device description file (.SVD) that describes the internal registers of the MCU to the debugger.

You can get the .SVD for LPC1347 from NXP lpcware site here. 

Stick the .svd file path into your Debug->Interfaces settings thus:


After I had put in the .svd and restarted the debugger, I finally got the info I needed:

NOTE: you will see register values only when the debugger is halted !! NOT when the MCU is running.

SYSPLLCTRL says MSEL is 5. Therefore main clock is (MSEL+1)*oscillator (12 MHz) = 72 Mhz.
SYSAHBCLKDIV says DIV is 1, therefore core clock is main / 1.

= System Core Clock is 72 MHz, as intended.

Monday, 20 July 2015

Importing your mbed project to EmBlocks

Unpack the .zip file you got by exporting from mbed online compiler (see previous post).

Open up EmBlocks (or EmIDE, depending on what version you are using).

Import the .eix (EmBlocks eXport) file to EmBlocks:




Put in correct settings for your debugger:


And your device settings (under the Settings >> button)