关于STM32 hal库SPI的一个BUG
Posted Rogueman
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于STM32 hal库SPI的一个BUG相关的知识,希望对你有一定的参考价值。
具体bug点在HAL_SPI_TransmitReceive这个函数里面。具体表现是莫名其妙会进入hardfault,但是,也不排除直接debug跑死没反应的情况。
因为在最初的时候,程序调试异常都是直接调试卡死。这其中的具体原因还没搞清楚。
既然是bug,那肯定是满足了一定条件下的错误。但是很遗憾,具体条件我没找到。但是解决方法找到了。
代码中这一段改成:
while((hspi->TxXferCount > 0) || (hspi->RxXferCount > 0)) { /* check TXE flag */ if((hspi->TxXferCount > 0) && ((hspi->Instance->SR & SPI_FLAG_TXE) == SPI_FLAG_TXE)) { // if(hspi->TxXferCount > 1) // { // hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr); // hspi->pTxBuffPtr += sizeof(uint16_t); // hspi->TxXferCount -= 2; // } // else // { *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++); hspi->TxXferCount--; // } /* Enable CRC Transmission */ if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) { /* Set NSS Soft to received correctly the CRC on slave mode with NSS pulse activated */ if(((hspi->Instance->CR1 & SPI_CR1_MSTR) == 0) && ((hspi->Instance->CR2 & SPI_CR2_NSSP) == SPI_CR2_NSSP)) { SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); } hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; } } /* Wait until RXNE flag is reset */ if((hspi->RxXferCount > 0) && ((hspi->Instance->SR & SPI_FLAG_RXNE) == SPI_FLAG_RXNE)) { // if(hspi->RxXferCount > 1) // { // *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; // hspi->pRxBuffPtr += sizeof(uint16_t); // hspi->RxXferCount -= 2; // if(hspi->RxXferCount <= 1) // { // /* set fiforxthresold before to switch on 8 bit data size */ // SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); // } // } // else // { SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); (*hspi->pRxBuffPtr++) = *(__IO uint8_t *)&hspi->Instance->DR; hspi->RxXferCount--; // } } if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)) { errorcode = HAL_TIMEOUT; goto error; } }while((hspi->TxXferCount > 0) || (hspi->RxXferCount > 0)) { /* check TXE flag */ if((hspi->TxXferCount > 0) && ((hspi->Instance->SR & SPI_FLAG_TXE) == SPI_FLAG_TXE)) { // if(hspi->TxXferCount > 1) // { // hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr); // hspi->pTxBuffPtr += sizeof(uint16_t); // hspi->TxXferCount -= 2; // } // else // { *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++); hspi->TxXferCount--; // } /* Enable CRC Transmission */ if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) { /* Set NSS Soft to received correctly the CRC on slave mode with NSS pulse activated */ if(((hspi->Instance->CR1 & SPI_CR1_MSTR) == 0) && ((hspi->Instance->CR2 & SPI_CR2_NSSP) == SPI_CR2_NSSP)) { SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); } hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; } } /* Wait until RXNE flag is reset */ if((hspi->RxXferCount > 0) && ((hspi->Instance->SR & SPI_FLAG_RXNE) == SPI_FLAG_RXNE)) { // if(hspi->RxXferCount > 1) // { // *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; // hspi->pRxBuffPtr += sizeof(uint16_t); // hspi->RxXferCount -= 2; // if(hspi->RxXferCount <= 1) // { // /* set fiforxthresold before to switch on 8 bit data size */ // SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); // } // } // else // { SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); (*hspi->pRxBuffPtr++) = *(__IO uint8_t *)&hspi->Instance->DR; hspi->RxXferCount--; // } } if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)) { errorcode = HAL_TIMEOUT; goto error; } }
问题就解决了。具体原因似乎是因为
hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
*((uint16_t *)hspi->pRxBuffPtr) = hspi->Instance->DR;
In 8-bit mode the address pTxBuffPtr (pRxBuffPtr) may be not word-aligned. The casting (uint16_t*)hspi->pTxBuffPtr is the cause of hard-fault.
以上是关于关于STM32 hal库SPI的一个BUG的主要内容,如果未能解决你的问题,请参考以下文章