Skip to main content
luke23
Associate III
March 4, 2011
Question

Does anyone have any MPU code that just works? STM32F103VG

  • March 4, 2011
  • 7 replies
  • 1134 views
Posted on March 04, 2011 at 22:51

Does anyone have any MPU code that just works? STM32F103VG

#mpu
    This topic has been closed for replies.

    7 replies

    luke23
    luke23Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:26

    Required MPU basic operation:

    1)

         

    Protect a section of RAM.

    2)

         

    Access the RAM.

    3)

         

    Run the exception routine

    My setup is a motor-control application presently utilising timer interrupts, A2D interrupts, and DMA transfers - STM32F103VG, has MPU/has 96kB RAM, all working nicely, except a demo MPU feature:

    #define SIZEOF_PROTMEM            0x4000        //16kB;

    #define ADDRESS_OF_PROTECTED_SRAM (SRAM_BASE + 0x14000)

    volatile __root __no_init u32 au32MyProtectedBuffer[SIZEOF_PROTMEM/sizeof(u32)] @ ADDRESS_OF_PROTECTED_SRAM;

           //Disable MPU

           MPU_Disable();

           //Turn off all regions - the reset states for the ENA bits are undefined.

           //No-one else seems to do this – but just for fun OK?

           for(u32 u32Rgn=0 ; u32Rgn < ((MPU->TYPE&MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos) ; u32Rgn++)

           {

                  MPU->RNR  = MPU_RNR_REGION_Msk & (u32Rgn << MPU_RNR_REGION_Pos);

                  MPU->RASR = 0;

           };

           //

           //Configure a no access MPU region for the 16 KB of RAM.

           //This region is used for demonstrating an MPU exception.

           //

           sMPUInit.regionEnable = TRUE;

           sMPUInit.regionNo = 0;

           sMPUInit.baseAddress = ADDRESS_OF_PROTECTED_SRAM;

           sMPUInit.size = mpuRegionSize16Kb;

           sMPUInit.accessPermission = mpuRegionNoAccess;

           sMPUInit.disableExec = TRUE;

           sMPUInit.shareable = FALSE;

           sMPUInit.cacheable = TRUE;

           sMPUInit.bufferable = TRUE;

           sMPUInit.srd = 0xFF;

           sMPUInit.tex = 0;

           MPU_ConfigureRegion(&sMPUInit);

           //Enable the Memory Manage Handler

           NVIC_SystemHandlerPriorityConfig(SystemHandler_MemoryManage, 2, 8);

          

           //Enable memory protection and mem fault exceptions – background is Priv-mode open access – courtesy MPU_CTRL_PRIVDEFENA bit.

           MPU_Enable(MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk);

    My trip code:

    void SimulateMemoryViolation(void)

    {

           //Access the forbidden memory!

           au32MyProtectedBuffer[0]++;

    }

    My exception handler which is not being called when I call

    SimulateMemoryViolation(),

    called from stub in

    MemManage_Handler():

    void EH_MemoryViolation(void)

    {

           SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTACT;           //clear the fault flag

           //Go to infinite loop when Memory Manage exception occurs

           SetScreen_MPU_Error();

    }

    Other symptoms: In other variations of this setup (ie. specify code blocks, peripheral blocks, User/Priv permissions etc) I can generate MPU exceptions, or hard faults , but not from accessing my “protected ram.�?

    Andrew Neil
    Super User
    May 17, 2011
    Posted on May 17, 2011 at 14:26

    No - because ''just works'' is meaningless!

    You need to specify exactly what ''work'' you want it to do - and in what environment.

    A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
    luke23
    luke23Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:26

    Oh, great.

    Now I see it.

    The SRD disables the regions if set to 1.

    Profoundly embarrassed.

    Anyhow, now it's throwing hardware faults when 

    SimulateMemoryViolation()

    called, not mem-handler exceptions - any observations?

    Does anyone just have code that ''just works?''

    Ta

    Tesla DeLorean
    Guru
    May 17, 2011
    Posted on May 17, 2011 at 14:26

    As I recall the STM32F103 series doesn't have the MPU included in the M3 core.  I believe you have to move the the STM32F200 series for that.

     

    I think you'll find the STM32F103xF/103xG (ie XL devices) are claiming to have one

    http://www.datasheetarchive.com/Indexer/Datasheet-099/DSA00188765.html

    I'd guess I'd start by looking at the code generated for

    void SimulateMemoryViolation(void);

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    jpeacock23
    Associate
    May 17, 2011
    Posted on May 17, 2011 at 14:26

    As I recall the STM32F103 series doesn't have the MPU included in the M3 core.  I believe you have to move the the STM32F200 series for that.

      Jack Peacock

    luke23
    luke23Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:26

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6a0&d=%2Fa%2F0X0000000br8%2Fxnny1Gkfby5b1IH5cYt7qxfEqnBho68CRUBhcosoX4Y&asPdf=false
    luke23
    luke23Author
    Associate III
    May 17, 2011
    Posted on May 17, 2011 at 14:26

    OK, so bottom line is, if you invoke an MPU fault from within an exception or interrupt handler, then a hard fault is called.  So you must call SimulateMemoryViolation() from the main line.

    MPU code that ''just works'' attempt to attach #5.

    To use the code.

    1)

         

    Copy stm32f10x_mpu.c/.h into your StdPeriphLibrary folder.

    2)

         

    Copy memprot.c/.h into your project files folder.

    3)

         

    Customise memprot.c as required for your ap.

    4)

         

    Call

    InitMemProt()

    from

    main()

    .

    5)

         

    Somewhere in your mainline, call

    SimulateMemoryViolation()

    .

    6)

     

    In the mem_fault exception handler (in stm32f10x_it.c), place a stub to call

    EH_MemoryViolation(),

    like this:

    void MemManage_Handler(void)

    {

         EH_MemoryViolation();

    }

    7)

         

    Enjoy.

    Luke

    (may the source be with you)