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.

[参考译文] MSP430FR6989:可用于 IPE 保护的地址范围

Guru**** 2964790 points

Other Parts Discussed in Thread: MSP430FR6989

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/685470/msp430fr6989-range-of-addresses-available-for-ipe-protection

器件型号:MSP430FR6989

使用 CCS7.4.0:

我可以使用0x4800及以上的地址范围成功实现 IPE 保护。 (可能最小地址边界略低、无关紧要)。 但是、我希望保护地址范围0x00000到0x10000、例如地址范围0x00000到。  

这是可能的吗? 我可以使用 IPE (例如0x4800 THORH 0x4600)成功保护存储器

我当前的故障模式是、我获得了不可预测的代码执行。 本质上、处理器会在代码未受保护的区域周围跳过几行 C 代码。 很难调试/跟踪此行为、但我将其计数为"yrone"、并想知道我所做的事情是否存在根本错误。

2.是否有一种保护主/后台伪任务的"正确"方法、这样地址范围0x0000到{MEMORY ADDRESS x}将受到保护、但在该范围之外将受到保护?

提前感谢、

Joe

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

    Joe、您好!

    如果您对使用此器件的 IPE 感兴趣、我建议您查看本文档中的信息:

    这应该可以回答您的很多问题。  至于主存储器之外的较低地址范围、您是否正在尝试通过将外设和 SRAM 空间包含在 IPE 区域中来保护它们?  MPU/IPE 功能仅允许保护 FRAM 主程序存储器、而不允许保护外设空间和 SRAM 空间。  下面的系列用户指南中的图9-5对此进行了说明。

    此致、
    Walter

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

    谢谢 Walter、

    好的,现在我意识到了限制。  

    然而,我仍然不理解解决办法的局限性。 例如、我为 MSP430FR6989设置了闪烁 LED 应用、并将 blink.c 代码替换为:

    #include 
    #include 
    #include 
    
    #define memory_readonly_start (0x10000)
    #define memory_readonly_end (0x20000)
    
    void init_lock_memory( void )
    {
    //解锁对 MPU 的写入
    MPUCTL0 = MPUPW;
    
    //设置 MPU 边界。
    MPUSEGB1 = MEMORY_READONY_START >> 4;
    MPUSEGB2 = MEMORY_READONY_END >> 4、
    
    //设置 MPU 权限,对于调试,请将所有设置为 rwx....
    MPUSAM = MPUSEGIXE | MPUSEGIRE | MPUSEGIWE
    | MPUSEG1XE | MPUSEG1RE | MPUSEG1WE
    | MPUSEG2XE | MPUSEG2RE | MPUSEG2WE
    | MPUSEG3XE | MPUSEG3RE | MPUSEG3WE;
    
    MPUIPC0 = 0;
    
    //值与链接器命令文件中的值相同:
    MPUIPSEGB1 = 0x4000 >> 4;
    MPUIPSEGB2 = 0x5000 >> 4;
    
    MPUIPC0 = MPUIPENA;
    
    MPUCTL0 = MPUPW | MPUENA;
    }
    
    #pragma SET_DATA_SECTION (".IPE_vars")
    volatile uint16_t IPE_VALUE;
    #pragma SET_DATA_SECTION ()
    
    
    #pragma SET_CODE_SECTION (".IPE")
    void SET_VALUE ()
    {
    IPE_VALUE = 0x123;
    }
    
    uint16_t GET_VALUE ()
    {
    返回 IPE_VALUE;
    }
    #pragma SET_CODE_SECTION ()
    
    volatile uint16_t value;
    
    void main (void){
    WDTCTL = WDTPW | WDTHOLD;
    PM5CTL0 &=~LOCKLPM5;
    
    P1DIR = 0x13;//评估上有3个 LED
    init_lock_memory();
    
    P1OUT = 0;
    
    set_value();
    
    for (;;){
    volatile unsigned int i;
    
    set_value();
    value = get_value();
    
    if (值==0x123)
    {
    //应该在这里...
    P1OUT ^= 0x01;
    }
    其他
    {
    //但当 IPE mem 低位地址设置为0x4400时、始终转到此处。
    P1OUT ^= 0x02;
    //. 值设置为0xFFFF、而不是0x3FFF
    }
    
    IPE_VALUE = 0x456;//设置为不违反 PUC 时应忽略。
    value = get_value();//在此次调用后应该为0x123
    if (值==0x456)
    {
    //如果启用了 IPE,则不应在此处获取。
    P1OUT ^= 0x10;
    }
    
    I = 10000; // SW 延迟
    我----
    while (i!= 0);
    }
    }
    
    
    

    现在、如果我如上所述运行程序、MPUIPSEGB1 = 0x4000、MPUIPSEGB2 = 0x5000、则运行正常。 我的测试结果是、当值= 0x123为真时、当值= 0x456为假时、我假设 IPE 按预期工作。

    但是、如果我在运行此操作时更改 了使 MPUIPSEGB1 = 0x4400、那么当执行以下行时:

    set_value();
    value = get_value();

    在调试器中观察到、'Value'被以某种方式设置为0xFFFF。 值得注意的是、不是 IPE 保护读取所预期的0x3FFF。

    我可以确认、对于这两个构建、存储器映射文件的相关部分显示 IPE 受保护变量及其关联的例程已插入标称 IPE 受保护区域:

    (笑声) 起步

    00002360_stack
    00002400 __STACK_END
    00004400 fram_ipe_start
    00004400 fram_rw_start
    00004400 SET_VALUE
    00004408 get_value
    0000440e IPE_VALUE
    00004800 _c_int00_noargs
    00004800 fram_ipe_end
    00004800 fram_rx_start

    (笑声) 尖头

    (笑声) 因此、它似乎是所选地址范围的问题。 从 inker 脚本文件中、对齐1k 块:

    PALIGN (0x0400)、

    我想到了这种设置  

    MPUIPSEGB1 = 0x4400 >> 4;

    就足够了、但实际上不是。

    我看不到存储器对齐/块大小限制区域的位置。

    提前感谢、

    Joe

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

    Joe、您好!

    我构建并运行了您的代码片段、我相信您正面临以下限制:

    此信息位于系列 用户指南 第9.2.2节中。

    由于 SET_VALUE ()函数链接到0x4400,并且分区设置为0x4400,因此设置0x0123的写入操作永远不会完成,这是正确的行为。  这是因为写函数存在于保护区域的前8个字节中、因此它不能访问数据。  这会将 IPE_VALUE 变量的默认值保留为0xFFFF。  然后、当您读取它时、读取是成功的、因为读取函数位于前8个字节之后。  因此、它可以正确读取0xFFFF、而不是0x3FFF 的错误返回。  您可以通过将 IP 边界起始地址设置为较低(这很有趣)但不是有效用例来使其正常工作。

    根据 以下示例、我可以在 MPUIPSEGB1 = 0x4400时通过在受保护区域的开头添加一个虚拟8字节填充来使代码正确运行:

    #pragma DATA_SECTION (IPE_STRUCT_DUPLEN、".ipestruct")
    #pragma RETAIN (IPE_STRUCT_DUAL)
    volatile uint16_t IPE_STRUCT_虚设[4]={0}; 

    在这种情况下、您的函数从0x4408开始、而不是从0x4400开始、并且一切工作正常。

    我不确定您在使用实现方案时要实现什么、但我强烈建议您考虑让 IDE 为您配置所有 MPU 设置-这涵盖了几乎所有用例并为您处理所有设置。  您只需告诉它所需的地址范围、或让它自动配置。  我还可以通过选中工程属性中的复选框来使代码以这种方式运行(请参阅下图)。

    CCS 将为您配置初始化结构、并将其放置在前8个字节中。  那么、您完全无需担心任何 MPU 寄存器配置。

    此致、
    Walter

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢 Walter、他按描述的那样工作。 非常感谢您的支持质量和速度!
    我手动设置 MPU/IPE、因为应用程序有两个阶段:配置和操作。 这样调试就更简单了、因为我不需要复位 MPU、也不需要在其他模式下重新启动调试器。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    足够公平。 我现在将把这个标记为关闭、您可以随时发布您有的任何其他 PMU 问题、并在需要时链接到此主题以供参考。

    此致、
    Walter