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.

[参考译文] MSP430FR5962:MPU 违反后、通过 FRAM 访问 INFO 变量、导致我的器件挂起。

Guru**** 2439710 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1032974/msp430fr5962-accessing-info-variables-via-fram-after-mpu-violation-causing-my-device-to-be-hanged

器件型号:MSP430FR5962

各位专家、您好!

我正在尝试实现失效防护功能、如果发生 MPU 违规、器件应通过 fram 写入函数访问信息变量并设置标志、以便我们可以编写一个函数、从备份存储器恢复代码。 但是、在 MPU 违规导致我的器件完全挂起、甚至我要访问的信息区域都设置为00后、通过 FRAM 写入来访问信息变量。 我搜索过大多数文档、但没有找到任何有关此问题的信息、我可以找到正确的答案。 是否有人可以指出 TI 是否记录过该问题、或者回答我的这个问题、即导致 MPU 违反的行为将导致器件被欺骗、除非 PUC 复位或刷写新新代码?
请尽快尝试对此提供帮助。

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

    1) 1)我不太清楚您的症状。 您的程序(A)是否冻结? (b)反复重置? (c)挂起调试器?

    2) 2)请记住、MPU 不是被 PUC 禁用的、尤其是由违规引起的 PUC、所以您可能需要先设置 MPUENA=0。 (您是否在另一个线程中执行过此操作?)

    3) 3) MPU 寄存器是如何设置的? 特别需要注意的是信息段的定义方式。 您是否在违规时请求 PUC?

    4) 4)我已经使用 CCS MPU 设置 GUI 获得了一些里程、然后加载程序并查看 MPU 寄存器、以查看我是否正确阅读了用户指南。

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

    您好、Bruce、

    第一个问题的答案是、当我访问/写入 FRAM 变量时、我的调试器会挂起。

    对于第二个问题、我纠正了我的错误、我将把我的代码附加到这个线程中。

    请找到我的代码以检查 MPU 寄存器配置

    #include <MSP430FR5962.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    
    typedef struct
    {
        bool FW_MPU_Violation;
    }st_mpu_flag;
    
    #pragma location="INFOA"   
    const st_mpu_flag stMPUFlag_bkup = 
    {
      .FW_MPU_Violation = 0,
    };
    
    st_mpu_flag stMPUFlag;
    const st_mpu_flag stMPUFlag_bkup;
    
    unsigned int *ptr = 0;
    unsigned int Data =0;
    
    
    void fram_write(unsigned long ulFramAddress, const uint8_t *ulFwBuff,
                        uint16_t ucDataCount)
    {
    //  unsigned int i;
      unsigned long * Fram_ptr;
      uint16_t count;
    
      union un_data
      {
          uint8_t ucData[4];
          uint32_t ulData;
      } unData;
    
      Fram_ptr = (unsigned long *)ulFramAddress;     // Initialize write address
      count = ucDataCount/4 ;
    
      do
      {
        unData.ucData[0] = *ulFwBuff++;
        unData.ucData[1] = *ulFwBuff++;
        unData.ucData[2] = *ulFwBuff++;
        unData.ucData[3] = *ulFwBuff++;
        *Fram_ptr++ = unData.ulData;                // Write long int to Flash
        count--;
      }while(count);        
      __delay_cycles(800000);
    }
    
    int main(void)
    {
       WDTCTL = WDTPW | WDTHOLD; // Stop WDT
       
       // Configure GPIO
       PJDIR |= BIT7; // Configure P1.0 for LED
       
       // Disable the GPIO power-on default high-impedance mode to activate
       // previously configured port settings
       PM5CTL0 &= ~LOCKLPM5;
       
       while (MPUCTL1 & MPUSEG2IFG) // has reset occurred due to Seg2
       {
           PJOUT ^= BIT7; // Toggle LED
           __delay_cycles(30000); // Delay to see toggle
           
           MPUCTL0 = MPUPW;
           MPUCTL1 &= ~MPUSEG2IFG;
           stMPUFlag.FW_MPU_Violation = true;
           /* it is getting reset after the violation when it is trying to execute the below statements*/
           fram_write((unsigned long)&stMPUFlag_bkup,(const uint8_t*)&stMPUFlag,sizeof(stMPUFlag));
       }
       memcpy((void*)&stMPUFlag,(const void*)&stMPUFlag_bkup,sizeof(stMPUFlag_bkup));
       // Configure MPU
       MPUCTL0 = MPUPW; // Write PWD to access MPU registers
       MPUSEGB1 = 0x0F00; // B1 = 0x6000; B2 = 0x8000
       MPUSEGB2 = 0x0FF7; // Borders are assigned to segments
       
       // Segment 1 - Execute, Read
       // Segment 2 - Violation, Execute, Read
       // Segment 3 - Execute, Read
       MPUSAM = MPUSEG1RE | MPUSEG1XE | MPUSEG1WE |
                MPUSEG2VS | MPUSEG2RE | MPUSEG2XE |
                MPUSEG3RE | MPUSEG3XE | MPUSEG3WE |
                MPUSEGIRE | MPUSEGIXE | MPUSEGIWE;
       MPUCTL0 = MPUPW | MPUENA | MPUSEGIE;
       
       Data = 0x88;
       
       // Cause an MPU violation by writing to segment 2
       ptr = (unsigned int *)0xF002;
       *ptr = Data;
       
       while(1); // Code never gets here
    }

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

    您好、Bruce、

    我还想知道是否发生了存储器违例、我们是否可以向 info 变量写入内容?

    我提出这一问题是因为如果我在  MPU 违反后访问 INFO 变量、那么所有的 INFO 变量都会被复位、所有的值都会变为零。

    请尽快回复此主题、因为这非常紧急。


    谢谢、

    Thakur Manish

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

    您好、Bruce、

    我还想知道是否发生了存储器违例、我们可以向 info 变量写入内容、或者我们可以执行哪些操作? 您能详细写吗? (这是我的主要问题、也是我的大疑问)

    我提出这一问题是因为如果我在  MPU 违反后访问 INFO 变量、那么所有的 INFO 变量都会被复位、所有的值都会变为零。

    请尽快回复此主题、因为这非常紧急。


    谢谢、

    Thakur Manish

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

    >  count = ucDataCount/4;

    由于 sizeof (bkup struct)=1、这将计算 count = 0、而 do 循环将尝试移动64K 字。 尝试:


    > count =(ucDataCount+3)/4;

    --------

    //#pragma LOCATION ="INFOA

    我怀疑这是 IAR-ISM、因为 CCS 编译器会诊断错误。 如果 IAR 忽略了这一点、则 bkup 变量将位于 RAM 中(因此不会更新 INFOA)。 我将其替换为

    >#pragma LOCATION = 0x1980

    --------

    通过这些修复、您的程序将按预期运行。

    [编辑:固定常量]

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

    您好、Bruce、

    感谢您的响应、我的计划能实现预期。 我只是想知道为什么你这么做 > count =(ucDataCount+3)/4;在我标记它以解决我的问题之前,需要在那里添加+3。

    请对此进行澄清。