查看: 1160|回复: 1

[分享] LPC55S69之TrustZone

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
    发表于 2020-10-15 09:45:12 | 显示全部楼层 |阅读模式
    LPC55S69之TrustZone


    LPC55S69只有CPU0才支持TrustZone,这里用官方的例子来说明其用法。


    一、导入例子。
    11.png
    二、编译工程
    12.png
    分别在两个工程中点击Build。
    三、调试。
    13.png
    先选中s工程,再点击Debug,这里的调试会区别不同的工程。
    14.png
    期间会弹出窗口,点确定就行。


    四、运行。
    15.png
    点击运行。结果如下:
    16.png
    代码先从s区域开始,再通过函数指针跳到ns区域,所有代码均运行在CPU0中。


    而ns区域中比较的两个字符串均在ns区域中比较,这里没有和s区域进行交互,只是做个简单的切换。


    五、相关设置。
    17.png
    在s区域中,点击调试配置。
    18.png
    在s区域的Debug配置中,需要装载ns区域的axf可执行文件,这是切换工程的关键。
    19.png
    右击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工程均一样)
    1. #ifndef _VENEER_TABLE_
    2. #define _VENEER_TABLE_

    3. uint32_t GetTestCaseNumber_NSE(void);
    4. uint32_t SetTestCaseNumber_NSE(uint8_t flag , uint32_t value);

    5. #endif /* _VENEER_TABLE_ */
    复制代码
    veneer_table.c(在s工程中才有)
    1. #if (__ARM_FEATURE_CMSE & 1) == 0
    2. #error "Need ARMv8-M security extensions"
    3. #elif (__ARM_FEATURE_CMSE & 2) == 0
    4. #error "Compile with --cmse"
    5. #endif

    6. #include "stdint.h"
    7. #include "arm_cmse.h"
    8. #include "veneer_table.h"
    9. #include "fsl_debug_console.h"

    10. extern uint32_t GetTestCaseNumber(void);

    11. __attribute__((cmse_nonsecure_entry)) uint32_t GetTestCaseNumber_NSE(void) {
    12.     return GetTestCaseNumber();
    13. }

    14. __attribute__((cmse_nonsecure_entry)) uint32_t SetTestCaseNumber_NSE(uint8_t flag , uint32_t value) {
    15.         static uint32_t tmp = 0;
    16.         if(flag == 0) {
    17.                 tmp = value;
    18.         }
    19.         return tmp;
    20. }
    复制代码
    secure_faults_s.c
    1. #if (__ARM_FEATURE_CMSE & 1) == 0
    2. #error "Need ARMv8-M security extensions"
    3. #elif (__ARM_FEATURE_CMSE & 2) == 0
    4. #error "Compile with --cmse"
    5. #endif

    6. #include "fsl_device_registers.h"
    7. #include "fsl_debug_console.h"
    8. #include "arm_cmse.h"
    9. #include "board.h"
    10. #include "veneer_table.h"
    11. #include "tzm_config.h"
    12. #include "pin_mux.h"
    13. #include "clock_config.h"
    14. #include "fsl_ctimer.h"
    15. #include <stdbool.h>

    16. #define NON_SECURE_START 0x00010000

    17. typedef void (*funcptr_ns)(void) __attribute__((cmse_nonsecure_call));
    18. uint32_t testCaseNumber;

    19. void SystemInitHook(void) {
    20.     BOARD_InitTrustZone();
    21. }

    22. #define CTIMER CTIMER2                 /* Timer 2 */
    23. #define CTIMER_MAT_OUT kCTIMER_Match_1 /* Match output 1 */
    24. #define CTIMER_CLK_FREQ CLOCK_GetCTimerClkFreq(2U)
    25. void ctimer2_callback(uint32_t flags);
    26. volatile uint32_t g_pwmPeriod   = 0U;
    27. volatile uint32_t g_pulsePeriod = 0U;
    28. static ctimer_callback_t ctimer_callback[] = {ctimer2_callback};

    29. volatile uint32_t gCtimer100msCnt = 0U;
    30. volatile uint32_t gCtimer100msFlag = 0U;

    31. status_t CTIMER_GetPwmPeriodValue(uint32_t pwmFreqHz, uint8_t dutyCyclePercent, uint32_t timerClock_Hz) {
    32.     g_pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1;
    33.     if (dutyCyclePercent == 0) {
    34.         g_pulsePeriod = g_pwmPeriod + 1;
    35.     } else {
    36.         g_pulsePeriod = (g_pwmPeriod * (100 - dutyCyclePercent)) / 100;
    37.     }
    38.     return kStatus_Success;
    39. }

    40. void ctimer2_callback(uint32_t flags) {
    41.         uint32_t tmp = 0;
    42.         gCtimer100msFlag = 1;
    43.         if(gCtimer100msCnt > 9) { // 1second
    44.                 gCtimer100msCnt = 0;
    45.                 tmp = SetTestCaseNumber_NSE(1,0);
    46.                 PRINTF("secure world tmp addr=%x\r\n",&tmp);
    47.                 PRINTF("secure world tmp value=%d\r\n",tmp);
    48.         } else {
    49.                 gCtimer100msCnt++;
    50.         }
    51. }

    52. uint32_t GetTestCaseNumber() {
    53.     return testCaseNumber;
    54. }

    55. int main(void) {
    56.     funcptr_ns ResetHandler_ns;
    57.     ctimer_config_t config;
    58.     uint32_t timerClock;
    59.     CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
    60.     CLOCK_AttachClk(kFRO_HF_to_CTIMER2);

    61.     BOARD_InitPins();
    62.     BOARD_BootClockPLL150M();
    63.     BOARD_InitDebugConsole();

    64.     CTIMER_GetDefaultConfig(&config);
    65.     timerClock = CTIMER_CLK_FREQ / (config.prescale + 1);
    66.     CTIMER_Init(CTIMER, &config);
    67.     CTIMER_RegisterCallBack(CTIMER, &ctimer_callback[0], kCTIMER_SingleCallback);
    68.     CTIMER_GetPwmPeriodValue(10, 50, timerClock); // 10Hz = 100ms中断一次
    69.     CTIMER_SetupPwmPeriod(CTIMER, CTIMER_MAT_OUT, g_pwmPeriod, g_pulsePeriod, true);
    70.     CTIMER_StartTimer(CTIMER);

    71.     PRINTF("Hello from secure world!\r\n");

    72.     testCaseNumber = 2333;
    73.     PRINTF("secure world testCaseNumber addr=%x\r\n",&testCaseNumber);
    74.     PRINTF("secure world testCaseNumber value=%d\r\n",testCaseNumber);

    75.     __TZ_set_MSP_NS(*((uint32_t *)(NON_SECURE_START)));
    76.     SCB_NS->VTOR = NON_SECURE_START;
    77.     ResetHandler_ns = (funcptr_ns)(*((uint32_t *)((NON_SECURE_START) + 4U)));
    78.     PRINTF("Entering normal world.\r\n");

    79.     ResetHandler_ns();
    80.     while (1) {
    81.     }
    82. }
    复制代码
    secure_faults_ns.c
    1. #include "fsl_device_registers.h"
    2. #include "fsl_debug_console.h"
    3. #include "board.h"
    4. #include "veneer_table.h"
    5. #include "pin_mux.h"
    6. #include "clock_config.h"

    7. typedef void (*funcptr_ns)(void) __attribute__((cmse_nonsecure_call));

    8. void SystemInit(void) {
    9. }

    10. int main(void) {
    11.     uint32_t tmp = 0;
    12.     uint32_t testCaseNumber = 0;

    13.     PRINTF("Welcome in normal world!\r\n");
    14.     testCaseNumber = GetTestCaseNumber_NSE();
    15.     PRINTF("normal world testCaseNumber addr=%x\r\n",&testCaseNumber);
    16.     PRINTF("normal world testCaseNumber value=%d\r\n",testCaseNumber);

    17.     tmp = SetTestCaseNumber_NSE(0,666);
    18.     PRINTF("normal world tmp addr=%x\r\n",&tmp);
    19.     PRINTF("normal world tmp value=%d\r\n",tmp);
    20.     while (1) {
    21.     }
    22. }
    复制代码
    这里s工程需要使用CTimer定时器,需要在SDK Manager中设置,如下图所示。
    20.png
    勾选ctimer即可,如下图所示。
    21.png
    运行结果,如下图所示。
    22.png
    testCaseNumber的s区域和ns区域地址和下表的地址范围相吻合的,即SRAM的0x20000000~0x2FFFFFFF和0x30000000~0x3FFFFFFF。
    23.png
    而在ns区域中设置了tmp的值,在s区域中能读到。由于初始化时s区域利用函数指针跳转到ns区域了,所以只能用定时器中断的方式,去读tmp的值,当然也能使用其它的中断方式。
    而tmp的地址也是和SRAM的地址范围相吻合的。
    使用全局变量的方式,s区域无法读取ns区域中的全局变量gTmp。(这部分代码未公开,因为不可行)
    24.png
    综上所述,veneer_table.c和veneer_table.h,就是s区域和ns区域交互的桥梁。


    文章出处:CSDN

    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2020-10-15 10:27:16 | 显示全部楼层
    昨天也在看这部分功能的相当内容。
    在实际项目中,对于小规模的设计来着,很少会采用对称式设计——如果真有,直接两颗MCU简单而高效。
    这样下来,core0来处理数据即可,所以只有一颗设为core0的内核带有安全功能即可。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-20 12:00 , Processed in 0.110251 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表