Arm® TrustZone® Getting Started Application on SAM L11: Step 6
Add Application Code to the Non-Secure Project
The application is already partially developed and is available in the main_l11.c file under <your unzip folder>/saml11_getting_started/dev_files/NonSecure. The main_l11.c file contains the application logic. It also contains placeholders that you will populate with the necessary code in the next step.
Open the trustzone_sam_l11_xpro_NonSecure project main_l11.c in MPLAB® X IDE and add the application code by following the steps:
Under the main_l11.c file, in function main, notice the call to the SYS_Initialize function.
The generated SYS_Initialize function initializes all the peripheral modules used in the non-secure application, which is configured through MPLAB® Code Configurator (MCC).
In the main() function, below SYS_Initialize(), add the following code to register callback event handlers.
DMAC_ChannelCallbackRegister(DMAC_CHANNEL_1, usartRxDmaChannelHandler, 0);
Following the addition of the code above, add the function call to receive a character from the serial terminal.
Implement the registered callback event handlers for the DMA PLIB (for both channels) by adding the following code before the non-secure main() function in main_l11.c.
{
if (event == DMAC_TRANSFER_EVENT_COMPLETE)
{
isUSARTTxComplete = true;
}
}
static void usartRxDmaChannelHandler(DMAC_TRANSFER_EVENT event, uintptr_t contextHandle)
{
if (event == DMAC_TRANSFER_EVENT_COMPLETE)
{
isEEPROMReadReq = true;
}
}
Implement the EEPROM data print function to print the last five temperature values received from the secure application.
{
char* pBuffer = (char*)nonSecureUartTxBuffer;
uint8_t len;
uint8_t i;
len = sprintf((char*)pBuffer, "EEPROM:");
for (i = wrIndex; i < EEPROM_MAX_LOG_VALUES; i++)
{
len += sprintf((char*)&pBuffer[len], "%dF|", (int8_t)pTemperatureValue[i]);
}
if (wrIndex > 0)
{
for (i = 0; i < wrIndex; i++ )
{
len += sprintf((char*)&pBuffer[len], "%dF|", (int8_t)pTemperatureValue[i]);
}
}
len += sprintf((char*)&pBuffer[len], "\r\n");
DMAC_ChannelTransfer(DMAC_CHANNEL_0, nonSecureUartTxBuffer, \
(const void *)&(SERCOM0_REGS->USART_INT.SERCOM_DATA), \
strlen((const char*)nonSecureUartTxBuffer));
}
Add the following code to print the received temperature values from the secure application on the serial terminal.
{
// Printing Temperature value read from Sensor
DMAC_ChannelTransfer(DMAC_CHANNEL_0, nonSecureUartTxBuffer, \
(const void *)&(SERCOM0_REGS->USART_INT.SERCOM_DATA), \
strlen((const char*)nonSecureUartTxBuffer));
}
Add the following code to request the secure application to read the last five values stored in the EEPROM by using non-secure Callables (NSCs) when a character on the serial terminal is received.
{
isEEPROMReadReq = false;
readEEPROMTemperatureDataReq(&eepromRxBuffer[1]);
}
Add the following code to print the last five temperature values on the serial terminal and also a function call to receive a character from the serial terminal when the requested last five stored temperature values are read from the EEPROM in the secure application.
{
isEEPROMReadReq = false;
EEPROM_PrintTemperature(&eepromRxBuffer[1], wrIndex);
DMAC_ChannelTransfer(DMAC_CHANNEL_1, (const void *)&(SERCOM0_REGS->USART_INT.SERCOM_DATA), \
&uartRxBuffer[1], 1);
}
Add the following code to run the complete secure functionality from this non-secure application.
Under Header Files > trustZone, in the nonsecure_entry.h file, add the following code to extern the NSCs to access and request the secure application from the non-secure application.
extern bool readTemperatureData(uint8_t *lcluartTxBuffer);
extern void readEEPROMTemperatureDataReq(uint8_t *temperatureBuf);
extern bool getEEPROMTemperatureDataReadStatus(uint8_t *LclWrIndex);
extern void secureAppEntry(void);
You are now ready to build the code!