April 29, 2013

Casting in C++

As I most of my day time code in C, I used C-style casts in the beginning. The application was mixture of C and C++ (C++ API for C static library), therefore casts were needed (void pointer to data returned).

I corrected entire code, to replace with proper C++ casts. Because be aware of how C casts are interpreted in C++ language, they combine const_cast, static_cast and reinterpret_cast. One which works is used. Here are some disadvantages: hard to locate them, no compiler check, the ambiguity => not explicit, no dynamic runtime check (sometimes useful but costy - RTTI).

There are 4 casting operators  in C++: static_cast, const_cast, dynamic_cast, reinterpret_cast.


Small guide to casting in C++ [justcheckingonall.wordpress.com]
It gives an insight about C++ casting, 

April 22, 2013

Two sites with list of C / ARM / AVR books and tutorials.

While I was checking books which I would like to buy, I found these two webpages which share literature about C/embedded/signals.

Keil embedded bookshelf [keil.com/books]
 I had to ordered another two new books which I have not read yet, ARM assembly language and ARM system developer's guide. I can't wait to read them.

AVR freaks - Online C books and Tools [avrfreaks.net]
Rich list of many tutorials, books mostly for C lang, AVR related.

April 20, 2013

G++ and C static library with C files ( -x flag )

I faced one rather small problem which engaged me for a while. I ported C++ demo application to CodeWarrior 10.3 using g++. Linked library was compiled with gcc.
Linker was against me to build the demo. It shown undefined variable errors in static library (library plus some files which are outside of the library). I knew those undefined variables are properly declared and had to be visible to the linker. The output in a console was allright at first sight.

I explored linker settings in CW (not much to do with options there, preferably to use own linker commands). Did not do the trick. I proceeded to compiler, here's link which made it clear:

man gcc [cf.ccmr.cornell.edu/cgi-bin]

Particulary option -x none. I did not see any -x in the console output. Once I had added it into command line pattern, it linked.

"${ARMSourceryDir}/${COMMAND}" -x none ${INPUTS} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT}


April 13, 2013

Sublime Go to the definition - CTags

One of the two features I really appreciate during a development - Go to the definition. I had downloaded Ctags plugin but it did not work out of the box only because I did not know about downloading CTags (http://ctags.sourceforge.net).

Once you extract files, add a path to CTags in PATH inside Enviroment variables (for instance ;C:/Program Files/ctags). Open command line and type ctags. If an output is ctags: No files specified, we can proceed to the Sublime.

Click on any project opened in file browser there, first option should be CTags Rebuild tags. CTags creates two files in your project .tags_sorted_by_file and .tags. Use shortcut to GO TO THE DEFINITION is by default CTRL+SHIFT+. in windows. Awesome!

April 10, 2013

Compile time assertion in C lang

I planned to check more information about compilation assertion in C. How to check for size errors, alignments during compilation phase? The answer is compilation assertion which declares a variable which causes compilation error if the condition is true. Here are "simplest" one:

Checking sizeof at compile time [scaryreasoner.wordpress.com]
This article provides explanation of BUILD_BUG_ON macro which is used in linux for example. It can't be used in global scope because it's a statement.

Catching errors early with compile-time assertions [embedded.com]
Dan Saks article which solves the global scope problem with previous one,

#define compile_time_assert(cond, msg) \
  typedef char msg[(cond) ? 1 : -1]

Even though message is not shown in some IDEs, at least code line is thus it's easy to decipher it from the msg parameter why it caused an error.

April 2, 2013

Header circular problem ("impossible" errors received)

Once I moved only one include from the main code file to the main header file, I received weird errors from IAR:

Error[Pe020]: identifier "namespace" is undefinied
Error[Pe065]: expected a ";"
and so on...

My intuition was that it is header include problems. How could it scream namespace is undefined.
I corrected few includes in my application but still no success. The same application was successfully built in KEIL. I continued with removal all unnecessary includes until I found the one which caused all errors.

Lesson learned, time to do a review of our includes in all applications.

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.