What are CMSIS software components?

The Cortex Microcontroller Software Interface Standard (CMSIS) is a vendor-independent hardware abstraction layer for Arm Cortex-M and Cortex-A processors and defines generic tool interfaces.   

The CMSIS-Pack standard specifies a delivery mechanism for device support and software components. The CMSIS-Pack system is now implemented in several leading development toolkits such as:

The ability to distribute software components makes CMSIS-Packs attractive for software platform providers. The following will focus on the benefits of CMSIS specifically for software components.

Benefits of software components

Well-defined software components, such as an RTOS, networking stack, driver interfaces, or DSP algorithms, are building blocks for user applications that significantly reduce the effort for software developers.

When directly using the source code of a software component in the user application, the maintenance of a product becomes difficult. Frequently, the initial source of that component is unclear, information about the related files, configuration settings, or original documentation is lost.

The CMSIS-Pack system solves several typical user problems: 

  • It provides meta-data of files that relate to a software component. Even after years, all files that belong to a software component can be identified and information about the original provider is preserved. 
  • It makes it easy to upgrade a software component and even identifies incompatible configuration files that may be part of the user application. 
  • It forces the provider of a software component to clearly specify the interfaces and relationship to other software components.
  • The meta-data of a software component can include dependency information for toolchains, devices, and processors which simplifies the integration into application programs. 

The integration of the CMSIS-Pack system into various IDEs simplifies the usage of software components. Generic software components can therefore gain a wider adoption.

Structure of a CMSIS software component 

A software component encapsulates a set of related functions. For bare-metal microcontroller development C/C++ is the de-facto language of choice. However, software components can also contain object code, assembler files, header files, or libraries. The interfaces of software components should be defined with API headers to make them substitutable by other compatible components at design time.

Software component contents

In addition, CMSIS software components should contain documentation for the software component. They may provide user code templates that give a starting point for the application developer, and can have optional debug view descriptions for debuggers. 

CMSIS software components can also refer to multiple interfaces of other software components. This could be also a hardware abstraction layer for a device peripheral. 

Configuration files contain application specific parameters for a software component. These files are typically copied to the user project workspace; all other files are not modified by the user and can remain in a separate location which avoids that a project workspace is polluted by many source files that should be considered as “black-box” elements by the application programmer.

Taxonomy 

To reference software components, CMSIS specifies naming conventions that have the following elements: 

  • Cclass: A component class which is a top-level component name, for example CMSIS, Device, FileSystem. There are several established Cclass names which may be used for certain type of software components. 
  • Cgroup: A component group name, for example CMSIS:RTOS, Device:Startup, RTOS:Heap 
  • Cversion: The version number of the software component. 

Optionally, a software component may have additional attributes: 

  • Csub: A component sub-group that is used when multiple compatible implementations of a component are be available. For example Driver:Flash:S29GL064Nx2, Driver:Flash:AT45DB642D. Sub-groups allow to use multiple different component implementations in the same project (for example two different Flash devices with the same interface can be in the same project).
  • Cvariant: a variant of the software component is typically used when the same implementation has multiple top-level configurations, like debug and release.
  • Cvendor: the supplier of the software component.
  • Cbundle: allows to combine multiple software components into a software bundle. For example if a network stack is used, all interfaces must match to that component.
  • Instances: allow to deploy multiple instances of a software component. Each instance can have a separate configuration file.

References to other software components

Software components can reference other software components using conditions which is illustrated in this diagram:

Component using conditions

A condition describes dependencies on device, processor, and tool attributes as well as the presence of other components. The condition can be used to ensure that specific software components are either present in the system or can prevent that illegal combinations of software components are chosen by the user. 

Central API interface definition 

A common problem of the software industry: API headers that are defined for a software component evolve over time, but the various implementations that consume these interfaces continue to use outdated header files, which frequently causes inconsistencies when drivers are independently developed. 

The CMSIS-Pack system allows therefore a central API definition that shares header file and documentation of an API interface.

Component APIs

This single API interface definition ensures consistency when it is used across multiple implementations that consume the interface. The API interface definition can be distributed separately or as part of the software component that consumes this interface. 

An example is the CMSIS-Driver pack that contains various Ethernet and Flash drivers – all compatible with the CMSIS-Driver APIs that are published in the CMSIS Pack.

Using software components in IDEs

Many software developers rely on an IDE for project creation and management. All popular IDEs support today the CMSIS-Pack concept and offer functionality to build projects using software components efficiently.

Add software components

For example, the IDEs use the component conditions to refer other required software components for the project:

Manage run-time environment

In this example, we selected a USB software component that requires that for example a real-time operating system is present. The Validation Output highlights during component selection such required software components and even suggests possible selections. During set up of the application specific run-time environment, this ensures that requirements are met. The software developer can then concentrate on the actual application development.

User code templates

