Toradex WinCE Libraries' Evolution: The New Library Approach Explained

Tuesday, November 8, 2016

Further information about our libraries including demo application downloads can be found in our developer center.


WindowsOver 10 years ago, we wrote some small pieces of WinCE code in order to demonstrate different features of our computer on modules (CoM), or system on modules (SoM); for example: GPIOs, I2C, Analog Inputs (ADC), etc. With the pure demo purpose in our minds we didn’t pay attention to things like maintenance, compatibility across different modules, etc. However, these demos were used by a huge Windows Embedded Compact customer base. We received more and more support and feature requests which we then started to integrate into the demo code. As a result, we got the library package for our PXA and Tegra® based SoMs as it exists today. These libraries are a reliable and easy way of using our modules. But it wasn’t an easy way to get there with the many maintenance iterations and bending the API to make use of newer features.

When we added newer processors (system on chip or SoC) to our module families, we decided to stop extending our old API and instead design a completely new API wherein we can put all our experience, which we gained over the last years. We called the new library package “Toradex CE Libraries”. The basic goal of the library pack is the same as it was with the older libraries: Make our SoM features easily available for customers.

But we had three very important additional requirements:

  1. Extensible, yet compatible API
  2. Allow library configuration through the registry
  3. Easy maintenance

We were able to fit all three requirements into our new library approach.

Extensible, yet compatible API

To keep our API future-proof, we decided to introduce two sets of API calls. The first one is rather generic and uses strings or integers to pass information to the library. The following example shows how to set a SoM pin to GPIO input and activate a pull-down using the SetConfigString function:

// Set pin to alternate function GPIO, Input with pull-down
    success = Gpio_SetConfigString(hGpio, io1, NULL,
              L"altfn=ioAltFnGpio,dir=in,pull=down", StoreVolatile);

Another example uses the SetConfigInt function to set the bit rate of the I2C controller to 400KHz:

// Set I2C speed to 400KHz
    success = I2c_SetConfigInt(i2c, L"BitRateHz", 400000,

Using this generic string approach allows us to keep the API 100% compatible also in the future if we need to add more features which aren’t available on today’s SoMs.

The second set of API calls is used for either performance reasons or standard functions. Here is an example for the GPIO library function which allows to modify a GPIO. The same could be done using SetConfigString or Set ConfigInt, but for performance reasons we provide functions which don’t require to parse strings:

// Set it to Output,  High
    Gpio_ConfigureAsGpio(hGpio, io1);
    Gpio_SetDir         (hGpio, io1, ioOutput);
    Gpio_SetLevel       (hGpio, io1, ioHigh);

As an example for standard functions we can look at an I2C read. We decided to not use the more generic string approach (Get/SetConfig as shown above) for performance reasons, but also because I2C read (and similar functions) are fixed and not expected to change for future SoCs:

    returnValue = I2c_Read(i2c, (DWORD*) data, 8);
Allow library configuration through the registry

As you saw earlier, we allow to configure our libraries through strings and integers. It is for example possible to setup the SPI library to use a certain SPI port, chip selects, baud rate, etc. in the registry and just load the settings from there at your application start. If you initialize the library with the following call:

    hSPI = Spi_Init(L"SPI2");

the library will automatically load the settings found in the registry under:


You might wonder which benefits this brings. Well, one very nice advantage of this approach is to be able to maintain only one application on different devices, e.g. you can use the same application on a SoM based on the NXP® (or should I write Qualcomm) i.MX6 SoC but also on an NXP Vybrid-based SoM. The only difference between these modules is the pin configuration which can be stored in the registry now. The rest is absolutely identical and therefore allows you to use one single binary application for different SoMs which makes your life easier.

Easy Maintenance

The last Toradex CE Libraries feature which I would like to highlight in this post is the “designed for maintenance” aspect. For an easy and risk-free maintenance on our side, we split the libraries into individual source code files per SoC. This ensures we can fix bugs or add SoC-specific features without touching other SoC’s code. This lowers the risk of breaking existing code and therefore makes our software offerings more robust and stable overall.

AuthorRoman Schnarwiler, CTO, Toradex AG

Subscribe to our future Blog posts:

Leave a comment

Your email ID will be kept confidential. Required fields are marked *

Click to change the Code

Please enter the letters as they are shown in the image above. Letters are not case-sensitive.

* Your comment will be reviewed and then added. Thank you.