1.4 Adding Application Logic to Secure Project
To develop and run the application, follow these steps:
- Open the main.c file of the
Secure project and add the following application logic. Add the following code to
the register RTC event handlers for a 500 ms compare event.
RTC_Timer32CallbackRegister (rtcEventHandler, 0)
; and add the following code to the EIC callback event handler for the switch press eventEIC_CallbackRegister (EIC_PIN_12, sw0_eventHandler, 0)
; in themain()
function andSYS_Initialize (NULL)
function below:RTC_Timer32CallbackRegister(rtcEventHandler, 0); EIC_CallbackRegister(EIC_PIN_12, sw0_eventHandler, 0); sprintf((char*)uartTxTempBuffer, "************* Printing Toggling LED rate *************\r\n"); readUartTxStatus = true;
- Add the line of code to call the
RTC_Timer32Start();
function after registering the callback event handlers.Figure 1-19. Adding Application Logic to Register Callback Event Handlers - Implement the registered callback
event handlers for Secure peripherals by adding the following code outside the
main()
function.static void sw0_eventHandler(uintptr_t context) { changeSamplingRate = true; } static void rtcEventHandler (RTC_TIMER32_INT_MASK intCause, uintptr_t context) { if (intCause & RTC_TIMER32_INT_MASK_CMP0) { isRTCTimerExpired = true; } }
- In the
secureApp()
function, add the application logic of toggling LED at different rates of 500 ms, 1s, 2s, and 4s whenever there is a switch press on the board by the user before themain()
function in Secure project.Note: Add this function outside themain()
function.void secureApp(void) { /* Basic Functionality: Demonstrates an LED toggle, i.e. LED0 toggles when * the switch SW0 is pressed on a timeout basis and prints the LED toggling * rate on the serial terminal.*/ if (printLedToggleRate == true) { memset((char*)uartTxTempBuffer, 0x00, 100); sprintf((char*)uartTxTempBuffer, "************* Printing Toggling LED rate *************\r\n"); printLedToggleRate = false; readUartTxStatus = true; } if (isRTCTimerExpired == true) { isRTCTimerExpired = false; memset((char*)uartTxTempBuffer, 0x00, 100); sprintf((char*)uartTxTempBuffer, "Toggling LED at %s rate \r\n", &timeouts[(uint8_t)tempSampleRate][0]); LED0_Toggle(); readUartTxStatus = true; } if(changeSamplingRate == true) { changeSamplingRate = false; if(tempSampleRate == SAMPLING_RATE_500MS) { tempSampleRate = SAMPLING_RATE_1S; RTC_Timer32CompareSet(PERIOD_1S); } else if(tempSampleRate == SAMPLING_RATE_1S) { tempSampleRate = SAMPLING_RATE_2S; RTC_Timer32CompareSet(PERIOD_2S); } else if(tempSampleRate == SAMPLING_RATE_2S) { tempSampleRate = SAMPLING_RATE_4S; RTC_Timer32CompareSet(PERIOD_4S); } else if(tempSampleRate == SAMPLING_RATE_4S) { tempSampleRate = SAMPLING_RATE_500MS; RTC_Timer32CompareSet(PERIOD_500MS); } else { ; } RTC_Timer32CounterSet(0); sprintf((char*)uartTxTempBuffer, "LED Toggling rate is changed to %s\r\n", &timeouts[(uint8_t)tempSampleRate][0]); readUartTxStatus = true; } }
Add the following code snippet to include the necessary header files, and define the macros for different RTC compare values.Note: Add this logic at start of the file to include necessary files which have definitions of functions used in the file.#include <stdio.h> #include <string.h> #define PERIOD_500MS 512 #define PERIOD_1S 1024 #define PERIOD_2S 2048 #define PERIOD_4S 4096
Add the following code snippet after including the header files.
The following codes declare various flags whose status is monitored and changed by event handlers in the application.static volatile bool isRTCTimerExpired = false; static volatile bool changeSamplingRate = false; static volatile bool printLedToggleRate = false; static const char timeouts[4][20] = {"500 milliSeconds", "1 Second", "2 Seconds", "4 Seconds"}; volatile bool readUartTxStatus = false; uint8_t uartTxTempBuffer[100] = {0}; typedef enum { SAMPLING_RATE_500MS = 0, SAMPLING_RATE_1S = 1, SAMPLING_RATE_2S = 2, SAMPLING_RATE_4S = 3, } SAMPLING_RATE; static SAMPLING_RATE tempSampleRate = SAMPLING_RATE_500MS;
- In the
nonsecure_entry.c
file, availble under Source Files > trustZone, implement the Non-Secure callables below to access and request the Secure application from the Non-Secure application.Note: Delete the generated template code and add the following code.bool __attribute__((cmse_nonsecure_entry)) readUartTxData(uint8_t *lcluartTxBuffer) { bool localSecureUartStatus = readUartTxStatus; if(localSecureUartStatus == true) { memset((char*)lcluartTxBuffer, 0x00, 100); memcpy(lcluartTxBuffer, uartTxTempBuffer, strlen((const char *)&uartTxTempBuffer[0])); readUartTxStatus = false; } return (localSecureUartStatus); } void __attribute__((cmse_nonsecure_entry)) secureAppEntry(void) { secureApp(); }
Add the following code snippet to include necessary header files and extern the variables and prototype of the SecureApp() function whose implementation takes place in the Securemain.c
file.#include <stdint.h> #include <stdio.h> #include <stddef.h> // Defines NULL #include <stdbool.h> // Defines true #include <stdlib.h> // Defines EXIT_FAILURE #include <string.h> extern uint8_t uartTxTempBuffer[]; extern volatile bool readUartTxStatus; extern void secureApp(void);