在线时间4067 小时
UID3441752
注册时间2017-11-21
NXP金币759430
TA的每日心情 | 开心 2024-3-26 15:16 |
---|
签到天数: 266 天 [LV.8]以坛为家I
管理员
- 积分
- 32003
- 最后登录
- 2024-4-9
|
LPC55S69之TrustZone
LPC55S69只有CPU0才支持TrustZone,这里用官方的例子来说明其用法。
一、导入例子。
二、编译工程
分别在两个工程中点击Build。
三、调试。
先选中s工程,再点击Debug,这里的调试会区别不同的工程。
期间会弹出窗口,点确定就行。
四、运行。
点击运行。结果如下:
代码先从s区域开始,再通过函数指针跳到ns区域,所有代码均运行在CPU0中。
而ns区域中比较的两个字符串均在ns区域中比较,这里没有和s区域进行交互,只是做个简单的切换。
五、相关设置。
在s区域中,点击调试配置。
在s区域的Debug配置中,需要装载ns区域的axf可执行文件,这是切换工程的关键。
右击ns工程->属性->MCU Settings中,可以看到ns工程是烧写在Flash的0x10000地址中,和s工程的DEMO_CODE_START_NS地址相一致,这就是函数指针跳转的地址。
六、ns区域与s区域交互数据。
可以参考官方的例子lpcxpresso55s69_secure_faults。
1、ns区域读s区域中的变量。
其中GetTestCaseNumber_NSE()函数,同时在s和ns工程的veneer_table.h中声明,但是只在s工程中的veneer_table.c中实现。
在ns工程调用GetTestCaseNumber_NSE()函数,可以读取到s工程中的testCaseNumber变量。
2、s区域设置ns区域中的变量。
在veneer_table.c中做一个带静态变量的函数,用于s区域和ns区域之间的变量传递。
其代码如下:
veneer_table.h(s工程和ns工程均一样)
- #ifndef _VENEER_TABLE_
- #define _VENEER_TABLE_
-
- uint32_t GetTestCaseNumber_NSE(void);
- uint32_t SetTestCaseNumber_NSE(uint8_t flag , uint32_t value);
-
- #endif /* _VENEER_TABLE_ */
复制代码 veneer_table.c(在s工程中才有)
- #if (__ARM_FEATURE_CMSE & 1) == 0
- #error "Need ARMv8-M security extensions"
- #elif (__ARM_FEATURE_CMSE & 2) == 0
- #error "Compile with --cmse"
- #endif
-
- #include "stdint.h"
- #include "arm_cmse.h"
- #include "veneer_table.h"
- #include "fsl_debug_console.h"
-
- extern uint32_t GetTestCaseNumber(void);
-
- __attribute__((cmse_nonsecure_entry)) uint32_t GetTestCaseNumber_NSE(void) {
- return GetTestCaseNumber();
- }
-
- __attribute__((cmse_nonsecure_entry)) uint32_t SetTestCaseNumber_NSE(uint8_t flag , uint32_t value) {
- static uint32_t tmp = 0;
- if(flag == 0) {
- tmp = value;
- }
- return tmp;
- }
复制代码 secure_faults_s.c
- #if (__ARM_FEATURE_CMSE & 1) == 0
- #error "Need ARMv8-M security extensions"
- #elif (__ARM_FEATURE_CMSE & 2) == 0
- #error "Compile with --cmse"
- #endif
-
- #include "fsl_device_registers.h"
- #include "fsl_debug_console.h"
- #include "arm_cmse.h"
- #include "board.h"
- #include "veneer_table.h"
- #include "tzm_config.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "fsl_ctimer.h"
- #include <stdbool.h>
-
- #define NON_SECURE_START 0x00010000
-
- typedef void (*funcptr_ns)(void) __attribute__((cmse_nonsecure_call));
- uint32_t testCaseNumber;
-
- void SystemInitHook(void) {
- BOARD_InitTrustZone();
- }
-
- #define CTIMER CTIMER2 /* Timer 2 */
- #define CTIMER_MAT_OUT kCTIMER_Match_1 /* Match output 1 */
- #define CTIMER_CLK_FREQ CLOCK_GetCTimerClkFreq(2U)
- void ctimer2_callback(uint32_t flags);
- volatile uint32_t g_pwmPeriod = 0U;
- volatile uint32_t g_pulsePeriod = 0U;
- static ctimer_callback_t ctimer_callback[] = {ctimer2_callback};
-
- volatile uint32_t gCtimer100msCnt = 0U;
- volatile uint32_t gCtimer100msFlag = 0U;
-
- status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint8_t dutyCyclePercent, uint32_t timerClock_Hz) {
- g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1;
- if (dutyCyclePercent == 0) {
- g_pulsePeriod = g_pwmPeriod + 1;
- } else {
- g_pulsePeriod = (g_pwmPeriod * (100 - dutyCyclePercent)) / 100;
- }
- return kStatus_Success;
- }
-
- void ctimer2_callback(uint32_t flags) {
- uint32_t tmp = 0;
- gCtimer100msFlag = 1;
- if(gCtimer100msCnt > 9) { // 1second
- gCtimer100msCnt = 0;
- tmp = SetTestCaseNumber_NSE(1,0);
- PRINTF("secure world tmp addr=%x\r\n",&tmp);
- PRINTF("secure world tmp value=%d\r\n",tmp);
- } else {
- gCtimer100msCnt++;
- }
- }
-
- uint32_t GetTestCaseNumber() {
- return testCaseNumber;
- }
-
- int main(void) {
- funcptr_ns ResetHandler_ns;
- ctimer_config_t config;
- uint32_t timerClock;
- CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
- CLOCK_AttachClk(kFRO_HF_to_CTIMER2);
-
- BOARD_InitPins();
- BOARD_BootClockPLL150M();
- BOARD_InitDebugConsole();
-
- CTIMER_GetDefaultConfig(&config);
- timerClock = CTIMER_CLK_FREQ / (config.prescale + 1);
- CTIMER_Init(CTIMER, &config);
- CTIMER_RegisterCallBack(CTIMER, &ctimer_callback[0], kCTIMER_SingleCallback);
- CTIMER_GetPwmPeriodValue(10, 50, timerClock); // 10Hz = 100ms中断一次
- CTIMER_SetupPwmPeriod(CTIMER, CTIMER_MAT_OUT, g_pwmPeriod, g_pulsePeriod, true);
- CTIMER_StartTimer(CTIMER);
-
- PRINTF("Hello from secure world!\r\n");
-
- testCaseNumber = 2333;
- PRINTF("secure world testCaseNumber addr=%x\r\n",&testCaseNumber);
- PRINTF("secure world testCaseNumber value=%d\r\n",testCaseNumber);
-
- __TZ_set_MSP_NS(*((uint32_t *)(NON_SECURE_START)));
- SCB_NS->VTOR = NON_SECURE_START;
- ResetHandler_ns = (funcptr_ns)(*((uint32_t *)((NON_SECURE_START) + 4U)));
- PRINTF("Entering normal world.\r\n");
-
- ResetHandler_ns();
- while (1) {
- }
- }
复制代码 secure_faults_ns.c
- #include "fsl_device_registers.h"
- #include "fsl_debug_console.h"
- #include "board.h"
- #include "veneer_table.h"
- #include "pin_mux.h"
- #include "clock_config.h"
-
- typedef void (*funcptr_ns)(void) __attribute__((cmse_nonsecure_call));
-
- void SystemInit(void) {
- }
-
- int main(void) {
- uint32_t tmp = 0;
- uint32_t testCaseNumber = 0;
-
- PRINTF("Welcome in normal world!\r\n");
- testCaseNumber = GetTestCaseNumber_NSE();
- PRINTF("normal world testCaseNumber addr=%x\r\n",&testCaseNumber);
- PRINTF("normal world testCaseNumber value=%d\r\n",testCaseNumber);
-
- tmp = SetTestCaseNumber_NSE(0,666);
- PRINTF("normal world tmp addr=%x\r\n",&tmp);
- PRINTF("normal world tmp value=%d\r\n",tmp);
- while (1) {
- }
- }
复制代码 这里s工程需要使用CTimer定时器,需要在SDK Manager中设置,如下图所示。
勾选ctimer即可,如下图所示。
运行结果,如下图所示。
testCaseNumber的s区域和ns区域地址和下表的地址范围相吻合的,即SRAM的0x20000000~0x2FFFFFFF和0x30000000~0x3FFFFFFF。
而在ns区域中设置了tmp的值,在s区域中能读到。由于初始化时s区域利用函数指针跳转到ns区域了,所以只能用定时器中断的方式,去读tmp的值,当然也能使用其它的中断方式。
而tmp的地址也是和SRAM的地址范围相吻合的。
使用全局变量的方式,s区域无法读取ns区域中的全局变量gTmp。(这部分代码未公开,因为不可行)
综上所述,veneer_table.c和veneer_table.h,就是s区域和ns区域交互的桥梁。
文章出处:CSDN
|
|