Friday, December 26, 2008

GIT and CR/LF-ing

I recently started using git and it's amazing. Since I do many of my work in Windows I use msysgit which does a nice job. 

However, there are some issues regarding the famous <CR><LF> line endings: git will try to convert single <LF>'s to <CR><LF>'s by defaut. Recalling the previous post about automatic build number generation, git will warn about single <LF> termination on some files, specially the ones generated by sh under Windows.

Fortunately, the git docs discuss every detail about customization and git itself. To force git to leave the files as is and forget about line terminations the file .git/info/attributes should be modified by adding something like this (and created if it doesn't exist yet):



file_to_ignore -crlf
another_file_to_ignore -crlf

That way git will just ignore the single-LF ending inside the specified files. Wildcards are also possible.

Another nice trick that has nothing to do with line termination is the file .git/info/exclude which tells git to exclude certain files from the repository (wildcards allowed too).

Wednesday, December 17, 2008

Automatic build number generation

Version tracking is essential for several reasons. Without a proper versioning system it's difficult to know if this or that firmware contains certain update or feature, specially if one forgets to increment the version number.

That's where the build number appears, assigning a unique number per build (or 'make' in this special case). That way it can't go wrong. Version number is still there but there is also a build number, uniquely defining the release.

I usually never reset the build number, so even if the version number jumps (modified manually) the build number will always increment. It's not mandatory, it depends on how you feel about it.

Implementation

Here is an automatic build number generator. It's a shell script based on sh. I used it with Windows without any problems as long as sh and friends are available on the system path.



#!sh
# FILE: make_buildnum.sh
version="`sed 's/^ *//' major_version`"
old="`sed 's/^ *//' build.number` +1"
echo $old | bc > build.number.temp
mv build.number.temp build.number
#versión..
echo "$version`sed 's/^ *//' build.number` - `date`" > version.number
#header
echo "#ifndef BUILD_NUMBER_STR" > build_number.h
echo "#define BUILD_NUMBER_STR \"`sed 's/^ *//' build.number`\"" >> build_number.h
echo "#endif" >> build_number.h

echo "#ifndef VERSION_STR" >> build_number.h
echo "#define VERSION_STR \"$version`sed 's/^ *//' build.number` - `date`\"" >> build_number.h
echo "#endif" >> build_number.h

echo "#ifndef VERSION_STR_SHORT" >> build_number.h
echo "#define VERSION_STR_SHORT \"$version`sed 's/^ *//' build.number`\"" >> build_number.h
echo "#endif" >> build_number.h

In order to make it work a file named major_version has to be created. It should contain something like "1.02." (no double commas). A file called build.number is also needed. It will be the starting build number like "1". Version number won't be modified but build number will be incremented each time make_buildnum.sh is executed. In order to be useful for C programming the header file build_number.h is updated to reflect both build.number and major_version.

I usually create a makefile dependency to perform automatic build number generation by adding something like this to the Makefile:



# main rule
all: build_number.h $(TARGET).whatever $(TARGET).other
@whatever rules

# rule for build number generation
build_number.h: $(SOURCES)
@echo
@echo Generating build number..
sh make_buildnum.sh

A new build number is assigned every time a source file is modified. There can be other approachs too like generating a new build number even if no files were modified.

IMPORTANT: Under Windows care must be taken with CR and CRLF line endings. The files build.number and major_version have to be terminated with CRLF, otherwise sed and the other linux/unix utils won't be able to parse them.

Finally here is an example of what build_number.h looks like:



#ifndef BUILD_NUMBER_STR
#define BUILD_NUMBER_STR "1234"
#endif
#ifndef VERSION_STR
#define VERSION_STR "1.0.1234 - Fri Dec 19 11:00:23 HSE 2008"
#endif
#ifndef VERSION_STR_SHORT
#define VERSION_STR_SHORT "1.0.1234"
#endif

The bash script is easy to modify if any other information is needed, such as build number as a proper integer if some preprocessing is needed.

Thursday, December 4, 2008

Embedded C++ constructs - Part 2

As mentioned in part 1, I'll now get into an UART example, providing the basic functionality through a class. This example works with the LPC ARM7 family from NXP Semiconductors (Philips).

Register abstraction

First here is how I abstract a hardware register. It's nothing special but a simple template class:



namespace HW
{
/**
* Individual HW register
*/
template < unsigned long int BASE, unsigned long int OFF >
class Reg
{
public:
void operator = (const unsigned long int & val) {
*((volatile unsigned long int *)(BASE + 4*OFF)) = val;
}

unsigned long int & operator = ( const Reg & reg ) {
return *((volatile unsigned long int *)(BASE + 4*OFF));
}

operator unsigned long int () {
return *((volatile unsigned long int *)(BASE + 4*OFF));
}
};

};

(I used C-like casts here but it would be better to use reinterpret_cast<> instead)


Three operators are implemented. It's essential to be able to cast the class to an unsigned int so we can use it transparently.

The template parameters let us provide a base and offset address which will be useful when a peripheral is abstracted through a template class.

UART peripheral abstraction

The UART peripheral in the LPC2xxx family consists of a collection of registers, starting from a base address. There are some interesting bits lying around on the microcontroller too that control peripheral power, the peripheral's clock and associated interrupts. Here all of them are encapsulated in a single class, except for the interrupts (to do).



namespace HW
{
/**
* UART Module Abstraction
*/
template<unsigned int BASE, unsigned int PCON_BIT, unsigned int PCLK_SEL>
class RegUART
{
public:
void powerOn() {
PCONP |= (1<<PCON_BIT);
}

void setClkDiv( unsigned int divv ) {
PCLOCK_SELECT( PCLK_SEL, divv );
}

HW::Reg<BASE, 0> RBR;
HW::Reg<BASE, 0> THR;
HW::Reg<BASE, 0> DLL;
HW::Reg<BASE, 1> DLM;
HW::Reg<BASE, 1> IER;
HW::Reg<BASE, 2> IIR;
HW::Reg<BASE, 2> FCR;
HW::Reg<BASE, 3> LCR;
HW::Reg<BASE, 5> LSR;
HW::Reg<BASE, 7> SCR;
HW::Reg<BASE, 8> ACR;
HW::Reg<BASE, 9> ICR;
HW::Reg<BASE, 10> FDR;
HW::Reg<BASE, 12> TER;
};
};

#define HWUART0 HW::RegUART< UART0_BASE_ADDR, PCLK_UART0, PCLK_UART0 >
#define HWUART1 HW::RegUART< UART1_BASE_ADDR, PCLK_UART1, PCLK_UART1 >
#define HWUART2 HW::RegUART< UART2_BASE_ADDR, PCLK_UART2, PCLK_UART2 >
#define HWUART3 HW::RegUART< UART3_BASE_ADDR, PCLK_UART3, PCLK_UART3 >

PCONP and PCLOCK_SELECT() are macros defined in another file, nothing special.

HWUARTx are macros that help when specifying certain port. It will be used in the next piece of code.



#include <string.h>

namespace Drivers
{
/**
* LPC2xxx UART Peripheral
* Polled.
*
* @param T Hw::RegUART
* Use HWUART0, HWUART1...
*/
template< class T >
class PolledUart
{
private:
T UART;

public:

/**
* Init UART
*
* @param brate desired baudrate
*/
void init(unsigned int brate) {

UART.setClkDiv( PCLK_DIV_1 );
UART.powerOn();

UART.LCR = 0x80; //DLAB = 1

UART.DLL = (Fpclk/16)/brate & 0xFF;
UART.DLM = (((Fpclk/16)/brate) >> 8) & 0xFF;

UART.LCR = 3 | //8 bit char length
(0<<2) | // 1 stop bit
(0<<3) | //no parity
(0<<4) | //partity type
(0<<6) | //disable break transmission
(0<<0) ; //enable access to divisor latches

UART.FCR = (0x07); //FIFO ENABLE, Rx & Tx
}

/**
* Transmit a single byte
*
* @param c
*/
void tx( unsigned char c ) {
while ( !( UART.LSR & (1<<5) ) )
;
UART.THR = c;
}

/**
* Transmit several bytes
*
* @param data data to transmit
* @param length length of 'data'
*/
void tx( const unsigned char *data, unsigned int length ) {
while( length-- > 0 )
tx( *(data++) );
}

/**
* Transmit a C string
*
* @param str
*/
void tx( const char *str ) {
tx( (const unsigned char *) str, strlen(str) );
}

/**
* Byte receive
* BLOCKING
*
* @return unsigned char received char
*/
unsigned char rx(void)
{
while ( !( UART.LSR & (1<<0) ) )
;

return UART.RBR;
}

/**
* Returns if there is data to be read in the FIFO
*
* @return bool true if there is data available
*/
bool isDataAvailable(void)
{
if ( UART.LSR & (1<<0) )
return true;
else
return false;
}
};
};

PolledUart implements UART basic functionality. No constructor is used to avoid undesired code creation, so init() must be called before using any other function.

Even though this class contains a RegUART class as a private member it won't take any extra memory since the compiler (at least gcc-elf-arm here) will optimize the template. I did some tests and there is no difference in code size with a simple C function doing the same statements directly.

Finally, to see how it works, if we wanted to use UART0 through this class we could instantiate it like this:



Drivers::PolledUart< HWUART0 > Uart0;

void testUart0()
{
Uart0.init(115200); //init @ 115200 bps

Uart0.tx("Hello there!\n");
}

If the class is to be used by many C++ files one should consider declaring it extern inside a header file and implementing it in a single cpp one. That would save code by avoiding function inlining each time it's used.

Improvements

This is just a basic version to demonstrate how easy and clean code can get. Here are some modifications that will make the class more useful:

  • If there is an RTOS it would be useful to protect this class from concurrent access by using semaphores. It's not a difficult task, a mutex should be declared and initialized (maybe inside a constructor).
  • An interrupt-based uart is nice too, even better if RTOS' messages queues are used. This shouldn't be a problem either.

Tuesday, December 2, 2008

Embedded C++ constructs - Part 1

There has been a big explosion about using C++ within embedded systems. Recently David sent me some interesting papers and info about Embedded C++ so here I present what I've been doing so far (or at least a small portion of it).

Templates

First I have to say that templates are not a code bloat if they're managed with care. In fact the C++ compiler is supposed to optimize them at compile time.

Here are some base templates I've coded to ease pin mapping on the LPC23xx ARM family.



#include "lpc24xx.h" /* LPC23/24xx register definitions */
#include "static_assert.h" /* static assert for non-C++0x compilers */

namespace HW
{
/**
* Output Pin Abstraction
*/
template<unsigned int port, unsigned int pin>
class OutPin
{
STATIC_ASSERT(pin <= 31, PinMustBeLessThan32);

public:
OutPin() {
*(&FIO0DIR + 8*port) |= (1<<pin); //configure pin as output
}
void Set(void) { *(&FIO0SET + 8*port) = (1<<pin);}
void Clr(void) { *(&FIO0CLR + 8*port) = (1<<pin);}
};

/**
* Input Pin Abstraction
*/
template<unsigned int port, unsigned int pin>
class InPin
{
STATIC_ASSERT(pin <= 31, PinMustBeLessThan32);

public:
InPin() {
*(&FIO0DIR + 8*port) &= ~(1<<pin); //configure pin as input
}

operator bool () {
if ( (*(&FIO0PIN + 8*port)) & (1<<pin) )
return true;
else
return false;
}
};
};

This may look a like waste of code at first glance. However these classes avoid many mistakes and provide a hardware independent interface to pin outputs and inputs, it's just a question of redefining this templates to fit the platform.

Also note that the compiler will throw an error if pin's value is not within the allowed range. This is also a protection and won't waste any processor instructions or any other memory. It would be useful to limit the port range too. The above templates use the static assert method described earlier in this post.

The constructors will manage to configure the port pin as output or input. If the pin is defined globally then the constructor will be called before entering the main function, configuring the pin as it should. If it is defined inside a function or by using the new operator (which I would try to avoid)  then the constructor will be called when it is instantiated.

Here is an example:



// Pin 0.25
HW::OutPin< 0,25 > myLed;
// Pin 1.20
HW::InPin< 1,20 > mySwitch;

void invert(void)
{
if ( mySwitch )
myLed.Clr();
else
myLed.Set();
}

Beautiful, isn't it? The generated code (arm-elf-gcc 4.2.x) is exactly the same as if it is done manually by writing/reading the corresponding registers. There is no loss in performance compared to the equivalent C code.

In the next post I will discuss a UART implementation by using similar code constructions.

What I do not like about C++

C++ lacks many useful C99 characteristics and g++ doesn't implement them either. I could live without most of them but what really hurts me is to avoid using Designated Initializers, specially on structs. It won't be a big problem if struct's data is on RAM but it's disappointing when structs are on ROM (const).

If we want a struct to be in ROM while using C++ it has to be declared const, but in addition constructors can't be used or the const-declared struct will be placed in RAM (cRazY). It is an understandable limitation but that means that the only way to initialize a struct is by passing each element one by one and in the exact order as they're defined in the struct. That is error prone, particularly when a new element is added in the middle of the struct. So when we try to switch to C++ to avoid errors we become prone to issues that were solved with C99.

So, that's the only thing I don't like about C++, the solution? Use C for cont struct initializers and C++ for the rest? Don't know.

Compile-time assertions

The new C++0x standard contains a neat feature called static_assert which does a compile-time assertion. It's really useful in cases we can't use the #if keyword (preprocessor) to throw a compile-time error. This happens when the preprocessor finds a C construct or expression it can't resolve such as sizeof, even if it is known at compile-time (actually it's only known to the compiler).

After searching the web I found this webpage that contains a nice trick to do this assertions in C. However, the macros defined there do not provide a description about the assertion, which might be useful, so here is my modified version:


/**
* STATIC ASSERT
* -- based on
* http://www.pixelbeat.org/programming/gcc/static_assert.html
*/
#define ASSERT_CONCAT_(a, b, c) a##b##c
#define ASSERT_CONCAT(a, b, c) ASSERT_CONCAT_(a, b, c)
#define STATIC_ASSERT(e,descr) enum { ASSERT_CONCAT(descr,_Line_,__LINE__) = 1/(!!(e)) }

As an example, this would require the size of the struct myStruct to be less than 20 in order to compile (this is only an example, remember 'magic numbers' should be avoided when programming):



STATIC_ASSERT( sizeof( struct myStruct ) < 20, MyStructIsTooLarge );

If there is an assertion error at compile time this error will be thrown:



file.c:40: error: division by zero
file.c:40: error: enumerator value for 'MyStructIsTooLarge_Line_40' is not an integer constant

On the other side, if C++ is being used and there is access to a (at least partial) C++0x compiler you can use static_assert() in a similar way:



static_assert( sizeof( struct myStruct ) < 20, "My Struct Is Too Large" );


Currently GCC 4.3 supports static_asserts as mentioned here.