2025-01-10 11:11 AM
I believe I discovered a bug in the SPI driver in relation to using HAL_SPI_TransmitReceive_IT() that causes buffer overflows, which also made it tricky to discover.
In our project, I had switched our SPI handlers to from blocking to non-blocking using the interrupt APIs.
The bug happens when calling HAL_SPI_TransmitReceive_IT() which hits:
HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
{
...
/* Fill in the TxFIFO */
while ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (tmp_TxXferCount != 0UL))
{
...
hspi->pTxBuffPtr += sizeof(~);
hspi->TxXferCount--; // <--- This decrements until 0
...
Then when an interrupt hits for SPI_TxISR_32BIT, SPI_TxISR_16BIT, or SPI_TxISR_8BIT it hits:
static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi)
{
/* Transmit data in 8 Bit mode */
*(__IO uint8_t *)&hspi->Instance->TXDR = *((const uint8_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint8_t);
hspi->TxXferCount--; // <---- Decrement without check, causing a rollover therefore an overflow
I fixed this locally by adding a condition check in the TxISR and RxISR handlers to this:
static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi)
{
/* Transmit data in 8 Bit mode */
*(__IO uint8_t *)&hspi->Instance->TXDR = *((const uint8_t *)hspi->pTxBuffPtr);
if(hspi->TxXferCount > 0) // <--- Make sure not zero
{
hspi->pTxBuffPtr += sizeof(uint8_t);
hspi->TxXferCount--;
}
Let me know your thoughts.
Regards.
2025-01-10 12:01 PM
Hello @AGreen 3rdEye ,
Thank you for having reported this issue.
An internal ticket number 200212 is submitted in order to review and check this.
(PS: Internal ticket number is only for reference, not available outside of ST)