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: Accessing INFO variables via FRAM after MPU violation causing my device to be hanged.

Part Number: MSP430FR5962

Hi experts,

I'm trying to implement a failsafe feature where if an MPU violation happens the device should access INFO variables via the fram_write function and set a flag so that we can write a function to restore the code from the backup memory. But accessing the INFO variables via FRAM write after MPU violation causing my device to be hanged completely and even the INFO region which I'm accessing is all set to 00. I have searched most of the documents but did not found anything regarding this issue where I can find out the correct answer. Can anyone please point it out if it has been documented by the Ti or please answer my this question that causing the MPU violation will lead the device to be bricked unless PUC reset or flashing of new code?
Please try to assist on this as soon as possible.

  • 1) I'm not quite clear on your symptom. Is your program (a) Freezing? (b) Reset-ing repeatedly? (c) Hanging the debugger?

    2) Keep in mind that the MPU isn't disabled by a PUC -- notably a PUC caused by a violation -- so you probably want to set MPUENA=0 first. (Weren't you doing that in the other thread?)

    3) How are the MPU registers set? Of particular interest is how the INFO segment is defined. Are you requesting a PUC on a violation?

    4) I've gotten some mileage out of using the CCS MPU setup GUI, then loading the program and looking at the MPU registers to see if I was reading the user guide properly.

  • Hi Bruce,

    For the first question answer is my debugger is hanged when I'm accessing/writing into the FRAM Variable.

    For the second one I have corrected my mistake and I'll be attaching my code to this thread.

    Please find out my code to check the MPU register configuration

    #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
    }

  • Hi Bruce,

    I also wanted to know if memory violation happens can we write something to the INFO variable?

    I'm asking because if I'm accessing the INFO variables after MPU Violation then all the INFO variables are getting reset and all the values are becoming zero.

    Please try to reply to this thread ASAP as this is very urgent.


    Thanks,

    Thakur Manish

  • Hi Bruce,

    I also wanted to know if memory violation happens can we write something to the INFO variable or what actions we can expect? Can you please write in detail? (This is my main question and big doubt)

    I'm asking because if I'm accessing the INFO variables after MPU Violation then all the INFO variables are getting reset and all the values are becoming zero.

    Please try to reply to this thread ASAP as this is very urgent.


    Thanks,

    Thakur Manish

  • >  count = ucDataCount/4 ;

    Since sizeof(bkup struct)==1, this will compute count=0, and the do-loop will try to move 64K words. Try:


    > count = (ucDataCount+3)/4 ;

    ----------------

    //#pragma location="INFOA"

    I suspect this is an IAR-ism, since the CCS compiler diagnoses an error. If IAR is ignoring this instead, your bkup variable will be in RAM (and thus INFOA won't be updated). I replaced it with

    > #pragma location=0x1980

    ----------------

    With these fixes, your program runs as expected.

    [Edit: Fixed constant]

  • Hi Bruce,

    Thanks for your response, my program works expectedly. I just wanted to know why you have done this > count = (ucDataCount+3)/4 ; what is the need of adding +3 in there before I mark it as it resolved my issue.

    Please clarify this.