Software components can refer the related code templates that help application developers to get started with the application development. To use a code template, just right-click the project and select to add a code template:

New file from CMSIS template

In the following dialog, select the user code template that you wish to use:

Select template

Access to documentation

IDEs using the meta-data from the XML description, make it easy to access documentation that is specific for the component version that you are using. Simply click on the link that is shown in the run-time environment manager:

Access documentation

Working with configuration files

Configuration files are commonly used to set certain parameters of a software component. Often, configuration files are complex, with too many #define statements. Using simple source code annotations for the Configuration Wizard, you can create a meaningful user interface. IDEs read the annotated file and display it in a user friendly way:

Configuration wizard view

Update configuration files

When you update a software component, the IDE makes you aware of potentially outdated configuration files for a software component. In this example, the USBD_Config_0.c file should be updated (marked by the yellow file icon). You can either update the file directly or use your favorite merge tool to examine the differences between the configuration file versions.

Merge conflicts

Central inventory header file: RTE_Components.h

Frequently, the behaviour or features of a software component depend on the presence of other software components in the system. For example, a network stack can interface to Ethernet or serial PPP (UART). Depending on the presence of interface components, the implementation may behave differently.

To simplify application configuration, the file RTE_Components.h is generated before the project build step and contains the inventory of all selected components. For each selected software component, it contains #define statements that are specified by the component meta data. The following example shows a sample RTE_Components.h file:

/* 
   Auto generated Run-Time-Environment Component Configuration File 
        *** Do not modify ! *** 
*/ 

#ifndef RTE_COMPONENTS_H 
#define RTE_COMPONENTS_H 

/* 
   Define the Device Header File: 
*/ 

#define CMSIS_device_header "stm32f10x.h" 

#define RTE_Network_Interface_ETH_0     /* Network Interface ETH 0 */ 
#define RTE_Network_Socket_BSD          /* Network Socket BSD */ 
#define RTE_Network_Socket_TCP          /* Network Socket TCP */ 
#define RTE_Network_Socket_UDP          /* Network Socket UDP */ 

#endif /* RTE_COMPONENTS_H */

The typical usage of the RTE_Components.h file is in header files to control features that depend on the inclusion to other software components. For example:

#include "RTE_Components.h" 
#ifdef  RTE_Network_Interface_ETH_0  // if component is included 
#include "Net_Config_ETH_0.h"        // add related configuration file 
#endif 

Combining software components

When using software components, you can use the conditions to automatically resolve dependencies on other components, as we have seen. You can use this to combine components for one project in a certain way while combining them differently for another project. In the following example, we are using a network stack to transfer data via Ethernet. The network stack requires a MAC and PHY to do this. The selected device from silicon vendor A that contains an on-chip MAC, thus only requiring a PHY to be selected:

Combined components for vendor A

You can copy the project, select a different device from silicon vendor B for example and let the run-time environment manager do the exchange of the components. As the new devices doe not have an on-chip MAC, you need to select a different component to fulfill the requirement for the network stack:

Combined components for vendor B

This reduces the development time drastically, as the developer does not need to care for the correct dependency between software components, but can concentrate on the implementation of his own application code.

Creating software components

Creating a CMSIS-Pack containing software components is an easy task. All you need to do is to follow these steps:

  1. Define the component: specify the overall component structure and the interfaces of the components. This is important for the taxonomy and the conditions that are described above. 
  2. Create the component: develop the source code, libraries, documentation, and configuration files of the component.
  3. Organize files: framing software components does not have specific requirements on directory structure, but it is advised to structure it in different directories. 
  4. Create PDSC file: the XML meta data can be created using any text editor, but some editors validate XML against a schema file which helps to avoid mistakes
  5. Use local repositories: several IDEs support pack development with local repositories. This makes it easy to iterate on steps 1 - 4 without the necessity to rebuild a pack all the time.

Release software components as Software Pack

The CMSIS-Pack concept also specifies a release mechanism that simplifies the integration of software components into complex applications. To release software components as a pack follow these steps:

  1. Create Software Pack: software components can be released as software pack (a ZIP file with PDSC meta data) which simplifies installation and the product life cycle management for users of the component.
  2. Publish Software Pack: there are multiple ways to distribute a software pack. An index file for a web portal makes your software component accessible via the CMSIS Pack Manager that is part of the IDEs.

The CMSIS-Pack documentation on GitHub explains the details and contains a step-by-step tutorial.

Summary

CMSIS-Packs containing software components ease the life of the developer. Many tedious tasks when working with components are automatically taken care for by the IDE using the mechanisms that are built-in into a pack. Required changes in the project when switching from one component revision to another or from one device to another are flagged by the component manager and demand only little attention. Portability of the overall code increases and time-to-market is reduced. Using APIs, software component providers can ensure that their components work in different software and hardware environments and can extend the reach of their component dramatically.

More about CMSIS-Pack

Anonymous