March 30, 2013

Dynamic initialization C++ in IAR

I've been running my demo application only in KEIL for few days which I believe was huge mistake which reflected on me on Friday. When I finally run it in IAR. Once it loaded, first object's method ended up in a default isr handler with the hard fault. My debug session started. First problem I found, was one function was overwritting memory, that one was simple to catch once I found out which memory and what object is located right before overwritten data. Second one was a bit tougher to find out.

I decided to move local user-type objects to a global scope, which means before an application hits main function, global objects must be initialized. No problem with KEIL, but IAR did not do it.

This is quote from EWARM Development Guide (IAR) [3] which is quite comprehensive manual to understand many options it offers through command line options. But it does not provide details which might be handy.
When using the IAR C/C++ compiler and the standard library, C++ dynamic
initialization is handled automatically.


I though all right, how to track it down and see if dynamic allocation is really executed. Let's check map file of my application:

INIT TABLE
          Address     Size
          -------     ----
Zero (__iar_zero_init3)
    1 destination range, total size 0x2a7:
          0x1ffff420  0x2a7
Extra (__iar_cstart_call_ctors)

And here's ENTRY LIST of our interest:

__call_ctors            0x00004775   0x18  Code  Gb  cppinit.o [4]
__iar_cstart_call_ctors
                        0x00004ae5   0x20  Code  Gb  cmain_call_ctors.o [7]

A problem is, they are not invoked, startup function just takes care regular things (copying initialized data from ROM to RAM, .bss data, vector table). There's nothing with dynamic initialization. I placed breakpoint inside __call_ctors and it surprisingly was not reached. How to invoke __call_ctors function? What's it declaration? Exactly this details is not in any documentation provided in IAR doc folder (at least I was not able to find it there). Only one link on google was relevant, let's test it.

extern void * __iar_cstart_call_ctors(void *ptr);

