cembeddedstm32interrupt

Protecting filling a buffer that is read from SRAM in STM32F429I


I'm trying to read a buffer from bus system using stm32F4, on falling interrupt. The problem is I need to process the data in main loop, and I don't need any latency, The falling interrupt, occurs at 500ns, and I don't want to miss any data. So disabling enabling an interrupt wouldn't be beneficial here.

I'm looking for a way to reduce latency, and not miss any interrupt. Here is my approach:

In Main Loop:

    while (1)
    {
        if(iowr_set)
        {
            iowr_set = 0;
              for (int i = 0; i < BUFFER_SIZE; i++)
              {
                  processData(aRxBuffer[i]);
              }

        }
}

Interrupt:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {


    if (GPIO_Pin == GPIO_PIN_6) { // IORD

        HAL_SRAM_Read_16b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + WRITE_READ_ADDR), aRxBuffer, BUFFER_SIZE);

        iowr_set = 1;
    }
}

Declarations:

#define BUFFER_SIZE         ((uint32_t)0x0100)
#define WRITE_READ_ADDR     ((uint32_t)0x0800)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
SRAM_HandleTypeDef hsram1;
FMC_NORSRAM_TimingTypeDef SRAM_Timing;

/* Read/Write Buffers */
volatile uint16_t aRxBuffer[BUFFER_SIZE];

Solution

  • Your STM32F429 can run at a maximum clock speed of 180MHz. This means that, assuming every instruction takes one clock cycle, you can execute 180 instructions in 1us, or 90 instructions in 500ns.

    Your goal is to process 256 bytes in 500ns, or 64 32-bit words. So you need to be able to process 64 words in 90 instructions.

    Let's imagine that you just wanted to read those words out of memory in that time. So let's simplify your code down to just this:

    #include <stdint.h>
    
    void read_data(uint32_t * data)
    {
        for (int i = 0; i < 256 / sizeof(uint32_t); ++i)
        {
            volatile uint32_t datum = data[i];
            // No processing
        }
    }
    

    Could this code even read 64 words in 90 instructions? Probably not. It seems like a naive approach like this will require about 4 instructions per word. https://godbolt.org/z/MarW37qvq

    You could unroll the loop and maybe, just maybe, be able to read the data out of RAM at the required speed. But this is with no processing being done at all.

    On top of all that, you have a call to HAL_SRAM_Read_16b(), which in itself will probably take hundreds if not thousands of clock cycles. And you are using interrupts, which add even more overhead.

    What you are trying to do is basically impossible. You'll need to reduce the data rate, or live with missing some of the data.