Why do I need to port in the first place?Arduino is many things but goal that is attempted with the project and not always accomplished is to abstract out the specific details of the Atmel microcontroller used on these boards. Abstracting out the microcontroller has a specific consequence of allowing a beginner to not have to dig in to the details of how the chip works to get a project up and running. It also has an unintended consequence of making the specific microcontroller that is used to implement a solution less relevant. Although the API (Application programmers Interface) for the Arduino is quite abstracted, some specific details within a library may not utilize these abstractions and talk directly to the chip. This can happen for several reasons. One, maybe there is no abstraction for the library writer to leverage. Two, it is difficult to use libraries within libraries in the Arduino environment (though work is on its way to resolve this). Three, there are some specific limitations of the Atmel chips that prevent “standard” C calls from being used, when this happens specific workarounds have been used. Four, C datatypes are not always consistent between compilers.
Porting TipsWhen starting with a working Arduino library that you want to port to chipKIT you should have in mind the goal to keep it working on Arduino while adding chipKIT functionality. One way to do this is to make use of compiler preprocessor directives such as #ifdef to conditionally compiler for the currently selected target platform. There is detailed information on how to do this the Programming hints page.
Atmel Specific CodeWhen Atmel registers are used, as mentioned above, try to convert to abstractions. If this is not possible use #ifdef’s to switch between Arduino and chipKIT. For example:
#if defined(__AVR__) /* Atmel-specific code goes here */ #endif #if defined(__PIC32MX__) /* chipKIT-specific code goes here */ #endif
Compiler WorkaroundsThe Atmel compiler uses some tricks for storing literal strings in program space that need to be converted to a standard C to work on chipKIT. Again, use of #ifdefs is a good way to do this. For example:
#if defined(__AVR__) /* Atmel-specific code goes here */ #else /* standard C code goes here */ #endif
C/C++ datatypesThe C/C++ programming language can be quite portable with a major exception. The size of a datatype in one compiler may not be the same a s datatype in another compiler. This is especially true when one complier is for an 8-bit architecture such as is used with Arduino Atmel chips and the other is a 32-bit architecture as is used in chipKIT PIC32 chips. For example, an int on a Atmel complier may be 16-bits and an int on a PIC32 may be 32-bits, so when an Atmel library is used on a PIC32 that relies on a int overflowing at a specific value the library will fail because of the larger storage type on the PIC32. One way to solve this problem is to use the stdint.h include that has types that call out a specific storage capacity such as the following: uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t. Example needed.
VN:F [1.9.22_1171]Tips on porting Arduino libraries,