This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSPM0G3519:基于 ARM 的微控制器论坛

Guru**** 2575725 points
Other Parts Discussed in Thread: MSPM0G3519

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1573427/mspm0g3519-arm-based-microcontrollers-forum

器件型号:MSPM0G3519


工具/软件:

大家好、我正在使用 mspm0g3519 控制器。 我根据客户安全代码的引用设计了自定义引导加载程序。  我有一个疑问。 为什么建议在运行客户安全代码时使用优化级别 2 或更高版本? 为什么此代码不适用于优化级别 0?  即使我尝试使用其示例应用程序代码运行客户安全代码(来自 SDK 启动映像管理器)示例代码时也是如此。 它只能用于-O2、不能用于-O0。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    任何更新人员?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    您能描述一下观察到的行为吗?

    马修

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、  

    我从 SDK 中获取了客户安全代码和示例。 优化级别 2 的代码即可正常工作。 表示客户安全代码完全跳转到示例代码。 但当我将优化级别更改为 0 (-O0) 时、客户安全代码不会跳转到应用代码。 优化级别是否会影响客户安全代码中的跳转逻辑代码?  这是来自客户安全代码的代码片段。  

    static void start_app(uint32_t *vector_table)
    {
        /* The following code resets the SP to the value specified in the
         * provided vector table, and then the Reset Handler is invoked.
         *
         * Per ARM Cortex specification:
         *
         *           ARM Cortex VTOR
         *
         *
         *   Offset             Vector
         *
         * 0x00000000  ++++++++++++++++++++++++++
         *             |    Initial SP value    |
         * 0x00000004  ++++++++++++++++++++++++++
         *             |         Reset          |
         * 0x00000008  ++++++++++++++++++++++++++
         *             |          NMI           |
         *             ++++++++++++++++++++++++++
         *             |           .            |
         *             |           .            |
         *             |           .            |
         *
         * */
    
        /* Reset the SP with the value stored at vector_table[0] */
        __asm volatile(
            "LDR R3,[%[vectab],#0x0] \n"
            "MOV SP, R3       \n" ::[vectab] "r"(vector_table));
    
        /* Set the Reset Vector to the new vector table (Will be reset to 0x000) */
        SCB->VTOR = (uint32_t) vector_table;
    
        /* Jump to the Reset Handler address at vector_table[1] */
    
        ((void (*)(void))(*(vector_table + 1)))();
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否看到过这样的行为? CSC 是否测试优化级别低于 2?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    该设置还会发生什么情况? 您能解释一下是否有其他运行中的内容可能会影响该行为吗?

    您能在地图上做一个比较来查看 O2 和 O0 之间有什么不同吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    代码进入硬故障。 我已检查了两种优化的汇编文件。  

    Optimization level 2. (code work fine)
    0x00001810  4818      ldr     r0, [pc, #0x60]      ; Load immediate address (string/format) into r0
    0x00001812  211F      movs    r1, #0x1f            ; r1 = 0x1F
    0x00001814  02CD      lsls    r5, r1, #0xb         ; r5 = 0x1F << 11 (vector table address base)
    0x00001816  4629      mov     r1, r5               ; Move r5 → r1 (bit_printf arg)
    
    0x0000181C  682B      ldr     r3, [r5]             ; r3 = *(r5) (new stack pointer)
    0x0000181E  469D      mov     r13, r3              ; Set SP = *(r5)
    
    0x00001820  4815      ldr     r0, [pc, #0x54]      ; Load address (VTOR reg addr) into r0
    0x00001822  6005      str     r5, [r0]             ; Write new vector table base to VTOR
    0x00001824  CD06      ldm     r5!, {r1, r2}        ; Load r1=*(r5), r2=*(r5+4), then r5+=8
    0x00001826  4815      ldr     r0, [pc, #0x54]      ; Reload VTOR addr into r0
    0x00001828  3D08      subs    r5, #8               ; Restore r5 back (undo ldm increment)
    0x0000182E  4811      ldr     r0, [pc, #0x44]      ; Load another format string address
    0x00001830  4629      mov     r1, r5               ; r1 = r5
    
    0x00001836  6868      ldr     r0, [r5, #4]         ; r0 = *(r5+4) (reset handler address)
    0x00001838  4780      blx     r0                   ; Jump to application reset handler
    
    0x0000183A  4620      mov     r0, r4               ; r0 = r4 (not used, dead code)
    0x0000183C  F000FC8E  bl      DL_Common_delayCycles; Delay (dead code after jump)
    
    
    
    Optimization level 0 (not jump to aaplication code)
    0x00001AD8  B580      push    {r7, r14}            ; Save frame pointer and LR
    0x00001ADA  B082      sub     r13, #8              ; Allocate 8 bytes stack
    
    0x00001ADC  9001      str     r0, [r13, #4]        ; Save argument (app base addr) to stack
    0x00001ADE  E7FF      b       #0x1ae0              ; Jump to next instruction (compiler artifact)
    0x00001AE0  9901      ldr     r1, [r13, #4]        ; r1 = saved arg
    0x00001AE2  480E      ldr     r0, [pc, #0x38]      ; Load format string addr
    0x00001AE8  E7FF      b       #0x1aea              ; Compiler artifact
    0x00001AEA  9801      ldr     r0, [r13, #4]        ; r0 = app base addr
    0x00001AEC  6803      ldr     r3, [r0]             ; r3 = *(app base) (stack pointer value)
    0x00001AEE  469D      mov     r13, r3              ; Set SP = *(app base)
    0x00001AF0  9801      ldr     r0, [r13, #4]        ; r0 = *(app base+4) (reset handler)
    0x00001AF2  490B      ldr     r1, [pc, #0x2c]      ; r1 = VTOR address
    0x00001AF4  6008      str     r0, [r1]             ; Write new vector table base
    0x00001AF6  E7FF      b       #0x1af8              ; Compiler artifact
    0x00001AF8  9801      ldr     r0, [r13, #4]        ; r0 = app base
    0x00001AFA  6801      ldr     r1, [r0]             ; r1 = *(app base) (stack pointer value)
    0x00001AFC  6842      ldr     r2, [r0, #4]         ; r2 = *(app base+4) (reset handler addr)
    0x00001AFE  4809      ldr     r0, [pc, #0x24]      ; Load format string addr
    0x00001B04  E7FF      b       #0x1b06              ; Compiler artifact
    0x00001B06  E7FF      b       #0x1b08              ; Compiler artifact
    0x00001B08  9901      ldr     r1, [r13, #4]        ; r1 = app base addr
    0x00001B0A  4804      ldr     r0, [pc, #0x10]      ; Load format string addr
    0x00001B10  E7FF      b       #0x1b12              ; Compiler artifact
    0x00001B12  9801      ldr     r0, [r13, #4]        ; r0 = app base addr
    0x00001B14  6840      ldr     r0, [r0, #4]         ; r0 = *(app base+4) (reset handler addr)
    
    0x00001B16  4780      blx     r0                   ; Jump to application reset handler
    0x00001B18  B002      add     r13, #8              ; restore stack after jump
    0x00001B1A  BD80      pop     {r7, pc}             ; Restore registers and return

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果可能、请尝试结束时使用可用的示例代码、以获得更好的曝光效果。 这些示例代码是否存在实际问题、或者是否缺少某些内容?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它看起来好像 C 代码加载 SP 太早了;使用-O0 时、它随后引用一个(悬空)栈变量、但使用-O2 时则不引用。 (即使有-O2 我会说它“意外工作“。

    我不确定这本身是一个编译器错误,因为它无法了解 SP(在__asm () 中是否有一个“clobber"选项“选项?)。

    我在 boot_manager/customer_secure_code 中未找到此代码。 您能给我们提示一下它在哪里吗?

    [编辑:啊、我在 customer_secure_code.c 中找到了它。]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Bruce

    customer_secure_code 这是代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、它位于 customer_secure_code.c 中

    我想您已经确定了问题、但我不知道 TI 的计划是什么。

    “-O2"变通“变通办法是否适合您的用途?

    或者:一个相当简单的更改可能是将 vector_table 变量复制到局部“static"(“(.bss 而不是栈)变量、并将其用在函数的其余部分。  .bss 不会移动太多。

    [编辑:为了更好地衡量,请将新变量声明为“volatile “,这样优化器就不会得到任何“不正确“的想法。]

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们正在内部工作、看看这里会发生什么

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    就我个人而言,我会在一个__ asm () 语句中执行 load-SP 和调用,但我不能实际尝试它。 我的建议似乎更有可能第一次起作用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    你是对的--发生这种硬故障是因为 start_app 函数在栈指针被移动到-O0 后试图访问栈上的值。

    我们建议在本示例中使用-O2 或更高版本。 如果整个函数是汇编函数,则 O0 可以工作,但我们通过用 C 语言编写来使其更易于阅读

    可以声明矢量表易失性静态、但这会消耗存储器和周期。

    马修

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨 Bruce ,我已经尝试加载 sp,然后调用,但板重新启动再次和 againe 到引导加载程序代码,我放入闪存开始 (0x00000000),这似乎是代码跳到引导加载程序再次.  

      _asm volatile (
         “LDR R3、[%[vectab]、#0x0]\n“//加载初始 SP 值
         “MSR MSP、R3         \n“//将 MSP 设置为初始 SP 值
         “LDR R3、[%[vectab]、#0x4]\n“//加载 Reset_Handler 地址
         “BX R3            \n“//分支到 Reset_Handler
         :[vectab]“r"(“(vector_table)
       );
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    为了我的目的、我希望使用 O0 级别运行代码。 您能不能更清楚为什么这个代码在-O0 级别上出现故障?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否删除了另一个_asm、即设置 SP 的_asm? 这就是事情开始出错的地方。

    具体来说:在-O0 情况下、汇编列表的第 37 行将 SP 设置到应用程序的栈、但随后第 38 行(然后是第 42 行)返回、从(旧)栈中获取 vector_table 的值、该值已消失。

    对于-O2 情况、第 8 行设置 SP、但到那时所有局部变量【好的,只有一个】都已在寄存器中、因此不需要返回到栈副本【好的是,因为没有任何】。 优化器不能保证执行此操作、但通常会执行此操作。

    理论上、您可以移动将 SP 设置为调用之前最后一个内容的_asm、但调用仍可以引用栈(第 42 行)。 我建议的技巧是让生成的代码查看其他地方、以防止引用栈。 这有点笨拙、但它是正常的 C。[我预计这个代码大约每年执行一次、因此 4 个字节和几个额外的时钟无关紧要。]

    也就是说、我在您的_asm 中没有看到任何明显的内容、除非是这样

    (a) 您使用的是 R3 、但没有将其声明为(伪)输出参数 — 编译器可能为[vectab]和分配了 R3

    (B) 我本来会使用“MOV SP、R3“而不是 MSR、但这主要是因为我不必仔细研究 Cortex-M0 文档、才能记住我是想要 MSP 还是 PSP。

    【编辑:轻微澄清。】

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    具体来说、类似于【未测试】

    static void start_app(uint32_t *vector_table)
    {
        static uint32_t * volatile bss_vector_ptr; // So it doesn't move
        bss_vector_ptr = vector_table;
        
        /* Set the Reset Vector to the new vector table (Will be reset to 0x000) */
        SCB->VTOR = (uint32_t) bss_vector_ptr;
    
        /* Reset the SP with the value stored at vector_table[0] */
        __asm volatile(
            "LDR R3,[%[vectab],#0x0] \n"
            "MOV SP, R3       \n" ::[vectab] "r"(bss_vector_ptr));
    
        /* Jump to the Reset Handler address at vector_table[1] */
    
        ((void (*)(void))(*(bss_vector_ptr + 1)))();
    }

    [编辑:固定的 goof]

    【编辑:已测试】

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    或者:

    void
    start_app(uint32_t *vector_table)
    {
        SCB->VTOR = (uint32_t) vector_table;
        __asm volatile(
           "MOV SP,%[newSP]  \n"
           "BLX %[newPC]     \n"
                :
                :[newSP] "r" (vector_table[0]), [newPC] "r" (vector_table[1])
                :
           );
        return;
    }