1. Home
  2. Symmetry Blog
  3. Making Peripheral Drivers Thread-safe

From Silicon Labs: Making Peripheral Drivers Thread-safe

Symmetry Electronics in Blogs on August 17, 2019

About Symmetry Electronics

Established in 1998, Symmetry Electronics, a Division of Braemac, is a global distributor of electronic components and systems. Combining premier components and comprehensive value-added services with an expert in-house engineering team, Symmetry supports engineers in the design, development, and deployment of a broad range of connected technologies. 

Exponential Technology Group Member

Acquired by Berkshire Hathaway company TTI, Inc. in 2017, Symmetry Electronics is a proud Exponential Technology Group (XTG) member. A collection of specialty semiconductor distributors and engineering design firms, XTG stands alongside industry leaders TTI Inc., Mouser Electronics, and Sager Electronics. Together, we provide a united global supply chain solution with the shared mission of simplifying engineering, offering affordable technologies, and assisting engineers in accelerating time to market. For more information about XTG, visit www.xponentialgroup.com.

If you are running in a multi-threaded environment in which you have more than one task making use of a peripheral driver such as USART, SPI, I2C, etc., you should consider making it thread-safe.

The Micrium OS kernel offers a variety of services designed to protect shared resources. In our case, let’s make use of the Mutual Exclusion Semaphore also known as mutex. Why a mutex? Because we want our resource (peripheral driver) to be accessed only by one task at a time. Regular semaphores present a vulnerability with priority-inversion. Mutexes, on the other hand, are implemented in a way that priority inversions are prevented by using priority inheritance.



For this exercise, you will be editing files from the Gecko SDK, which is not recommended therefore do this with caution.

In the peripheral driver file that you want to protect, include the following file:


#include  <kernel/include/os.h>


Now we have to declare a global variable for our mutex, for example, if you want to protect the SPI you could declare it as follows:


OS_MUTEX  SPI_Mutex;


With the mutex now declared, you need to invoke the kernel call to create it. My recommendation is to make this in the initialization function of the peripheral driver that you are using. You create the mutex by calling:


OSMutexCreate(&SPI_Mutex, “SPI Mutex”, &err);


Notice how the function requires an error argument, just declare RTOS_ERR  err locally and pass it on.

Always make sure to check the error returned, if it’s not RTOS_ERR_NONE then something went wrong.

The mutex is now created and registered with the kernel. Now you will need to wrap around the driver calls that your application is using with:


void foo () {

  RTOS_ERR  err;

OSMutexPend(&SPI_Mutex,                                                  /* Pointer to the mutex */
                           0,                                                                   /* No timeout */
                           OS_OPT_PEND_BLOCKING,                      /* Block if not available */
                           DEF_NULL,                                                   /*Timestamp not used */
                         &err);

if (err.Code != RTOS_ERR_NONE) {
      /* handle error */
  }

/* peripheral driver function code */
  ...
  ...
  ...

  OSMutexPost(&SPI_Mutex,
                            OS_OPT_POST_NONE,
                          &err);

if (err.Code != RTOS_ERR_NONE) {
      /* handle error */
  }
}


Please make sure to check the returned errors. A common one is RTOS_ERR_NOT_READY, this happens when the pend or post calls are made before the kernel is in its running state (after the call to OSStart()).

If the driver initialization function can potentially be called multiple times from more than one task, my recommendation is to also protect it.

With this setup, you can be sure that your peripheral is only being accessed by one task at a time.

Beware also that some drivers have abort functions, you have to be careful with this and not lock your system on a mutex pend. For more information on how to protect a resource using Micrium OS please visit https://doc.micrium.com/display/OSUM50600/Resource+Management+Using+the+Kernel


Source: https://www.silabs.com/community/blog.entry.html/2019/06/26/making_peripheraldriversthread-safe-5AjD


Looking to integrate Silicon Labs products with your design? Our Applications Engineers offer free design and technical help for your latest designs. Contact us today!

Share

Symmetry Electronics in Blogs on August 17, 2019

About Symmetry Electronics

Established in 1998, Symmetry Electronics, a Division of Braemac, is a global distributor of electronic components and systems. Combining premier components and comprehensive value-added services with an expert in-house engineering team, Symmetry supports engineers in the design, development, and deployment of a broad range of connected technologies. 

Exponential Technology Group Member

Acquired by Berkshire Hathaway company TTI, Inc. in 2017, Symmetry Electronics is a proud Exponential Technology Group (XTG) member. A collection of specialty semiconductor distributors and engineering design firms, XTG stands alongside industry leaders TTI Inc., Mouser Electronics, and Sager Electronics. Together, we provide a united global supply chain solution with the shared mission of simplifying engineering, offering affordable technologies, and assisting engineers in accelerating time to market. For more information about XTG, visit www.xponentialgroup.com.

Subscribe

Stay up to date with industry and supplier news!

Browse

See all tags