Synergy Software Package User's Manual
SSP Overview

Table of Contents

SSP Overview

ssp-detail.png

 

Learn how to develop applications with the Synergy Software Package (SSP) using the SSP's module-based architecture and the functional software layers. Integrate SSP applications with multiple boards and Synergy devices using the Board Support Package (BSP).

The following pages describe the fundamental SSP architecture:

Introduction

Purpose

The Renesas Synergy™ Software Package (SSP), part of the Renesas Synergy™ Platform, is a complete integrated software package designed to provide easy to use, scalable, high quality software for embedded system design. Using the Synergy Software Platform will reduce time to market by providing a completely integrated and qualified embedded software platform comprising of an industry leading, completely optimized and hardened Real-time Operating System (RTOS), middleware, communication stacks, function libraries, application framework and hardware abstracted low-level device drivers.

Overview

The SSP is divided into four main layers:

  • Framework Interfaces The Framework Library connects to Synergy hardware peripherals through common Interfaces, which abstract the hardware into functional use cases. The Interface layer is a group of header files with definitions of functions and parameters, so it consumes no code space.
  • Framework Layer The Framework layer consists of RTOS integrated drivers and valuable application code.
  • HAL Interfaces HAL layer Interfaces connect to RTOS-independent HAL-level drivers.
  • HAL Layer The HAL layer drivers with hardware registers implement Interfaces.

Ease of Use

The SSP provides uniform and intuitive APIs that are well documented. Each module is supported with detailed user documentation and software datasheet including code size and execution time for each function.

Scalability

Users have the choice to integrate with the platform capabilities using either the Framework Interface or HAL layer, depending on which best meets the needs of the application. To further scale each module, build time options such as parameter checking may be compiled out for smaller, more efficient code.

SSP Architecture

                                                                       

Renesas Synergy Software Package (SSP) Architecture

This section describes the Renesas Synergy Software Package (SSP) architecture and how to use the SSP Application Programming Interface (API).

Introduction to the SSP

As microcontrollers increase in complexity, so does the breadth of knowledge required to make them operate in the desired way. The SSP provides an innovative approach to embedded software for IoT applications. With the SSP, you have a new and extremely powerful software interface from the ground up, making coding fast and providing you with a robust development processes. With this software, you can create differentiated application code instead of spending months developing baseline code to interface at the hardware level.

SSP Terms

Term Description Reference
Module Modules can be peripheral drivers, purely software, or anything in between. Each Module consists of a folder with source code, documentation, and anything else that the customer needs to use the code effectively. Modules are independent units, but they may depend on other Modules. Example SSP Modules are the UART driver (UART Interface), Audio Playback Framework, which relies on timer, DMA, and DAC drivers (Audio Framework Interface), or the Messaging Framework (Messaging Framework Interface). Applications can be built by combining multiple modules to provide the user with the features they need. SSP Modules                  
BSP Short for Board Support Package. In the SSP the BSP provides just enough foundation to allow other SSP modules to work together without issue. BSP Architecture
Callback Function This term refers to a function that is called when an event occurs. For example, the bus error interrupt handler is implemented in the r_bsp. The user will likely want to know when a bus error occurs. To alert the user, a callback function can be supplied to the r_bsp. When a bus error occurs the r_bsp will jump to the provided callback function and the user can handle the error. Interrupt callback functions should be kept short and be handled carefully because when they are called the MCU will still be inside of an interrupt and therefore will be delaying any pending interrupts. -
Interface See SSP Interfaces section: SSP Interfaces. All interfaces in the SSP are listed here: Framework Interfaces and HAL Interfaces SSP Interfaces
Instance See SSP Instances section: SSP Instances SSP Instances
Module Instance Single and independent configuration of a Module. -
Application Code that is owned and maintained by the user. Application code may be based off sample application code provided by Renesas, but is the responsibility of the user. An example for a simple application is included as tutorial in this manual: ref application-wdt
Driver A Driver is a specific kind of Module that directly modifies registers on the MCU. -
Stacks The SSP architecture is designed such that Modules work together to form a Stack. Starting with the uppermost Module and going to the bottommost dependency forms a specific Stack. SSP Stacks
Layer/Level Stacks are made of multiple layers of Modules. A Layer can consist of one or multiple Modules depending on the requirements of the next Layer up. Layer and Level are used interchangeably. ref ssp-predefined-layers

SSP Modules

Modules are the core building block of SSP. Modules can do many different things, but all Modules share the basic concept of providing functionality upwards and requiring functionality from below.

 

figure-ssp-architecture-image1.png
Modules

The amount of functionality provided by a Module is not limited though there are usually points where separation makes sense. If too much functionality is provided, then reuse of the Module can become difficult in the future. If not enough functionality is provided, then unnecessary complexity and overhead may be added in order to make the Modules work as expected.

The simplest SSP application consists of one Module with the user application on top.  

figure-ssp-architecture-image2.png
Module with application

 

For simplicity, ignore the Board Support Package (BSP) for now because it is a requirement of any SSP project. In the picture above, the BSP is located underneath the bottom layer, SSP Layer 0.

SSP Stacks

When modules are layered atop one another, an SSP stack is formed. The stacking process is performed by matching what one module provides with what another module requires. For example, the Audio Playback Framework Module requires a Transfer Interface, which can be fulfilled by the Data Transfer Controller (DTC) Driver Module. Instead of including the DTC code in the Audio Playback Module, we split these into two modules. This allows for reuse of the underlying modules, which has many benefits.

figure-ssp-architecture-image3.png
Stacks – Audio playback

By continuing to add layers to the Stack using SSP Modules, you can interface with the Synergy hardware at a high level.

 

figure-ssp-architecture-image4.png
Stacks

The ability to stack modules has great benefit because it ensures the flexibility of the architecture as a whole. If modules are directly dependent upon other modules, then issues arise when application features must work across different user designs. To ensure that modules are reusable the modules must be capable of being swapped out for other modules that provide the same features. The SSP architecture provides this flexibility to swap modules in and out through the use of SSP Interfaces.

SSP Interfaces

At the architecture level, Interfaces are the way that Modules provide common features. This commonality allows Modules that adhere to the same Interface to be used interchangeably. Interfaces can be thought of as a contract between two Modules. The Modules agree to work together using the information that was agreed upon in the contract.                                                                                                                                                     

On Synergy hardware there is occasionally an overlap of features between different peripherals. For example, I2C communications can be achieved through use of the IIC peripheral or the SCI peripheral in its Simple I2C mode. There is a difference in the level of features provided by both peripherals. In I2C mode the SCI peripheral will only support a subset of the features of the full-featured IIC.  

Interfaces aim to provide support for the common features that most users would expect. This means that some of the advanced features of a peripheral, such as the IIC, might not be available in the Interface. In most cases these features are still available through Interface Extensions.  

In design, Interfaces are implemented as header files. All Interface header filenames end with '_api.h'. The following sections detail what makes up an Interface.                                                                                            

SSP Interface Enumerations

Whenever possible, Interfaces use typed enumerations for function parameters and structure members.

