cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7xx - Serious Bug in SPI Driver HAL Version 1.3.0, 1.7.0 and 1.8.0

Dub Bartolec
Associate III

We were experiencing strange crashes originating from HAL_SPI_TransmitReceive and HAL_SPI_Receive when operating in SPI Slave mode.

Issue is that STM32 HAL code is not handling cases for 8 bit SPI Transfers correctly causing overflow of user buffers and corruption of stack or heap.

Here is simplified example of code:

uint8_t txData[4];

uint8_t rxData[4];

HAL_SPI_TransmitReceive(hspi, txData, rxData, 4, HAL_MAX_DELAY);

On some occasions function will increment rxData pointer past its size of 4 bytes and will copy SPI data to memory that was not designated to be written. In above case stack will be overwritten.

Bug is in function HAL_SPI_TransmitReceive() and HAL_SPI_Receive and it is in the block that handles 8 bit transfers:

/* Receive data in 8 Bit mode */
  else
  {
    /* Transfer loop */
    while (hspi->RxXferCount > 0U)
    {
      /* Check the RXWNE/FRLVL flag */
      if (hspi->Instance->SR & (SPI_FLAG_RXWNE|SPI_FLAG_FRLVL))
      {
        if (hspi->Instance->SR & SPI_FLAG_RXWNE)
        {
          *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
          hspi->pRxBuffPtr += sizeof(uint32_t);
          hspi->RxXferCount-=4;
        }
        else if ((hspi->Instance->SR & SPI_FLAG_FRLVL) > SPI_FRLVL_QUARTER_FULL)
        {
          *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
          hspi->pRxBuffPtr += sizeof(uint16_t);
          hspi->RxXferCount-=2;
        }
        else
        {
          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
          hspi->pRxBuffPtr += sizeof(uint8_t);
          hspi->RxXferCount--;
        }
      }
      else
      {
....
...
}
 

It actually occurs that E.g. we are expecting 4 bytes, but master sends more than 4 bytes and by the time we poll SPI buffer we have:

  1. 1 byte in FIFO
  2. Code reads byte and decrements RxXferCount so its value is now 3.
  3. Another 4 bytes arrive to SPI FIFO
  4. At this point code reads 4 bytes into buffer as it runs if (hspi->Instance->SR & SPI_FLAG_RXWNE) condition. At this point corruption has already occured as only 3 bytes were requested by caller of the function.
  5. Code then subtracts 4 from RxXferCount and count is now 0xFFFF,
  6. The rest is now in a hands of master. If master sends more data if there is no timeout set it will copy up to 0xFFFF bytes into RAM causing catasrophic failure of the program.

This is very easy to reproduce.

Can someone from STM development team review this code and let us know what the next step should be ?

14 REPLIES 14
Pavel A.
Evangelist III

While you're waiting for useful answers - please note that version 1.3 is old. The current version is 1.9. Read the changelog to see what was changed for SPI:

https://htmlpreview.github.io/?https://github.com/STMicroelectronics/stm32h7xx_hal_driver/blob/master/Release_Notes.html

-- pa

TDK
Guru

For HAL_SPI_TransmitReceive, I don't see how it can be receiving more bytes than it sends. And it only sends the exact number of bytes you specify.

For HAL_SPI_Receive, it appears the bug is still in the current code. Note that this is only used when SPI is used in slave mode or in half duplex.

https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c#L1098

And since RxXferCount is unsigned, it'll overflow and you'll try to receive 2^32 bytes which clearly won't work.

Didn't reproduce but seems like an issue if your CPU doesn't keep up with the data.

If you feel a post has answered your question, please click "Accept as Solution".
Dub Bartolec
Associate III

Hi @Pavel A.​

One release not in 1.9.0 suggest that something has been fixed.

Question is ...

How to obtain H7 HAL 1.9.0 as STM32CubeMX doesn't suggest it as upgrade when we try "Check For Updates".

Highest suggested version is 1.7.0 and problem is there too.

We are using Stm32Cube 5.6.1 because version 6.xx.x.x has bugs in generating FreeRTOS projects that renders our older projects unusable.

Dub Bartolec
Associate III

Hi @TDK​ .

Thanks for looking into it.

As impossible as it looks we actually noticed that problem first on HAL_SPI_TransmitReceive() where receive portion would receive more bytes than it sent. This is possible and it actually occurs.

We should not be relying on MCU having to keep with data. Code in STM32 HAL SPI in its current form is wrong.

As the matter of fact, what is letting this code down is the fact that H7 is actually too fast and it jumps and processes first byte in SPI before second one is received. Once this is done RxXferCount = 3.

In the meantime 4 more bytes are pushed into SPI FIFO by SPI MASTER, that causes another decision to be executed RxXferCount -= 4 and that overflows to 0xFFFF.

It is actual serious bug that should be fixed by STM.

Hi @Pavel A.​ ,

I've verified on STM32 Cube

https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-mcu-mpu-packages/stm32cubeh7.html

And highers publicly available H7 HAL is still only 1.7.0.

When will 1.9.0 be available to developers ?

TDK
Guru

The latest STM32CubeH7 repo is here and also in the latest CubeMX:

https://github.com/STMicroelectronics/STM32CubeH7

This is version "1.8.0" as listed in CubeMX. However, the internal version macro is one minor version ahead (no idea why) and internal comments refer to it as version "1.9.0". Perhaps this is what Pavel A is referring to. This inconsistency was in all previous versions as well.

https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c#L52

If you feel a post has answered your question, please click "Accept as Solution".

Hi @TDK​ ,

Thanks I checked it out and problem is still there.

We do not tend to use releases that are on GIT for production code as if we end up with an issue then STM refers us to use only officially available HALs from respective sites (https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-mcu-mpu-packages/stm32cubeh7.html)

We use GIT versions only for testing and I've already verified that problem is there too. I was curious about that 1.9.0 version in which Release notes are stating that it was some change in SPI driver.

Hi @Pavel A.​ 

I've checked latest version in GIT repository of H7 Cube and problem is there too.

Pavel A.
Evangelist III

@TDK​ ST now has separate lineage of HAL drivers and other components, vs. lineage of combined Cube packages that are auto-installed by Cube/CubeIDE.

In this specific case, Cube combined package H7_1.8.0 includes HAL drivers component version 1.9.0.

This is mentioned in release notes of the former.

Sophisticated users can mix and match the components & versions on their own (from github).

-- pa