Wednesday, 11 February 2015

Working with C's new fixed point datatypes in Eclipse CDT

I recently dusted off my ArduRoller project and ported the code to use C's new(ish) fixed-point extensions (as well as removing the dependency on the Arduino standard library).

I use Eclipse with the AVR plugin to develop ArduRoller because it's much more powerful than the Arduino IDE and it lets me work more closely with the hardware.  However, I quickly found out that Eclipse doesn't yet support the C fixed-point standard that I wanted to use for the new version.  After posting a feature request, one of the Eclipse developers got back to me and explained how to work around the issue, which is that the fixed point datatypes are completely unknown to Eclipse so they show up as unresolved symbols.

The trick is to define a special type of symbol that only appears in the Eclipse code indexer and then use a header shim to #define the datatypes only in the indexer.


First go to Your project > Properties > C/C++ General > Preprocessor include paths > Language and then add a new "User setting entry".  I added a symbol "ECLIPSE_INDEXER" defined as 1.

Then, before #include , include a shim header like this one:

/*
 * eclipsefixp.h
 *
 *  Created on: Feb 11, 2015
 *      Author: shaun
 */

#ifndef ECLIPSEFIXP_H_
#define ECLIPSEFIXP_H_

#ifdef ECLIPSE_INDEXER

#define ACCUM_LIT(num) 0
#define FRACT_LIT(num) 0

#define _Accum float
#define _Fract float
#define _Sat

#else

#define ACCUM_LIT(num) num##k
#define FRACT_LIT(num) num##r

#endif

#endif /* ECLIPSEFIXP_H_ */
Now you can use "accum" "fract" and "sat" with impunity as I did in the new ArduRoller code (the stdfix.h header maps _Accum to accum etc.) and if you need a fixed-point literal such as "123.456lk" you can use ACCUM_LIT(123.456l) and the k will get appended for you in the real code.

The fixed point datatypes helped speed up the code enough to run with a 1msec loop time, which as my target and they seem to work fairly well, with the rather annoying gotcha that there's no way to completely disable floating point.  If you accidentally use a float literal somewhere, it's easy to pull in the whole floating point library by mistake.