【STM32CUBEMX】HAL 库的 Timeout=1 异常分析

背景

STM32CUBEMX 在生成的库函数,基本上都有输入参数 Timeout。
比如说:

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);

这几天就吃了这个 Timeout 的哑巴亏。。。怎么说~
我把这个 Timeout 设成 1 了,1 这个值是万万使不得的一个值,咱们分析下。

分析 Timeout = 1 为什么不能用

我们以HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout),先来看看 Timeout 这个值是怎么用的。

在进入 函数后,咱们可以看到这个语句:tickstart = HAL_GetTick();
语句的作用:获取进入函数时的时间。

提取HAL_GetTick的源码:

__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

接儿,找到 uwTick 赋值的位置。

__weak void HAL_IncTick(void)
{
  uwTick++;
}

最后定位HAL_IncTick函数应用位置。

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

咱们来屡下思路:
滴答时钟在每次中断时会更新 uwTick,以供各个HAL函数计算超时使用。

再回到HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)函数,看 tickstart 和 TImeout 是怎么用的。

        /* Timeout management */
        if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
        {
          errorcode = HAL_TIMEOUT;
          goto error;
        }

当 HAL_GetTick() - tickstart) >= Timeout 时,就会认为是 Timeout。这么看着没有任何问题。

那咱们假定 SysTick_Handler 的中断周期是 1ms。看下图,当tickstart在红色点上赋值,若操作在 SysTick_Handler 中断前未完成,SysTick_Handler 中断先执行了 uTick++,那么 HAL_GetTick() - tickstart) >= 1 就为真了。也就意味着,实际上,咱们的 Timeout 并不为 1 个 SysTick_Handler 中断周期。尤其是当 tickstart 赋值越向右靠近,越容易出现 Timeout,因此在调用HAL 库时,必须使 Timeout 设置大于1!
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值