we are currently evaluating to use an external SRAM for C/C++ heap storage on our platform using a STM32F439BI microcontroller.
The problem
Using the SRAM as storage for heap results in random hardfaults which are raised from buserrors/imprecice buserrors. Without placing the heap on the SRAM, memory tests run successfully on the whole SRAM (8 bit/16 bit and 32 bit accesses). Connecting a debugger I can observe these errors sometimes before a hardfault occurs. Most often a word is read from the SRAM and the CPU register fills with addresses of the following format: 0x-1F3-1F3 (- is most often '0', sometimes 'A' or '6'). The pattern '1F3' persists. If the same address is read again some lines further down the correct value is read (some other address in 0x60000000 space). If I stop the program on a breakpoint at some point early in the program and step a few lines, I get these errors more frequently.
Further details
- The SRAM is connected using the FMC/FSMC peripheral on FMC bank 1 and SRAM bank 1 and is therefore memory-mapped to address 0x60000000.
- All settings for GPIO pins and FMC configuration are set from the startup file before main() executes or static objects are created.
- The SRAM is the following: CY7C1041GN30
- We connect all 16 data pins, all 18 address pins, BHE, BLE, OE, WE and CE to our controller. All pins are configured as push-pull-alternate-function, pull-up, AF_12 (FMC), very high speed. We enable clocks for all necessary pins and the clock for FMC. Note: Initially we started out without pull-up/down showing the same symptoms.
- The controller runs with a clock speed of 168 MHz
- As stated above, a memory test runs successfully
- We use DMA for SPI, I2C and ADC data transfers
- We frequently use interrupts, including external (pin) interrupts
- We use the following timing settings:
- AddressSetupTime: 2
- AddressHoldTime: 4
- DataSetupTime: 4
- BusTurnAroundDuration: 1
- CLKDivision: 2
- DataLatency: 2
- We configure the FMC as follows:
- NSBank FMC_NORSRAM_BANK1,
- DataAddressMux FMC_DATA_ADDRESS_MUX_DISABLE,
- MemoryType FMC_MEMORY_TYPE_SRAM,
- MemoryDataWidth FMC_NORSRAM_MEM_BUS_WIDTH_16,
- BurstAccessMode FMC_BURST_ACCESS_MODE_DISABLE,
- WaitSignalPolarity FMC_WAIT_SIGNAL_POLARITY_LOW,
- WrapMode FMC_WRAP_MODE_DISABLE,
- WaitSignalActive FMC_WAIT_TIMING_BEFORE_WS,
- WriteOperation FMC_WRITE_OPERATION_ENABLE,
- WaitSignal FMC_WAIT_SIGNAL_DISABLE,
- ExtendedMode FMC_EXTENDED_MODE_DISABLE,
- AsynchronousWait FMC_ASYNCHRONOUS_WAIT_DISABLE,
- WriteBurst FMC_WRITE_BURST_DISABLE,
- ContinuousClock FMC_CONTINUOUS_CLOCK_SYNC_ASYNC,
- WriteFifo 0,
- PageSize 0
- We spend a lot of time of experimenting with longer timings and compared all the settings to examples including this one: Using STM32L476/486 FSMC peripheral to drive external memories (although this one is for the STM32L4, I am fairly certain it applies to this controller as well)
Findings on similar problems
- The problem sounds very similar to this errata sheet entry: "2.3.4 Corruption of data read from the FMC" but it also says the error is fixed in our revision of the controller (3)
I hope someone out there has seen this strange behaviour before and can help us. After over one week of debugging we expect some kind of error in the controller when interrupts/DMA accesses occur while the CPU accesses the SRAM (when we use it as heap, it is accessed very frequently). Hopefully you can shed some light on this topic.