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.

Compiler/TM4C129ENCPDT: MPU configuration

Part Number: TM4C129ENCPDT

Tool/software: TI C/C++ Compiler

Hi everyone,

my question is about MPU, i want to protect NVIC_NVIC_MPU_ATTR, after configuring the mpu and protecting this address with 32B, it seems it is not protected because when i try to write on this address it does not give me mpu fault error. where is the problem?

    Error_Block eb;


    Error_init(&eb);
    Hwi_create(FAULT_MPU, MpuIntHandler, NULL, &eb);

        MPU_RegionSet(3, 0xE000EDA0,
                     MPU_RGN_SIZE_32B |
                     MPU_RGN_PERM_EXEC|
                     MPU_RGN_PERM_PRV_RO_USR_RO|
                     MPU_RGN_DISABLE);

        MPU_RegionEnable(3);


    IntEnable(FAULT_MPU);

    MPU_Enable(MPU_CONFIG_PRIV_DEFAULT);

  • Did you leave privileged mode? Your call to MPU_Enable() puts back the default map in privileged mode. Also, you should not set this region as MPU_RGN_PERM_EXEC. You should never try to execute code from this location.

  • i want to produce error, i want to see that the protection is active, why i still can write on these address?

  • I suspect you are still in privileged mode as that is the default. You need to change to unprivileged mode by writing to the CPU CONTROL register or use "MPU_CONFIG_NONE" instead of "MPU_CONFIG_PRIV_DEFAULT"

        MPUEnable(MPU_CONFIG_NONE);
    

  • this configuration gives me error, when launch the firmware

  • but still i can not understand, with this set i am configuring that also in privilage mode it should not be writeable, so why you have still doubt?

    MPU_RegionSet(3, 0xE000EDA0,
                     MPU_RGN_SIZE_32B |
                     MPU_RGN_PERM_EXEC|
                     MPU_RGN_PERM_PRV_RO_USR_RO|
                     MPU_RGN_ENABLE);

  • As I posted before, the line 

        MPU_Enable(MPU_CONFIG_PRIV_DEFAULT);

    in your code causes the default memory map (not the MPU) to be used in privileged mode.

  • ok i changed the configuration but at the time of doing MPUEnable it goes to error:

    #define MPU_CONFIG_PRIV_DEFAULT     4
    #define MPU_CONFIG_HARDFLT_NMI      2
    #define MPU_CONFIG_NONE             0
    
    
    
    void MPU_Init()
     {
         Error_Block eb; Error_init(&eb); 
         Hwi_create(FAULT_MPU, MpuIntHandler, NULL, &eb); 
    
         MPU_RegionSet(); 
    
         MPURegionSet(3, 0xE000EDA0, 
                                   MPU_RGN_SIZE_32B | 
                                   MPU_RGN_PERM_NOEXEC | 
                                   MPU_RGN_PERM_PRV_RO_USR_RO | 
                                   MPU_RGN_ENABLE); 
    
       IntEnable(FAULT_MPU); 
       MPUEnable(MPU_CONFIG_NONE); //-----> gives me error when wanto execute this function 
    }

  • Sorry, this took me a while to figure out. First, what I said about using MPU_CONFIG_NONE does not help because that disables the default map which means the flash code was now in unmapped space. That is why it immediately gave a Fault NMI.

    According to the ARM V7 Architecture Reference Manual, access to the private peripheral bus always use the default map.

    From the CPU block diagram in the datasheet we see that the MPU registers are on the private peripheral bus:

    This means that you cannot use the MPU to protect these registers.  Since these registers are only writeable in privileged mode, the easiest way to protect them is to go to non-privileged mode:

        // Change to non-privileged mode
        asm(" mov r0, #1");
        asm(" msr control, r0");