No linker errors, correct declaration. Only one parameter, what it should be? The linker created following sections which are the one we are looking for (more info find in section C++ DYNAMIC INITIALIZATION [3] :

.init_array$$Base       0x00004d58          --   Gb  - Linker created -
.init_array$$Limit      0x00004d5c          --   Gb  - Linker created -
 
SHT$$INIT_ARRAY$$Base   0x00004d58          --   Gb  - Linker created -
SHT$$INIT_ARRAY$$Limit  0x00004d5c          --   Gb  - Linker created -
SHT$$PREINIT_ARRAY$$Base
                        0x00004d58          --   Gb  - Linker created -
SHT$$PREINIT_ARRAY$$Limit
                        0x00004d58          --   Gb  - Linker created -

Each section (INIT_ARRAY, PRE_INIT_ARRAY) contain array of pointers to initialization functions. [2] Let's invoke it in the end of an application's startup with a following line:

void *cpp_init = __section_begin(".init_array");
__iar_cstart_call_ctors(cpp_init);

That calls __call_ctors which initializes all global dynamic objects. Thus application works. An unanswered question is why it was not invoked automatically? I hope I'll come with an answer soon :)

References:
[1] cmain.s [http://code.google.com/p/sdp-firmwares]
[2] System V Application Binary Interface [sco.com/developers/gabi]
[3] EWARM Development Guide - IAR installation folder/arm/doc or online

auto_ptr , unique_ptr C++

I implemented kind of factory to create objects which were already alocated by one library. A user can just ask for object and the factory returns it. Firstly, it has normal pointer which leads to resource leaks. I tried to include memory header and small test application it in KEIL. It worked, the pointer gets deleted after it leaves it's scope. Thus I rewrote "factory" to return auto_ptr. Unique_ptr is not available in KEIL v4.60 (not tested in IAR yet).

I am glad I bought Effective C++ from Scott Mayer. Many ITEMS in the book make me think why I did not think of that before. I appreciate having more books like that one.

unique_ptr C++ [home.roadrunner.com/~hinnant/]
The site provides a comparision between auto_ptr and unique_ptr with code examples.

March 24, 2013

Stack usage for ARM Cortex-M

I'll present how I used one of the methods to measure stack usage, not using any plugin, just debugger and memory window.

Methods to use:
1. IDE plugins (usually compiler and linker do the job)
2. Fill pattern (add small assembly routine in startup)
3. Take an address of the stack pointer in the main function, and in the most nested function (for a simple application usable)


IAR stack plugin [www.iar.com]
This document is targeted to IAR stack plugin. Although this did not work for the MCU I debugged.

Stack and Heap [www.iar.com]
What's stack, heap, methods explained briefly how to calculate stack usage in IAR. Methods applicable for other IDE's as well, not limited to IAR only.

Stack use in C and C++ [www.keil.com]
How to obtain stack usage in KEIL using callgraph (option --callgraph).
Here's callgraph output which I found on the internet, not needed to share mine:
Keil callgraph - an example [ftp.analog.com/pub/MicroConverter]

Using indirect calls (function pointers) make this method unreliable, same for IAR stack plugin, where it can be added #pragma calls, but what if an application using another library, that's too much changes to do, more simple approach is in a following paragraph presented, a filling memory for a stack with a pattern and show how low it gets.

KEIL stack initialize routine [www.keil.com/forum]
Stack initialization routine, which I only accustomed to Thumb-2. Here's the code used on Cortex-M0. Label __user_initial_stackheap is located in assembly file for your board. Just run your application for a while and check the memory window to obtain the lowest address of the last character of your pattern (in our case it's AA (char values)). Calculate the subtraction which gives your application stack usage.

__user_initial_stackheap
    LDR     R0, =Stack_Mem
    LDR     R1, =Stack_Size           
    LDR     R2, =0xAAAAAAAA
fill             
    STR     R2, [R0]
    ADDS    R0,#4
    SUBS    R1,#4                     
    BNE     fill

This also can be added in assembly file which is used in IAR or any other IDE, just replace Stack_Mem symbol (beginning of the stack) and Stack_Size (size of the stack).

March 19, 2013

Singleton design pattern C++ (bookmark)

I am still waiting for my GoF book to arrive, thus I have to read some articles.. This time I was curious about singleton design pattern, there's a user type object in my application which has to be only one. To implement simple singleton, I chose Scott Mayers Singleton (from Effective C++).

C++ Singleton Implementation [vladislavonline.com]
Here's comparison between GoF implementation and Scott Mayer's.

Several C++ singleton implementations [silviuardelean.ro]
4 approaches presented, but scott mayers is slighty different, because copy and assignment are defined, which is not the original version.

Anyway, the best reference is the book Modern C++ Design. Chapter 6 contains information about implementation of Singleton, how to handle destroying it and also multi threaded application concern.
In case you don't have a copy of the book, this presentation uses sources from it, check it out:
Singleton C++ [www10.informatik.uni-erlangen.de]

March 17, 2013

Effective C++ in an embedded environment (book review)

There's only a preview of this presentation created by Scott Mayer, first 30 pages are accessible online.

The beginning is targeted to the virtual functions (virtual tables and their pointers). Virtual methods, multiply inheritance. Follows C++ features comparison with C with no-cast, small-cost and what can surprise C programmer if they are not aware of "small" details. More topics discussed in the book are C callbacks, code bloat (templates, inlining), TR1 and Modeling Memory-Mapped IO.

Almost at the end is Further information chapter where is quite long list of articles (links, books..) used for each topic in the book. That serves as references if something is still not clear.

Consequently, the book (more of a presentation than a book) gave me some insights in C++ which I did not consider before. As an example, I am currently implementing C++ application for one C library which generates callbacks. The section dedicated to the callbacks helped me a lot.

References:
Effective C++ in an embedded environment [www.artima.com]

March 13, 2013

KEIL and bkpt 0xab

This was particular my inattentiveness this time. Once I created new function which returns object created on the HEAP (using C++ and KEIL on Freescale KL25), program stopped working. It got stucked at instruction BKPT 0xab. I thought somehow semihost got enabled, did recheck if it was not enabled.

After I checked all options offered in KEIL, I started to think this must be related to the heap. The problem was in startup assembly file where HEAP was initialized to 0.

I have attached picture from disassembly:

March 3, 2013

Error detection checksums (bookmark)

This post will be describing checksums only.
How to find out the message you received is same as the one which was sent? Checksums or CRC? there are at least dozen approaches (let's name few : additive, XOR, one's complement, two's complement, fletcher's  and many more).

One library I have been using implemented additive checksum. Is this the right one to implement in embedded world? The answer is provided in the next link:

The Effectiveness of Checksums for Embedded Networks [ece.cmu.edu/~koopman]
One to start with, thesis dedicated to the checksums.

Which Error Detection Code Should You Use? [betterembsw.blogspot.com]
This one sums it all briefly.

Additive checksums [barrgroup.com]
I usually find an article on barrgroup which forces me to look for more than just that topic.

I am going to rewrite that additive checksum to the one's complement solution. Few more instructions executed once in a while are worth it. The implementation is in the barrgroup's article down the page. There's mistake though, sum should be 32bits in order to get properly carry bits.