# Time Management in Wireless Sensor Networks for Industrial Process Control
## 3 Results  
### Hardware Abstraction Layer  
Optimizing the code execution time and having consistency in this execution requires quick and easy access to the microcontroller's registers. To do his, we have skipped using the open-source libraries available from the manufacturer (i.e., STM32 Cube MCU Packages) and developed a hardware abstraction layer (HAL) to access the most common microcontroller modules like the clock system, the GPIOs, the timers, the communication interfaces, the flash, and ADCs and DACs. The HAL defines standard function headers with the implementation varying from one microcontroller to another and allows for easy code porting to another hardware platform if needed. The application layer calls these standard functions to configure and use the physical layer of the microcontroller. The HAL uses the device descriptions to access the microcontroller registers that follow the Common Microcontroller Software Interface Standard (CMSIS) which is an Arm-maintained, vendor-independent software framework that standardizes how the code, tools, and device descriptions interact with Arm Cortex-based microcontrollers. The goal is to let the user focus on the application instead of relearning low-level details for every new microcontroller. Each module has its registered part of a structure, such as the one given below, for example, the GPIO module. CMSIS defines all microcontroller registers as volatile and uses the standard C99 data types for interoperability. \begin{tabular}{l l l l} \hline \hline typedef struct & & & & \\ \{ & I\_U uint32\_t MODER; & /*IC GPIO port mode register, & Address offset: 0x00 & */ \\ \_IO uint32\_t GYYTER; & /*IC GPIO port output type register, & Address offset: 0x04 & */ \\ \_IO uint32\_t GYYTER; & /*IC GPIO port output speed register, & Address offset: 0x08 & */ \\ \_IO uint32\_t FUPDR; & /*IC GPIO port pull-up/pull-down register, & Address offset: 0x0C & */ \\ \_IO uint32\_t HDR; & /*IC GPIO port input data register, & Address offset: 0x10 & */ \\ \_IO uint32\_t ORB; & /*IC GPIO port output data register, & Address offset: 0x14 & */ \\ \_IO uint32\_t BSR; & /*IC GPIO port bit set/reset register, & Address offset: 0x18 & */ \\ \_IO uint32\_t LCRK; & /*IC GPIO port configuration lock register, & Address offset: 0x1C & */ \\ \_IO uint32\_t ARFR2; & /*IC GPIO alternate function registers, & Address offset: 0x20-0x24 & */ \\ \_IO uint32\_t BSR; & /*IC GPIO Bit Reset register, & Address offset: 0x28 & */ \\ \_IO uint32\_t ASCR; & /*IC GPIO analog switch control register, & Address offset: 0x2C & */ \\ \cline{1-1} GPIO\_TypeDef; & & & & \\ \hline \hline \end{tabular}   
Each microcontroller module is then defined as a pointer to a structure that points to the module's fixed RAM address, for example, the first GPIO module named GPIOA: #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE), with GPIO_BASE being defined as the base address for the module. Using this structure, we have defined functions to configure and access the functionality of each module. The example given below sets the state for a microcontroller pin, given as the function parameters (port and pin) controlled by a GPIO module and uses the same standard data types as the ones used by CMSIS. The code also follows the MISRA C [17] coding guidelines to make safety- and security-critical embedded software safe, secure, portable, and reliable, and is annotated according to Doxygen [18] which can be used to automatically generate code documentation.