EHAL

Embedded Hardware Abstraction Library


It is a library containing codes written in C with C++ wrapper for embedded devices that most MCUs have builtin.   Generally those devices are SPI, I2C, UART, TWI, etc... These are generic code independent of microprocessor architecture that can be ported to any type of microcontrollers.  This is a modern replacement of the arcane BSP (Board Support Package).  The library also contains other high level control code for add-on devices such as the IDM-LMX3208 series LED matrix multi-displays, SD card, etc... 

On second thought.  Initially I wanted to write C code with C++ wrapper.  The more generic code being added the more it is difficult to write it purely in C.  I ended up writing C++ class code in C.  ARM base MCU has begun taking over the low cost MCU realm with more memory resources.  Why should I pull my hairs off trying to support MCU with less resources.   For instant an LPC11Uxx with 64KB Flash, 8KB ram cost almost the same as an AT90USB with 16KB flash, 512 bytes ram.  Even Arduino is C++.  I will start refactoring this library be C++ based.   

One of the most important thing in multi-platform software development is the proper layout of the source tree, the directory tree structure.  The structure layout is simple.  Upper folder contains code generic to all folder under it.  The lower in the tree the more platform specific it is.  Often it is not easy to decide what goes where.  As long we keep in mind this structure the easier to find where things are.  Compiled binaries are always at the lowest level of the directory tree.

Source code on github : https://github.com/I-SYST/EHAL.

/your_root     - Development root directory
 |-- external    - Contains downloaded SDKs from silicon vendors
 |   |-- CMSIS            - ARM CMSIS SDK for all ARM platform (download from ARM)
 |   |-- nRF5_SDK     - Latest Nordic SDK (download from nordicsemi.com)
 |   |-- KSDK             - Kinetis SDK
 |   |......
 |-- EHAL      - Put the EHAL here
 |   |-- include     - Generic include common to all platform
 |   |-- src            - Generic source common to all platform
 |   |-- ARM - Cortex-M series based MCU
 |   |   |-- include    - Common include for all ARM platform
 |   |   |-- src           - Common source for all ARM platform
 |   |   |-- NXP        - NXP ARM platform
 |   |   |   |-- LPC11xx - LPC11xx processor workspace
 |   |   |   |   |-- CMSIS
 |   |   |   |   |-- EHAL     - Embedded Hardware Abstraction Library project for NXP
 |   |   |   |   |   |-- include
 |   |   |   |   |   |-- src
 |   |   |   |   |-- exemples - Example code
 |   |   |   |-- LPC17xx - LPC17xx processor workspace
 |   |   |   |   |-- CMSIS
 |   |   |   |   |-- EHAL     - Embedded Hardware Abstraction Library project for NXP
 |   |   |   |   |   |-- include
 |   |   |   |   |   |-- src
 |   |   |   |   |-- exemples - Example code
 |   |   |-- Nordic
 |   |   |   |-- nRF51 - nRF51 processor workspace
 |   |   |   |   |-- CMSIS   - static library of CMSIS system functions for nRF51
 |   |   |   |   |-- EHAL    - Embedded Hardware Abstraction Library project for Nordic
 |   |   |   |   |   |-- include
 |   |   |   |   |   |-- src
 |   |   |   |   |-- exemples - exemple projects
 |   |   |   |-- nRF52 - nRF52 processor workspace
 |   |   |   |   |-- CMSIS   - static library of CMSIS system functions for nRF52
 |   |   |   |   |-- EHAL    - Embedded Hardware Abstraction Library project for Nordic
 |   |   |   |   |   |-- include
 |   |   |   |   |   |-- src
 |   |   |   |   |-- exemples - exemple projects
 |   |   |-- TI
 |   |   |   |-- CC3200
 |   |   |   |   |-- CMSIS
 |   |   |   |   |-- EHAL
 |   |   |   |   |   |-- include
 |   |   |   |   |   |-- src
 |   |   |   |   |-- exemples - Example code
 |   |   |-- Freescale
 |   |   |   |-- MKL
 |   |   |   |   |-- CMSIS
 |   |   |   |   |-- EHAL
 |   |   |   |   |   |-- include
 |   |   |   |   |   |-- src
 |   |   |   |   |-- exemples - Example code
 |   |...
 |   |-- Linux
 |   |   |...
 |   |-- OSX
 |   |   |...
 |   |-- Win
 |   |   |...
 | ...


ARM CMSIS library


ARM development requires the CMSIS library.  The latest library can be downloaded from https://github.com/ARM-software/CMSIS_5.  Put the library under ARM folder of the development tree as shown above.  All core specifics are reference from the ARM CMSIS SDK.  All chip specifics are referenced to workspace CMSIS library.

Note : Require change to compile CMSIS_RTX with GCC.  There is a compile error about the use of r7 for Cortex-M0 in the file rt_CMSIS.c in function SVC_Call.  Just replace r7 by r6.

Coding practice


Other important things to remember when writing portable code :

- Avoid using conditional compilation as much as possible.  Use library instead.
- Pack all structures accordingly, use #pragma pack(n) or #pragma pack(push, n) / #pragma pack(pop) instead of compiler specific keyword such as __packed or __attribute__((__packed__)).  Those #pragma pack(...) are standard on most compilers long long ago.
- Use stdint types such as uint32_t... instead of some custom types like U32 or UINT32 ... 
- To use standard C++ bool type C, include "stdbool.h"
- Absolute must avoid using macro to define a function or variable.  It is a source of bug that you never expect.  See simple example bellow.  Keep macro strictly to define a constant.

#define min(x, y)     ((x) > (y) ? (y) : (x))

int a =5, b = 6, c;
c = min(5, 6);      // result c = 5, a = 5, b = 6
c = min(a++, b);    // result c = 6, a = 7, b = 6 but the intended result is c = 5, a = 6, b = 6

That is a common macro everyone is doing unconsciously.  Imagine when you put a whole function in a macro like that.   Which I have seen a lot in open source and many big name companies.  C99 has support for inline.  Use it instead to replace the macro.

static inline int min(x, y)   { return x > y ? y : x; }

c = min(a++, b);    // result c = 5, a = 6, b = 6



Generating automatic build number


There is a simple way to generate automatic build number using date.  The follow will work on OS X and Linux only.  It make use of system command date.  When you type date +"%Y%m%d" at the shell it will give a number yyymmdd.  Example 20150210.  The command is date +Format.  To use this.  Open project property, add a preprocessor macro as

BUILDNO=$$(date +"%Y%m%d")

Note : a space between 'date' and '+' is important.

Each time you compile BUILDNO will be defined as the current date.  Use format "%s" if you wish to use number of second elapsed since 1970 instead of current date.


Nordic nRF51/nRF52 requirements

The Nordic SDK needs to be downloaded and put into your workspace.  The SDK must be placed under folder nrf51_sdk.  Download the SDK zip format from nordic,  unzip it, rename it to nrf51_sdk, move it to the folder structured as above.  See nRF51 blog page for more on software development with nRF51 series

Support for TI CC3200  Wifi SoC is progressing well.  See CC3200 Page for details

No specific SDK require for NXP LPC series

Freescale has a big SDK.  Main issue, Flash security settings located at 0x400-0x410 of the code region.  Be careful, bad values in that area will result in processor lockup for good.





No comments:

Post a Comment