Skip to main content
Visitor II
October 1, 2025
Question

Dual core concurrent access to the same FMC memory address

  • October 1, 2025
  • 1 reply
  • 642 views

Hello,

We have a STM32H755 with an FRam (similar to SRAM) module attached to the FMC. We have been seeing CPU exceptions when the M4 core tries to access (read only) the same memory location the M7 core is writing to.

So, it seems that the FMC does not arbitrate between the two cores... Is that correct? or do we potentially have the FMC configured incorrectly.

 

We have the FRam memory address region configured in the MPU as shareable (M7 - read/write) and read-only (M4 - reads only) and tried with cache disabled as well with same cpu exception...

Thanks,

-mike

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    October 2, 2025

    Hello,

    I don't think there is a limitation in term of concurrent access to the same memory between both cores, either from internal or external memories . The bus matrix is there to manage that kind of arbitration.

    If I understood well, the exception is seen from CM4, right not from CM7? and what do you mean by "the M4 core tries to access (read only)"? code execution? reading only data?

     

    Visitor II
    October 2, 2025

    Thanks mƎALLEm for the response, I'm Scuba's minion following up with more details.  The CM7 generates the exception.  Its reading only data, no code execution/instructions.

    What we are seeing is if the M4 and M7 are accessing different addresses on the FRam, it works fine but if the M7 is writing to an address when the M4 is polling(reading) the SAME address for changes, the M7 will generate a memmanage fault if there is a "simultaneous" access. If its not simultaneous, there is no issue. We've tested ensuring D-Cache is disabled, slowed down timing, tweaked FMC / MPU settings, nothing has helped. We'd prefer not to add complexity by using a hardware semaphore(or equivalent strategy) to ensure there is no simultaneous access to it so asking for verification if the FMC correctly arbitrates this situation or not? Since the M4 is polling, it doesn't matter who goes first,

    here is some of the code:

    M7 configures FMC as follows:

    hsram1.Instance = FMC_NORSRAM_DEVICE;
    hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
    
    /* hsram1.Init */
    hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
    hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
    hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
    hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
    hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
    hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
    hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
    hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
    hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
    hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
    hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
    hsram1.Init.WriteBurst = FMC_WRITE_BURST_ENABLE;
    hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
    hsram1.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
    hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
    
    /* Timing */
    Timing.AddressSetupTime = 11;
    Timing.AddressHoldTime = 15;
    Timing.DataSetupTime = 11;
    Timing.BusTurnAroundDuration = 11;
    Timing.CLKDivision = 16;
    Timing.DataLatency = 17;
    Timing.AccessMode = FMC_ACCESS_MODE_A;
    /* ExtTiming */
    
    if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
    {
    Error_Handler( );
    }


    M7's MPU configuration, should be Strongly Ordered:

    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0x60000000;
    MPU_InitStruct.Size = MPU_REGION_SIZE_64MB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER2;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    M4's MPU is same except Read-Only Access Permission.


    Here is some pseudo code, FramCounter are at the same address for both in the external FRam:


    The M7 is effectively just doing:

    __attribute__((section(".Fram"))) uint16_t FramCounter;
    uint16_t InternalCounter = 0;
    
    // The trigger happened, increment the counter
    FramCounter = InternalCounter;
    ++InternalCounter;

    Then the M4 is polling/reading the FramCounter to change:

    __attribute__((section(".Fram"))) uint16_t FramCounter;
    uint16_t InternalCounter;
    uint16_t PreviousCounter = 0;
    
    //inside a function that runs periodically
    InternalCounter = FramCounter;
    if(InternalCounter != PreviousCounter)
    {
     //Do Work
     PreviousCounter = InternalCounter;
    }

    Given that simultaneous access to the same address causes a MemManage fault on the M7, can ST confirm if this is expected behavior due to lack of FMC arbitration?  Although you mentioned the bus matrix handles this arbitration?  In this situation, is the only supported solution to serialize access (e.g., hardware semaphore or software lock), or is there an FMC/MPU configuration that allows safe concurrent access?

    Technical Moderator
    October 2, 2025

    Hello,

    As I said previously to my knowledge we don't have a limitation on this situation at least at the current time. None of our customers reported that.

    What if you access by address and make CM7 / CM4 access to different FRAM addresses?