typedef enum e_i2c_addr_mode
{
     I2C_ADDR_MODE_7BIT = 1, // Use 7-bit addressing mode
     I2C_ADDR_MODE_10BIT // Use 10-bit addressing mode

Enumerations remove any uncertainty when deciding what values are available for a parameter. Also note that enumeration options follow a strict naming convention where the name of the type is prefixed on the available options. Combining the naming convention with the autocomplete feature available in e2 studio provides the benefits of rapid coding while maintaining highly readable code.

SSP Interface Data Structures

At a minimum, all SSP Interfaces include three data structures: a control structure, a configuration structure, and an instance structure.

The control structure is used as a unique identifier for using the module. If SSP modules were only peripheral drivers then this control structure might be replaced with a channel number. All function calls for that module would then take a channel number so that the code could determine which peripheral channel to operate on. SSP modules are not restricted to device drivers and therefore the control structure is used. The user allocates storage for a control structure and then sends a pointer to it into the open() call for a Module. At this point, the Module initializes the structure as needed. You must then send in a pointer to the control structure for all subsequent module calls. The contents of the control structure are used by the module and must not be altered. Reading data from a control structure should also be avoided as the data structure is not guaranteed to remain the same between SSP releases. In general, you should treat control structures like a black box.

The contents of a control structure are specific to an instance. This means that two instances of the same interface will have two completely different control structure types. The control structures that exist in an interface are named <interface>_ctrl_t. Below is an example of the interface control structure for I2C:

 

typedef void i2c_ctrl_t;

Since all interface control structures are of type void, they cannot be allocated. Instead, these types are placeholders for instance control structures. Instance control structures are defined in instance header files and are named <instance>_instance_ctrl_t. Below are examples of I2C Instance control structures for the IIC (r_riic) and SCI (r_sci_i2c) peripherals:

 

/* riic Instance control structure to be used with I2C Interface. */
typedef struct st_riic_instance_ctrl
{
    i2c_cfg_t info; // Information describing I2C device
    uint32_t open; // Flag to determine if the device is open
    void * p_reg; // Base register for this channel
 
/* sci_i2c Instance control structure to be used with I2C Interface. */
typedef struct st_sci_i2c_instance_ctrl
{
    i2c_cfg_t info; // Information describing I2C device
    uint32_t open; // Flag to determine if the device is open
    void * p_reg; // Base register for this channel
 /* More members specific to sci_i2c Instance. */

When using an interface, the instance control structure should be allocated and used in place of the interface control structure. Using the example above, if the SCI-I2C Instance was being used then you would allocate a structure of type sci_i2c_instance_ctrl_t and use it wherever i2c_ctrl_t is referenced in the Interface. The ISDE will take care of allocating the correct control structure for you.

 

Dynamic memory allocation through use of the malloc() and free() functions are not used in SSP modules.

The configuration structure is used for the initial configuration of a module during the open() call. The structure consists of members such as: channel, interrupt priority, bitrate, and operating mode. The structure is used purely for input into the module. This structure does not have to be unique and could be discarded by you after initialization, if desired.

typedef struct st_i2c_cfg
{
    /* Generic configuration */
    uint8_t         channel;                                    // Identifier recognizable by implementation
    i2c_rate_t      rate;                                       // Device's maximum clock rate from enum i2c_rate_t
    uint16_t        slave;                                      // The address of the slave device
    i2c_addr_mode_t addr_mode;                                  // Indicates how slave fields should be interpreted
    uint16_t        sda_delay;                                  // The SDA output delay
    uint8_t         rxi_ipl;                                    // Receive interrupt priority
    uint8_t         txi_ipl;                                    // Transmit interrupt priority
    uint8_t         tei_ipl;                                    // Transmit end interrupt priority
    uint8_t         eri_ipl;                                    // Error interrupt priority
   
    /* DTC/DMA support */
    transfer_instance_t const * p_transfer_tx;             // DTC instance for I2C transmit.Set to NULL if unused.
    transfer_instance_t const * p_transfer_rx;             // DTC instance for I2C receive. Set to NULL if unused.
   
    /* Parameters to control software behavior */
    void         (* p_callback)(i2c_callback_args_t * p_args);  // Pointer to callback function
    void const    * p_context;                                  // Pointer to the user-provided context
   
    /* Implementation-specific configuration */
    void const    * p_extend;                                   // Any configuration data needed by the hardware

Above is an example configuration structure for the I2C Interface. The last three structure members (p_callback, p_context, and p_extend) are common to almost all module configurations.

The p_callback and p_context members are described in the SSP Interface Callback Functions section.

The p_extend member is used for extending the current Interface for a specific Instance. Interfaces are designed to support the most common features. There are cases where an Instance of an Interface requires extra information to properly configure itself. There are also cases where the extra information is not required, but users might need it to adjust the module for their specific application. When this is the case, the user can provide the underlying Instance with more configuration information by passing it through the p_extend member. The information that is passed through this member is defined by the underlying Instance, and therefore the user must adhere to its structure. If invalid information is passed to the underlying driver, then the Instance is not able to successfully use the data and proper operation cannot be guaranteed. Refer to the Interface Extensions section for more information. 

It is also important that configuration structures only have members that apply to the current Interface. If multiple layers in the same stack define the same configuration parameters then it becomes difficult to know where to modify the option. For example, the baud rate for a UART is only be defined at the Driver layer. Any layers that use the UART Interface rely on the baud rate being provided at the Driver layer and do not offer it in their own configuration structures.

SSP Interface Callback Functions

Callback functions allow Modules to asynchronously alert the user application when an event has occurred. An example for an event is when a byte has been received over a UART channel. Callbacks are required to allow user application code to react to interrupts. SSP Modules define and handle the interrupts for Synergy MCU peripherals. If the user tries to define the interrupt service routine at the same time as a SSP Module, then the code does not build. Therefore SSP Modules allow the user application to respond to interrupts by registering a function to be called when an interrupt occurs. 

 

Callback functions must be defined in the user application. They always return void and take a structure for their one parameter. The structure typedef is provided in the Interface for the Module and is named * _callback_args_t*. The contents of the structure may vary depending on the Interface, but two members are common: event and p_context.

The event member is used by the application to determine why the callback was called. Using the UART example again, the callback could have been triggered because a byte was received, all bytes had been transmitted, or a framing error has occurred. The event member is an enumeration provided by the Interface.

The p_context member is used for providing user-specified data to the callback function. In many cases a callback function is shared between multiple channels or Module Instances. When the callback occurs, the code handling the callback needs context information so that it can figure out which Module Instance the callback is for. For example, if the callback wanted to make a SSP API call in the callback, then at a minimum the callback must use the control structure. To make this easy, the user can provide a pointer to the control structure as the p_context. When the callback occurs, the control structure is available as it will be passed in the callback structure.

Callback functions are called from within an interrupt service routine. For this reason callback functions should be kept as short as possible so they do not affect the real time performance of the user's system. An example skeleton function for the Flash Interface callback is shown below.

static void flash_callback (flash_callback_args_t * p_args)
{
    /* See what event caused this callback. */
switch (p_args-&gt;event)
    {
        case FLASH_EVENT_ERASE_COMPLETE:
        /* Handle event. */
        break;
        case FLASH_EVENT_WRITE_COMPLETE:
        /* Handle event. */
        break;
        case FLASH_EVENT_BLANK:
        /* Handle event. */
        break;
        case FLASH_EVENT_NOT_BLANK:
        /* Handle event. */
        break;
        case FLASH_EVENT_ERR_DF_ACCESS:
        /* Handle error. */
        break;
        case FLASH_EVENT_ERR_CF_ACCESS:
        /* Handle error. */
        break;
        case FLASH_EVENT_ERR_CMD_LOCKED:
        /* Handle error. */
        break;
    }
}

When a Module is not directly used in the user application (it is not the top layer of the stack) then its callback function will be handled by the Module above. If there is a Console Interface Module that requires a UART Interface Module then the Console Module will control and use the UART's callback function. In this case the user does not need to create a callback function for the UART Module in their application code.

SSP Interface API Structure

All Interfaces include an API structure which contains function pointers for all the supported Interface functions. An example structure, with the comments removed, for the Digital to Analog Convert (DAC) is shown below. 

                                                                                            

typedef struct st_dac_api
{
    ssp_err_t (* open)(dac_ctrl_t * p_ctrl, dac_cfg_t const * const p_cfg);
    ssp_err_t (* close)(dac_ctrl_t * p_ctrl);
    ssp_err_t (* write)(dac_ctrl_t * p_ctrl, dac_size_t * p_value);
    ssp_err_t (* start)(dac_ctrl_t * p_ctrl);
    ssp_err_t (* stop)(dac_ctrl_t * p_ctrl);
    ssp_err_t (* versionGet)(ssp_version_t * p_version);

The API structure is what allows for Modules to easily be swapped in and out for other Modules that are Instances of the same Interface. Let's look at an example application using the DAC Interface above.

Synergy MCUs have an internal DAC peripheral. If the DAC API structure in the DAC Interface were not used, then the application could make calls directly into the module. In the example below the application is making calls to the R_DAC_Write function which is provided in the r_dac module.

figure-ssp-architecture-image5.png
DAC Write example

 

Now let's assume that the user needs more DAC channels than are available on the MCU by adding a new external DAC module named r_dac_external. The external DAC uses I2C for communications. The application must now distinguish between the two modules, which adds complexity and further dependencies to the application.                                                             

figure-ssp-architecture-image6.png
DAC Write with two write modules

 

The use of Interfaces and the API structure allows for the use of an abstracted DAC. This means that no extra logic is needed and the application no longer depends upon certain hard-coded Modules. Instead the application now depends on the DAC Interface API which can be implemented by any number of Modules.  

figure-ssp-architecture-image7.png
DAC Interface

 

Functions inside of the API structures follow common names. Most Modules will have a pair of open() and close functions. The open() function must be called before any of the other functions. The only exception is the versionGet() function which is not dependent upon any user provided information.

Other functions that will commonly be found are read(), write(), get(), and set(). Function names are designed to be a noun followed by a verb. Example names include:                                                                                  

  • read(), write(), writeRead()
  • statusGet()
  • calendarAlarmSet(), calendarAlarmGet()
  • accessWindowSet(), accessWindowClear()

SSP Interface Version Information

All Interfaces supply a versionGet() function. This function fills in a structure of type ssp_version_t. This structure is made up of two versions: one for the Interface (the API) and one for the underlying Instance that is currently being used.

/* Common version structure */
typedef union st_ssp_version
{
    /* Version id */
    uint32_t version_id;
    /* Code version parameters */
    struct
    {
        uint8_t code_version_major; //  Code major version
        uint8_t code_version_minor; // Code minor version
        uint8_t api_version_major; // API major version
        uint8_t api_version_minor; // API minor version
    };
 

The API version ideally never changes, and only rarely if it does. A change to the API may require users to go back and modify their code. The code version, the version of the current Instance, may be updated more frequently. Bug fixes, enhancements, and additional features may all bump the code version. Changes to the code version will only require changes to the user code if the user code is using extended features provided by the Instance.

SSP Instances

While Interfaces dictate the features that are provided, Instances actually implement those features. Each Instance is tied to a specific Interface. Instances use the enumerations, data structures, and API prototypes from the Interface. This allows for an application that uses an Interface to swap out the Instance when needed.                                                                                                                         

On Synergy MCUs some peripherals will have a one-to-one mapping between the Interface and Instance, while others will have a one-to-many. In the example below the IIC and SPI peripherals map to only one Interface each while the SCI peripheral implements three Interfaces.

 

figure-ssp-architecture-image8.png
Instances

SSP Instances API Structure

Each Instance includes a constant global structure with its functions that implement the Interface's API. The name of this structure is standardized as g__on_. Examples include g_spi_on_spi, g_transfer_on_dtc, and g_adc_on_adc. This structure is available to be used through an extern in the instances header file (r_spi.h, r_dtc.h, and r_adc.h respectively).

Build Time Configuration

All modules have a build-time configuration header file. Most configuration options are supplied at run time. Some options that are rarely used, or apply to all instances of a module, may be moved to build time. The advantage of using a build-time configuration option is to potentially reduce code size reduction by removing an unused feature. Performance enhancements are also possible.                                                                                      All modules have at least one build time option, which is whether to enable or disable parameter checking for the module. SSP modules check function arguments for validity when possible. You may want to disable this feature when your testing has concluded to save code space and to speed up execution.

Interface Extensions

In some cases, Instances require more information than is provided in the Interface. This situation can occur in the following two cases:

  • An Instance offers extra features that are not common to most Instances of the Interface.
  • An Interface must be very generic out of necessity. As an Interface becomes more generic, the number of possible Instances increases. A prime example of this is the Block Media Interface.
typedef struct st_sf_block_media_cfg
{
    uint32_t block_size; // Block size in bytes
    void * p_extend; // Instance dependent configuration

The configuration structure for the Block Media Interface is intentionally sparse. This allows for nearly endless Instances. Possible Instances include SD card, SPI Flash, SDRAM, USB, and many more. Different configuration information is needed for each Instance. This is accomplished by supplying the information through the p_extend parameter. While the configuration data provided in the p_extend is not the same between Instances, the API calls thereafter will be. This means that the change is only required in one place.                                                                                                                                                   

Use of Interface extensions is not always necessary. Some Instances do not offer an extension since all functionality is provided in the Interface. In many cases the p_extend member can be set to NULL. If NULL is provided and the Instance does offer an extension then the Instance will take this to mean that the default options should be used. The documentation for each Instance indicates whether an Interface extension is provided and whether its use is mandatory or optional.

SSP Predefined Layers

 

The SSP comes with two predefined layers: the Driver layer and the Framework layer. The layers are easily identifiable because the modules reside in different folders and have different prefixes. Driver layer modules are located in the ssp/src/driver folder, while Framework level modules are located in the ssp/src/framework folder. Modules in the Driver layer start with an r_ prefix, while Framework level modules start with a sf_ prefix.                                                                                                

The core difference in the functionality between the layers is that Driver layer modules are restricted to being peripheral drivers that are RTOS aware, but do not use any RTOS objects or make any RTOS API calls. This means that Driver layer modules can be used in applications with, or without, an RTOS.

Framework layer modules are free to use RTOS objects such as semaphores, mutexes, or event flags. Framework modules may also create their own when needed. Framework layer modules that need to access hardware typically do so through a Driver layer Interface. Exceptions can be granted in special cases where multiple peripherals need to be used together in a way that would not be practical through multiple individual Interfaces.

SSP File Structure

The high-level file structure of the SSP is shown below.

ssp
+---inc
\|     +---bsp
\|     \|    +---cmsis
\|     +---driver
\|     \|     +---api
\|     \|      \\---instances
\|     \\---framework
\|          +---api
\|          +---el
\|          +---instances
\|           \\---tes
---src
   +---bsp
   \|     +---cmsis
   \|      \\---mcu
  +---driver
   \|    \\---r_module
   \\---framework
        \\---sf_module
synergy_cfg
+---ssp_cfg
      +---bsp
      +---driver
      \\---framework
}

Directly underneath the base ssp folder the folders are split into the source and include folders. Include folders are kept separate from the source for easy browsing and easy setup of include paths. The same set of folders are located in the ssp/inc and ssp/src folders: bsp, driver, and framework.

Apart from the BSP, the SSP's two predefined layers, Driver and Framework, are present. Driver layer modules are located in the ssp/src/driver folder and Framework layer modules are located in ssp/src/framework. Under the include tree, the Driver and Framework layer folders contain two folders each: api and instances. The api folder contains the Interface header files for that layer. The instances folder contains the Instance header files for that layer. Both layers are flat internally which limits the number of include paths required for a project.                                                          

The ssp_cfg folder is where configuration header files are stored for each module. Its layout is the same as the ssp folder where the BSP, Driver, and Framework layers have separate flat directories. See the Build Time Configuration section for information on what is provided in these header files.

SSP Connecting Layers

SSP modules are meant to be both reusable and stackable. It is important to remember that modules are not dependent upon other modules, but upon other Interfaces. The user is then free to fulfill the Interface using the Instance that best fits their needs.

 

figure-ssp-architecture-image9.png
Connecting layers

 

In the image above Interface Y is a dependency of Interface X and has its own dependency on Interface Z. Interface X only has a dependency on Interface Y. Interface X has no knowledge of Interface Z. This is a requirement for ensuring that layers can easily be swapped out. This is shown in the diagram below:  

figure-ssp-architecture-image10.png
Connecting layers with the FileX interface

 

In this example we are using the Azure RTOS. FileX file system on two storage mediums: SDMMC and SPI Flash. The SPI Flash Interface takes care of the SPI flash protocol but requires a SPI Interface for actual SPI bus communications. The SDMMC Interface takes care of the protocol and the bus communications meaning that it does not have any dependencies.

SSP Architecture In Practice

Each layer in the SSP Stack is responsible for calling the API functions of its dependencies. This can also be described by saying that users are only responsible for calling the API functions at the layer at which they are interfacing. Using the FileX example above, the user is only responsible for calling FileX functions in the application code. Internally, FileX then calls FileX I/O, which in turn calls a Block Media Interface Module. The Block Media Interface can call multiple drivers. At a minimum an upper layer Module calls the open() function of the Interface it depends upon.

To write an application using a Module, you must determine the following:

1) Determine which open() function to call. Dependencies are based upon Interfaces which means that a Module must have some way of discerning which Instance to call.

 

2) Determine the configuration parameters. The Module also needs to know what configuration information to pass down. In some cases the Module requires certain configuration parameters to be set. If this is the case then the module sets these configuration structure members itself before passing on the rest of the structure. The rest of the configuration structure members must be provided outside of the Module.

 

3) Provide a control structure which is Module Instance specific and therefore can be allocated by the upper layer module.

Putting this all together means that to interact with a Module Instance, the following is needed:

  • A pointer to the Instance's API structure
  • A pointer to the Module Instance's configuration structure
  • A pointer to the Module Instance's control structure

This information is sufficient to use any module. Notice that the API structure is the only structure that is Instance specific; not Module Instance specific. This is because the API structure will not vary between multiple uses of the same Instance. If SPI is being used on SCI channels 0 and 2 then both Module Instances will use the same API structure while the configuration and control structures will vary.

To make Module Instances easier to use, all of these pieces are encapsulated in instance structures found in each Interface. These structures have a standardized name of <interface>_instance_t. An example from the WDT interface is shown below.

typedef struct st_wdt_instance
{
    wdt_ctrl_t * p_ctrl; // Pointer to the control structure for this instance
    wdt_cfg_t const * p_cfg; // Pointer to the configuration structure for this instance
wdt_api_t const * p_api; // Pointer to the API structure for this instance

Upper layer modules that have a dependency on an Interface can then use the instance structure to hold everything needed to interact with an Instance of that Interface. Continuing with the WDT example above, below is the Thread Monitor Framework Interface configuration structure. The Thread Monitor Interface is dependent upon the WDT Interface.

typedef struct st_sf_thread_monitor_watchdog_type
{
    wdt_instance_t * p_lower_lvl_wdt; // Pointer to lower level watchdog instance
    bool profiling_mode_enabled; // Enables or disables profiling mode
    UINT priority; // Priority of thread monitor thread

The Thread Monitor module has everything it needs to work with the WDT Interface in the p_lower_lvl_wdt structure member.                                                                

In some cases module dependencies are not be defined in the Interface, but instead in the Instance. An example is the Block Media Interface could be implemented on SDMCC, SPI Flash, or many other Instances (also see API Reference section). Because of the wide range of implementations, the instance structure for a particular Interface cannot be used directly in the Block Media Interface's configuration structure. The Block Media Interface's configuration structure is shown again below.                   

 

                                                                       
    
typedef struct st_sf_block_media_cfg
{
    uint32_t block_size; // Block size in bytes
    void * p_extend; // Instance dependent configuration

Notice there are Instance structure pointers provided. The reason for this, as previously mentioned, is that the Block Media Interface is too generic to enforce a dependency upon a particular Interface. When a Module is an Instance of a generic Interface, such as Block Media, and it has dependencies on other Modules, the module puts the lower-layer pointers in an extension structure that is referenced through the Interface's p_extend configuration member. This is required to allow Module stacking while not forcing Interfaces to expand and have many optional configuration members.

typedef struct st_block_media_on_sdmmc_cfg
{
    sdmmc_instance_t const * const p_lower_lvl_sdmmc; // Pointer to SDMMC instance structure
} sf_block_media_on_sdmmc_cfg_t;

Using SSP Modules

This section will give general information on how to use a SSP module.

Pick an Interface

Start by picking an Interface for the functionality that is required. For example, for UART communications use the UART Interface.                                                                         

Find a suitable Instance of the Interface

After picking an Interface, choose a suitable Instance. The list of known Instances of an Interface is listed in the documentation comments for an Interface. Include the header file of the selected Instance in the source file of the application that uses the Instance.

Allocate control and configuration structures

The e2 studio ISDE provides a graphical user interface for setting the parameters of the Interface and Instance configuration structures. The ISDE also automatically includes those structures, once they are configured in the GUI, in application-specific header files that you can include into your application code.

To see how the ISDE handles the configuration, see Configuring a Project in the ISDE User’s Guide: Using the e2 studio ISDE

The configuration and control structure types follow standard names of <interface>_ctrl_t and <interface>_cfg_t respectively. The ISDE allocates storage for both structures in the application specific header files, which the ISDE creates. Use the ISDE Properties view to set the values for the members of the configuration structure as needed. Many members will be typed enumerations in which case the enumeration can be referenced for available options.

If the Interface has a callback function option, then you first need to declare and define the function in their source code. The return value is always of type void and the parameter to the function is a typed structure of name <interface>_callback_args_t. Once the function has been defined, assign its name to the p_callback member of the configuration structure. If any context information is required in the callback, then the user can provide a pointer to the p_context member. You can assign callback function names through the ISDE Properties window for the selected Module.

Refer to the Instance documentation to see if an Interface extension is provided. If so, then it will be found in the Instance's header file and named <interface>_on__cfg_t. It may have several members just like the Interface's configuration structure. When you select a driver with a specific Instance, you can select any parameter in the configuration structure of the instance in the ISDE property.

Interact using Interface’s Instance Structure

Once the instance structure has been defined, you can interact with the Instance as needed. Below is code that builds up an instance structure for the UART Interface as implemented on SCI. Please note that when using e2 studio for Synergy, the following code is automatically generated for the user.

/* Include the header file of the Instance. */
#include "r_sci_uart.h" // This will in turn include the r_uart_api.h Interface
/* Allocate control structure. */
uart_ctrl_t my_uart_ctrl;
/* Setup extended UART configuration on SCI. */
uart_on_sci_cfg_t my_uart_extended_cfg =
{
    /* Set extended configuration members... */
};
/* Configure standard UART Interface. */
uart_cfg_t my_uart_cfg =
{
    /* Continue configuring other members... */
    .p_extend = &my_uart_extended_cfg
};
/* Setup instance structure */
uart_instance_t my_uart = {
    .p_ctrl = &my_uart_ctrl,
    .p_cfg = &my_uart_cfg, //Extended configuration is brought through
in p_extend
    .p_api = &g_uart_on_sci //Defined in r_sci_uart.h
};
 

Now that the instance structure is ready, you can interact with the UART Interface. In e2 studio, the name of the instance structure is the *Name* that you provide when configuring the Module Instance in the ISDE Properties window.

/* Initialize UART */
err = my_uart.p_api-&gt;open(my_uart.p_ctrl, my_uart.p_cfg);
/* Check return for errors. */
if (SSP_SUCCESS != err)
{
/* Handle error. */
}
/* Use other Interface functions. */
err = my_uart.p_api-&gt;write(my_uart.p_ctrl, ...);
err = my_uart.p_api-&gt;read(my_uart.p_ctrl, ...);

Coding Style

C99 Use

SSP uses the ISO/IEC 9899:1999 (C99) C programming language standard. Specific features introduced in C99 that are used include standard integer types (stdint.h), booleans (stdbool.h), designated initializers, and the ability to intermingle declarations and code.

Use of const in API parameters

The const qualifier is used with API parameters whenever possible. An example case is shown below:

ssp_err_t (* open)(flash_ctrl_t * const p_ctrl, flash_cfg_t const * const p_cfg);

While not fool-proof by any means, this does provide some extra checking inside the SSP code to ensure that arguments that should not be altered are treated as such.

Weak Symbols

Weak symbols are used occasionally in and with SSP. They are used to ensure that a project builds even when you have not defined an optional function.

BSP Architecture

This section describes the BSP or Board Support Package. For the API Reference see Board Support Package. The BSP is board specific and as a result also MCU specific.

What Does the BSP Do?

The BSP is responsible for getting the MCU from reset to the user's application (that is, the main() function). Before reaching the user's application the BSP sets up the stacks, heap, clocks, interrupts, and C runtime environment. The BSP also configures and sets up the port I/O pins and performs any board specific initializations. 

                                                                          

figure-bsp-image1.png
BSP flow

BSP Related Terminology

Term Meaning
system_xxxx.c or startup_xxxx.c The ‘xxxx’ refers to the MCU type. For example, system_S7G2.c when referencing the S7G2 MCU.
BSP Short for Board Support Package. BSP’s usually have source files related to a specific board.
Callback Function This term refers to a function that is called when an event occurs. For example, the NMI interrupt handler is implemented in the BSP. The user will likely want to know when an NMI system exception occurs. To alert the user, a callback function can be configured for the group interrupts (a group of exceptions all of which are tied to the NMI). When an NMI occurs the BSP will jump to the provided callback function and the user can handle the error. Interrupt callback functions should be kept short and be handled carefully because when they are called the MCU will still be inside of an interrupt and therefore will be delaying any pending interrupts.

BSP Directory Structure

The BSP is organized into folders containing MCU, board specific and CMSIS information.

Synergy is CMSIS-compliant and based on the CMSIS-Core. This requires that we follow CMSIS requirements and naming standards.

  • Standardized definitions for processor peripherals
  • NVIC (Nested Vector Interrupt Controller)
  • Systick (System Tick Timer)
  • MPU (Memory Protection Unit)
  • Standardized access functions to access processor features
  • NVIC_SetPriority()
  • NVIC_EnableIRQ
  • Standardized function names for system exception handlers
  • Reset_Handler()
  • SysTick_Handler()
  • Standardized functions for system initialization.
  • SystemInit() – defined in system_S7G2.c for S7G2 MCUs
  • Standardized software variables for clock speed information
  • SystemCoreClock

The BSP directory structure is shown below:

figure-bsp-image2.png
BSP directory structure

Configuring the BSP

The BSP is heavily data driven with most features and functionality being configured based on the content from configuration files. Configuration files represent the settings specified by the user and are generated by the ISDE when the Generate Project Content button is clicked.                                                                     

BSP Configuration Settings

The table below describes each of the configurable BSP settings. Many of these settings are MCU specific and there are differences between the settings available for each of the supported MCUs.

Table: BSP Configuration options

BSP Property Description
Part number MCU part number
ram_size_bytes Available RAM in this MCU package
rom_size_bytes Available ROM in this MCU package
data_flash_size_bytes Available Data Flash in this MCU package
package_style Style of package (ie. BGA)
package_pins Number of pins in this MCU package
series MCU part series
Main stack size (bytes) Size of the Main Stack. Must be > 0.
Process stack size (bytes) Size of the Process Stack. Use of this stack is optional. If 0, then PSP use is disabled
Heap size (bytes) Size of the heap in bytes. If 0, the heap is disabled.
OFS0 register settings: IWDT Start Mode, IWDT Timeout Period, IWDT Dedicated Clock Frequency Divisor, IWDT Window End Position, IWDT Window Start Position, IWDT Reset Interrupt Request Select, IWDT Stop Control, WDT Start Mode Select , WDT Timeout Period, WDT Clock Frequency Division Ratio, WDT Window End Position, WDT Window Start Position, WDT Reset Interrupt Request, WDT Stop Control The option-setting memory determines the state of the MCU after a reset. It is allocated to the configuration setting area and the program flash area of the flash memory. See the MCU user manual for details.
OFS1 register settings: Voltage Detection 0 Circuit Start, Voltage Detection 0 Level, HOCO Oscillation Enable. S3 MPU has MPU configuration settings. See the MCU user manual for details.
MPU - Enable or disable PC Region 0 Start block address for access window protection
MPU - PC0 Start, MPU - PC0 End, MPU - Enable or disable PC Region 1, MPU - PC1 Start, MPU - PC1 End, MPU - Enable or disable Memory Region 0, MPU -Memory Region 0 Start, MPU - Memory Region 0 End, MPU - Enable or disable Memory Region 1, MPU - Memory Region 1 Start, MPU - Memory Region 1 End, MPU - Enable or disable Memory Region 2, MPU - Memory Region 2 Start, MPU - Memory Region 2 End, MPU - Enable or disable Memory Region 3, MPU - Memory Region 3 Start, MPU - Memory Region 3 End Secure MPU ROM register settings. See user manual for details.
ID code 1, ID code 2, ID code 3, ID code 4 Sets the ID Code for boot mode and debugger access protection.
MCU Vcc (mV) Some Modules (e.g. LVD) need to know the voltage supplied to the MCU. This information is obtained from here.
Parameter checking Defines whether the global setting for parameter checking is enabled or disabled. Local modules will take this value by default but can be locally overridden.
Assert Failures Defines what happens when an assertion failure occurs.
Error Log Defines whether or not errors are logged to ssp_error_log.

BSP Configuration Files

Configuration files are used by the BSP to set up ROM registers, clocks, interrupts, ELC events and initial pin configurations. These configuration files can be found in ssp_cfg\bsp.

Bsp_cfg.h

This configuration file contains the values for BSP system settings. These are the settings that can be modified from the ISDE BSP properties tab. They include ROM register settings, stack and heap size, parameter checking and control of error logging.

Some registers are located in ROM and therefore must be set at compile-time. These include some option-setting memory (OFS) registers as well as certain memory protection registers.

Option-setting memory determines the state of the MCU after a reset. For example, the IWDT can be configured and enabled, voltage detection can be enabled, and HOCO oscillation can be enabled. When these registers are set the operations are completed before the MCU’s reset vector is fetched and execution begins.

Some Synergy MCUs include a Memory Protection Unit (MPU). The MPU is a programmable device that can be used to define memory access permissions (i.e. privileged access only or full access) and memory attributes (for example, bufferable, cacheable) for different memory regions. The MPU can support up to eight programmable memory regions, each with their own programmable starting addresses, sizes and settings.

The ISDE configures these memory areas by setting values for the provided MPU settings. You must be careful when setting these registers. Incorrect settings can prevent access to required memory areas or prevent access to the MCU entirely.

BSP Pin Configuration

You can configure the pins used in your application through the ISDE pin configurator. See Configuring Pins.

Bsp_pin_cfg.h

This configuration file contains an array of pin configurations. During start-up, and before main() is executed, the BSP iterates over this array and initializes the MCU's port pins based on the settings in the array. Initially, before any pin configuration by the user, the ISDE Pins tab displays the initial reference configuration defined for the selected board type (see Configuring Pins). Once the user modifies the pin configuration and clicks Generate Project, a new bsp_pin_cfg.h file is generated containing the new pin configuration. The BSP always uses the bsp_pin_cfg.h file from ssp_cfg\bsp as the source for its pin configuration information, but the pin information generated by clicking Generate Project is written to a bsp_pin_cfg.h file in the hidden folder ssp_cfg\bsp\.out.                                                                            

In this way, the user can manually edit the bsp_pin_cfg.h in ssp_cfg\bsp without the fear of the file being overwritten by the project generation, while the Pin Configuration information generated by the ISDE also remains available for view or merging with the user’s config file.

BSP Clock Configuration

All system clocks are set up during BSP initialization based on the settings in bsp_clock_cfg.h. These settings are derived from clock configuration information provided from the ISDE Clocks tab setting.

  • Clock configuration is performed prior to initializing the C runtime environment to speed up the startup process, as it is possible to start up on a relatively slow (for example, 32 kHz) clock.
  • The BSP implements the required delays to allow the selected clock to stabilize.

Bsp_clock_cfg.h

This configuration file represents the values for system clock settings. These are the settings that can be modified from the ISDE **Clocks** tab. See: Configuring Clocks

System Interrupts

As Synergy MCU’s are based on the Cortex-M ARM architecture, the NVIC Nested Vectored Interrupt Controller (NVIC) handles exceptions and interrupt configuration, prioritization and interrupt masking. In the ARM architecture, the NVIC handles exceptions. Some exceptions are known as System Exceptions. System exceptions are statically located at the top of the vector table and occupy vector numbers 1 to 15. Vector zero is reserved for the MSP Main Stack Pointer (MSP). The remaining 15 system exceptions are shown below:

 

  • Reset
  • NMI
  • Cortex-M4 Hard Fault Handler
  • Cortex-M4 MPU Fault Handler
  • Cortex-M4 Bus Fault Handler
  • Cortex-M4 Usage Fault Handler
  • Reserved
  • Reserved
  • Reserved
  • Reserved
  • Cortex-M4 SVCall Handler
  • Cortex-M4 Debug Monitor Handler
  • Reserved
  • Cortex-M4 PendSV Handler
  • Cortex-M4 SysTick Handler

NMI and Hard Fault exceptions are enabled out of reset and have fixed priorities. Other exceptions have configurable priorities and some can be disabled.

Group Interrupts

Group interrupt is the term used to describe the 12 sources that can trigger the Non-Maskable Interrupt (NMI). When an NMI occurs the NMI Handler examines the NMISR (status register) to determine the source of the interrupt. NMI interrupts take precedence over all interrupts, are usable only as CPU interrupts, and cannot activate the Synergy peripherals Data Transfer Controller (DTC) or Direct Memory Access Controller (DMAC).

Possible group interrupt sources include:

  • IWDT Underflow/Refresh Error
  • WDT Underflow/Refresh Error
  • Voltage-Monitoring 1 Interrupt
  • Voltage-Monitoring 2 Interrupt
  • VBATT monitor Interrupt
  • Oscillation Stop is detected
  • NMI pin
  • RAM Parity Error
  • RAM ECC Error
  • MPU Bus Slave Error
  • MPU Bus Master Error
  • MPU Stack Error

A user may enable notification for one or more group interrupts by registering a callback using the BSP API function R_BSP_GroupIrqWrite. When an NMI interrupt occurs, the NMI handler checks to see if there is a callback registered for the cause of the interrupt and if so calls the registered callback function.

As mentioned earlier, the first 16 slots in the vector table are already accounted for by the system exceptions. Beginning with slot 16 are user configurable interrupts. These may be external, or peripheral generated interrupts.                                                                                                 

The size of the NVIC interrupt table varies across Synergy MCU types (shown below).

figure-bsp-image4.png
NVIC Interrupt vector table

 

Although the number of available slots for the NVIC interrupt vector table may seem small, the BSP defines up to 512 events that are capable of generating an interrupt. By using Event Mapping, the BSP maps user enabled events to NVIC interrupts. For an S7G2 MCU, only 96 of these events may be active at any one time, but the user has flexibility by choosing which events generate the active event.  

The diagram below shows the interrupt vector table for the S7G2:

figure-bsp-image5.png
NVIC Interrupt vector table

By allowing the user to select only the events they are interested in as interrupt sources, we are able to provide an interrupt service routine that is fast and event specific.                                                   

For example, on other microcontrollers a standard NVIC interrupt vector table might contain a single vector entry for the SCI0 (Serial Communications Interface) peripheral. The interrupt service routine for this would have to check a status register for the 'real' source of the interrupt. In the Synergy implementation there is a vector entry for each of the SCI0 events that we are interested in. The difference between a standard NVIC table and the Synergy S7G2 NVIC table is shown below:

 

figure-bsp-image6.png
NVIC Interrupt vector table example

 

Configuration of interrupts is handled by the ISDE. Selecting an interrupt to be used by a module will generate the code necessary to allocate its entry in the vector table, as well as link it to the proper ICU ELC event.

When an interrupt occurs one of the very first operations must be to call R_BSP_IrqStatusClear() with the interrupt number corresponding to the NVIC interrupt slot that was assigned by the BSP. R_BSP_ IrqStatusClear() clears the interrupt status flag (IR) for the given interrupt. When an interrupt is triggered the IR bit is set. If it is not cleared in the ISR then the interrupt will trigger again immediately.

Entries that have been assigned a priority (i.e. BSP_IRQ_CFG_ICU_IRQ0) in our example, have their corresponding ‘weak handler’ address placed in the next available vector slot. All of the possible interrupt sources are iterated over in this manner. Defined interrupts are entered into the vector table.

BSP Interrupt Configuration File

Bsp_irq_cfg.h is a legacy file that is no longer used and will be removed in the future. Interrupt configuration is now completely handled by the ISDE.

Vector table entries

System exceptions such as the HardFault_Handler, are defined as weak references. This allows the user to override the default handler for a particular exception and define their own handler.

All other entries in the vector table are generated by the ISDE using a macro which defines the vector and a corresponding vector information structure to generate an entries in ROM table linker sections (.vector.* for vectors and .vector_info.* for vector information).

Note that in CMSIS system_xxxx.c, there is also a weak definition (and a function body) for the Warm Start callback function R_BSP_WarmStart(). Because this function is defined in the same file as the weak declaration, it will be called as the ‘default’ implementation. The function may be overridden by you by copying the body into your application and modifying it as necessary. The linker identifies this as the ‘strong’ reference and uses it.

Warm start callbacks

As the BSP is in the process of bringing up the board out of reset, there are two points where the user can request a callback. These are defined as the 'Pre C' and 'Post C' warm start callbacks.                   

As described above, this function is already weakly defined as R_BSP_WarmStart(), so it is a simple matter of redefining the function or copying the existing body from CMSIS system_xxxx.c into the application code to get a callback. R_BSP_Warmstart() takes an event parameter which describes the type of warm start callback being made.                                                                                             

 
/* Different warm start entry locations in the BSP. */
typedef enum e_bsp_warm_start_event
{
    BSP_WARM_START_PRE_C = 0, // Called almost immediately after reset.
    /* No C runtime environment, clocks, or IRQs. */
    BSP_WARM_START_POST_C // Called after clocks and C runtime environment have been set up.
} bsp_warm_start_event_t;

This function is not enabled/disabled and is always called for both events as part of the BSP startup. Therefore it needs a function body, which will not be called if the user is overriding it. The function body is located in system_xxxx. To use this function just copy this function into your own code and modify it to meet your needs.                                                                                                             

Pre C Warm start callback

This callback occurs almost immediately after reset and at this point no C runtime environment, clocks, or IRQs have been setup.

Why would you be interested in a 'Pre C' warm start callback?

Below are a few examples.

  • Execution of safety code (i.e. destructive memory tests) as part of the startup process.
  • Examination of global memory as part of a crash dump investigation.
  • Preventing re-initialization of an already running RTC.

Post C Warm start callback

This callback occurs after clocks and the C runtime environment have been setup.

Why would you be interested in a 'Post C' warm start callback?

Below are a few examples.

  • Run tests that require that clocks have been setup.
  • ADC diagnostics.
  • ROM/External memory system checks.

Custom BSP Board support

Creating a Custom BSP for your own board is not supported in this version of the SSP. For information on creating a Custom BSP with earlier versions, see application note R11AN0071EU, Creating a Custom Board Support Package for SSP v1.2.0 or Later.

BSP API functions

The BSP provides public functions, available to any project using the BSP, that allow access to functionality that is common across BSP supported MCUs and boards.  

  • R_BSP_SoftwareLockInit: The BSP provides API functions to implement atomic locking. These locks can be used to protect critical areas of code as an RTOS semaphore or mutex normally would. This function simply initializes a defined lock structure to BSP_LOCK_UNLOCKED
  • R_BSP_SoftwareLock: Attempts to acquire the lock that has been sent in. The Load-Exclusive and Store-Exclusive instructions are being used to perform an exclusive read-modify-write on the input lock. This process is:
    •  Use a load-exclusive (LDREXB) to read the value of the lock.
    •  If the lock is available, then modify the lock value so it is reserved. If not available, then issue CLREX.
    •  Use a store-exclusive to attempt to write the new value back to memory.
    •  Test the returned status bit to see if the write was performed or not.
  • R_BSP_SoftwareUnlock: Releases the hold on an existing software lock.
  • R_BSP_HardwareLock: Hardware locks are similar to Software locks. In fact, the BSP Software lock functions are called by the Hardware lock functions. Hardware locks are specific to a particular peripheral, the list of available hardware locks being defined in bsp_hw_locks.h. Hardware locks can be used to prevent multiple threads from trying to use a peripheral that is already in use by a process or thread. For example, when the Flash API open() function is called, it takes the Flash Hardware lock and keeps it until the Flash API close is called.
  • R_BSP_HardwareUnlock: Releases the hold on an existing hardware lock. In the Flash example above, the Flash API close function would call this function.
  • R_BSP_GroupIrqWrite: Registers a callback function for one of supported group interrupts. As described earlier, there are 12 of these and they are all mapped to the NMI exception. When an NMI occurs, the NMI_Handler looks at the NMISR (status register) to determine the source of the interrupt. If a callback function has been registered for this group interrupt, it will be called. If NULL is passed for the callback argument, then any previously registered callbacks are unregistered.
  • R_BSP_IrqStatusClear: Clears the interrupt status flag (IR) for a given interrupt. When an interrupt is triggered the IR bit is set. If it is not cleared in the ISR, then the interrupt will trigger again immediately.
  • R_BSP_SoftwareDelay: Implements a blocking software delay. A delay can be specified in microseconds, milliseconds, or seconds. The delay is implemented based on the system clock rate.
  • R_BSP_VersionGet: Returns the version of the BSP.
  • R_BSP_LedsGet(): Returns information about the LEDs on the board.
  • R_BSP_ModuleStop(): Specifies modules whose stop bit should be set.
  • R_BSP_ModuleStart(): Specifies modules whose stop bit should be cleared.
  • R_BSP_CacheOff(): Turns off the ROM cache, and return it’s prior state.
  • R_BSP_CacheSet(): Sets the cache state to a specific state (on or off).
  • R_BSP_RegisterProtectEnable: Enables register protection. Registers that are protected cannot be written to. Register protection is enabled by using the Protect Register (PRCR) and the MPC's Write-Protect Register (PWPR). The registers that may be protected are grouped together into one of three groups.
    •   BSP_REG_PROTECT_CGC - registers related to the clock generation circuit.
    •   BSP_REG_PROTECT_OM_LPC_BATT - registers related to operating modes, low power consumption, and battery backup function.
    •   BSP_REG_PROTECT_LVD – registers related to LVD (Low Voltage Detection)

The BSP register protection functions utilize reference counters to ensure that an application which has specified a certain register and subsequently calls another function does not have its register protection settings inadvertently modified.                                                                                       

  • Each time RegisterProtectDisable() is called, the respective reference counter is incremented.
  • Each time RegisterProtectEnable() is called, the respective reference counter is decremented.

Both functions will only modify the protection state if their reference counter is zero.  

As the example below shows, without reference counters, MODULE2 would re-protect the registers that MODULE 1 had un-protected, preventing MODULE1 from writing them.

 

figure-bsp-image14.png
Register protection

 

  • R_BSP_RegisterProtectDisable: Disables register protection. Registers that are not protected can be written to. Register protection is disabled by using the Protect Register (PRCR) and the MPC's Write-Protect Register (PWPR). The register groupings described above still apply.

Key Features

This section describes the key features 

Azure RTOS ThreadX® RTOS

  • Multithreaded, deeply embedded, real-time systems
  • Small, fast Picokernel™ architecture
  • Multitasking capabilities
  • Preemptive and cooperative scheduling
  • Flexible thread priority support (32-1024 priority levels)
  • Small memory footprint and fast response times
  • Optimized interrupt handling
  • Stack Pointer Overflow Monitor

Azure RTOS GUIX™

  • Supports 2D Graphics Acceleration in Hardware
  • Unlimited objects (screens, windows, widgets)
  • Dynamic object creation/deletion
  • Alpha blending and anti-aliasing at higher color depths
  • Canvas blending
  • Dithering support
  • Complete windowing support, including viewports and Z-order maintenance
  • Multiple canvases and physical displays
  • Window blending and fading
  • Screen transitions, sprites, and dynamic animations
  • Touchscreen and virtual keyboards
  • Multilingual support with UTF8 string encoding
  • Automatic size scaling
  • 8-bit Color Lookup Table (CLUT) support
  • Touch Rotation
  • Radial Progress Bar
  • Endian Neutral
  • Monochrome through 32-bit true-color with alpha graphics formats
  • Skinning and Themes
  • Bitmap compression
  • GUIX Studio desktop tool and Win32 simulation
  • Integrated with hardware JPEG/MJPEG decoder

Azure RTOS USBX™

  • USB 2.0 Full Speed and High-Speed support
  • Device class: MSC, HID, CDC-ACM
  • Host class: MSC, HID, CDC-ACM, UVC, HUB, Printer, Video
  • Supports fast DMA and isochronous transfers

Azure RTOS FileX®

  • MS-DOS compatible file system integrated with ThreadX
  • FAT12-, 16-, 32-bit support
  • exFAT
  • Fault-tolerant file system (uses journaling)
  • Multiple media instances
  • LevelX Flash block media driver
  • LevelX support for NOR Flash on QSPI

Azure RTOS NetX™

  • Integrated with wired (Ethernet) and wireless (WiFi, Cellular) networking interfaces for Synergy
  • IPv4 compliant TCP/IP Protocol Stack
  • Integrated with ThreadX
  • Zero-copy API
  • UDP Fast Path Technology
  • BSD-compatible socket layer
  • RFC 791 Internet Protocol (IP)
  • RFC 826 Address Resolution Protocol (ARP)
  • RFC 903 Reverse Address Resolution Protocol (RARP)
  • RFC 792 Internet Control Message Protocol (ICMP)
  • RFC 3376 Internet Group Management Protocol (IGMP)
  • RFC 768 User Datagram Protocol (UDP)
  • RFC 793 Transmission Control Protocol (TCP)
  • RFC 1112 Host Extensions for IP Multicasting

Application Frameworks

  • ADC Periodic framework
  • Audio Playback framework
  • Audio Playback HW DAC framework
  • Audio Playback HW I2S framework
  • Audio Record framework
  • Audio Recording HW ADC framework
  • Block Media Interface for SD Multi Media Card
  • Block Media LevelX NOR framework
  • Block Media QSPI framework
  • Block Media RAM framework
  • Block Media SDMMC framework
  • Bluetooth Low Energy (BLE) framework
  • Deprecated – Capacitive Touch Sensing Unit framework
  • Capacitive Touch Sensing Unit framework Version 2
  • Deprecated – Capacitive Touch Sensing Unit Button framework
  • Deprecated – Capacitive Touch Sensing Unit Slider framework
  • Cellular framework
  • Communications framework on NetX
  • Communications framework on NetX Telnet
  • Deprecated - Communications framework on USBX
  • Communications Framework on USBX version2
  • Console framework
  • External Interrupt framework
  • I2C framework
  • Inter-Thread Messaging framework
  • JPEG Decode framework
  • Memory framework
  • Port LevelX framework
  • Periodic Sampling ADC framework
  • Power Profile Version 2 framework
  • SPI Framework
  • Synergy FileX® Port Block Media Interface framework
  • Synergy GUIX™ Interface framework
  • Synergy NetX™ Port framework
  • Synergy USBX™ Port framework
  • Thread Monitor framework
  • Deprecated - Touch Panel framework
  • Touch Panel Version 2 framework
  • UART framework
  • Wi-Fi Framework

Security Cryptographic (SCE) Library

  • True RNG (TRNG)
  • SHA1, SHA224/SHA256
  • ECC P-192, P-224, P-256 and P-384 curves. Includes APIs for scalar multiplication, key generation, ECDSA signature generation, and ECDSA signature verification operations
  • AES 128, 192, and 256-bits ECB, CBC, CTR, GCM, XTS
  • 3DES, 192-bit key, ECB, CBC, CTR
  • ARC4
  • RSA up to 2048-bit keys
  • DLP, DSA up to 2048-bit keys
  • Encryption/Decryption
  • Key Generation (plaintext and wrapped keys) and Installation.
  • Signature Generation and Verification
  • MD5

CMSIS DSP Library

  • Basic math functions
  • Fast math functions
  • Complex math functions
  • Filters
  • Convolution
  • Matrix functions
  • Transforms
  • Motor control functions
  • Statistical functions
  • Support functions
  • Interpolation functions
  • Bayes functions
  • Controller functions
  • Distance functions
  • Quaternion functions
  • SVM functions

Detailed CMSIS library details can be found on Github: https://github.com/ARM-software/CMSIS_5/releases/tag/5.8.0

CMSIS Neural Network Library

  • Convolution functions
  • Activation functions
  • Fully-connected Layer functions
  • Pooling functions
  • Softmax functions
  • Basic math functions
  • Concatenation functions
  • NN Support functions
  • Reshape Functions
  • SVD Functions

Detailed CMSIS library details can be found on Github: https://github.com/ARM-software/CMSIS_5/releases/tag/5.8.0

AzureRTOS NetX Duo™

  • IPv4 and IPv6 compliant TCP/IP Protocol Stack
  • Integrated with ThreadX
  • Integrated with wired (Ethernet) and wireless (WiFi, Cellular) networking interfaces for Synergy
  • Zero-copy API
  • UDP Fast Path Technology
  • BSD-compatible socket layer
  • RFC 2460 IPv6 Specification
  • RFC 4861 Neighbor Discovery for IPv6
  • RFC 4862 IPv6 Stateless Address
  • RFC 1981 Path MTU Discovery for IPv6
  • RFC 4443 ICMPv6
  • RFC 791 Internet Protocol (IP)
  • RFC 826 Address Resolution Protocol (ARP)
  • RFC 903 Reverse Address Resolution Protocol (RARP)
  • RFC 792 Internet Control Message Protocol (ICMP)
  • RFC 3376 Internet Group Management Protocol (IGMP)
  • RFC 768 User Datagram Protocol (UDP)
  • RFC 793 Transmission Control Protocol (TCP)
  • RFC 1112 Host Extensions for IP Multicasting
  • RFC 1661 - The Point-to-Point Protocol (PPP)

Azure RTOS NetX™ Applications (IPv4 Networking Services)

  • DHCP Client and Server
  • DNS Client
  • HTTP 1.0 Client and Webserver
  • HTTP 1.1 Client
  • FTP Client and Server
  • TFTP Client and Server
  • Telnet Client and Server
  • Auto IP
  • NAT
  • SMTP Client
  • POP3 Client and Server
  • SNMP Agent
  • SNTP Client
  • PPP (Not currently supported by Synergy Configuration tool)

Azure RTOS NetX Duo™ Applications (IPv4/v6 Networking Services)

  • DHCP Client and Server
  • DNS Client
  • HTTP 1.0 Client and Webserver
  • HTTP 1.1 Client
  • HTTPS Client and Server
  • FTP Client and Server
  • TFTP Client and Server
  • Telnet Client and Server
  • Auto IP
  • NAT
  • SMTP Client
  • POP3 Client and Server
  • SNMP Agent
  • SNTP Client
  • MDNS/DNS-SD
  • PPP (Not currently supported by Synergy Configuration tool)

Azure RTOS NetX Secure

  • TLS v1.2 (RFC 5246) and v1.3 (RFC 8446)
  • DTLS v1.2 (RFC 6347)
  • RFC 5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
  • RFC 5280 X.509 PKI Certificates (v3)
  • Supports X.509 extensions for Key Usage and Extended Key Usage
  • RFC 3268 Advanced Encryption Standard (AES) Cipher suites for Transport Layer Security (TLS)
  • RFC 3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1
  • RFC 2104 HMAC: Keyed-Hashing for Message Authentication
  • RFC 6234 US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)
  • RFC 8422 Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) Versions 1.2 and Earlier
  • RFC 4279 Pre-Shared Key Cipher suites for TLS
  • Supports TLS extensions for:
    •     Secure Renegotiation Indication
    •     Server Name Indication
    •     Signature Algorithms
  • Subject Alternative Name
  • Integrated with hardware accelerated Cryptographic library on Synergy

Azure RTOS MQTT client for NetX Duo

  • Compliant with OASIS MQTT Version 3.1.1
  • Provides option to enable/disable TLS for secure communications using NetX Secure in SSP
  • Supports QoS and provides the ability to choose the levels that can be selected while publishing the message
  • Supports multiple Instances of MQTT Client Per Device

Memory Support

  • Flash programming support via JTAG
  • Code and Data Flash drivers
  • External memory bus support

Human Machine Interface (HMI)

  • Graphics LCD controller driver
  • Segment LCD controller driver
  • Capacitive Touch Sensing Unit (CTSU)

Hardware Abstract Layer (HAL) Driver Modules

  • Analog Comparator High-Speed (ACMPHS)
  • Analog Comparator Low Power (ACMPLP)
  • Analog Connect Module (ACM)
  • Analog to Digital Converter (ADC) (12-bit, 14-bit)
  • Asynchronous General Purpose Timer (AGT)
  • AGT Input Capture (AGT Input Capture)
  • Capacitive Touch Sensing Unit (CTSU)
  • Clock Frequency Accuracy Measurement (CAC)
  • Clock Generation Circuit (CGC)
  • Controller Area Network Interface (CAN)
  • Cyclic Redundancy Check calculator (CRC)
  • Data Operation Circuit (DOC)
  • Data Transfer Controller (DTC)
  • Digital to Analog converter (DAC)
  • Digital to Analog converter 8-bit (DAC8)
  • Direct Memory Access Controller (DMAC)
  • Event Link Controller (ELC)
  • Flash Memory-High Performance (FLASH_HP)
  • Flash Memory-Low Power (FLASH_LP)
  • General Purpose I/O Port (GPIO / IOPORT)
  • General Purpose Timer (GPT)
  • General PWM Timer with Input Capture (GPT_INPUT_CAPTURE)
  • Graphics LCD Controller (GLCD)
  • IEEE 1588 Precision Time Protocol (PTP)
  • I2IC (RIIC)
  • Independent Watchdog Timer (IWDT)
  • Interrupt Controller Unit (ICU)
  • JPEG Codec (JPEG_COMMON, JPEG_ENCODE, JPEG_DECODE)
  • Keyboard Interrupt Interface (KINT)
  • Deprecated – Low Power Mode (LPM)
  • Low Power Mode Version 2 (LPMv2)
  • Low Voltage Detection (LVD)
  • Parallel Data Capture Unit (PDC)
  • Quad SPI (QSPI)
  • Real Time clock (RTC)
  • SD Multi Media Card (SDMMC)
  • Segment LCD (SLCD)
  • Serial Communication Interface I2C (SCI_I2C)
  • Serial Communication Interface SPI (SCI_SPI)
  • Serial Communication Interface UART (SCI_UART)
  • Sigma-Delta ADC (SDADC)
  • Serial Peripheral Interface (SPI)
  • Serial Sound Interface (SSI)
  • Watchdog Timer (WDT)

GPIO and Key Interrupts

  • GPIO module
  • Key Interrupts module