gpt4 book ai didi

c - HAL_Delay() 陷入死循环

转载 作者:太空宇宙 更新时间:2023-11-04 01:45:53 24 4
gpt4 key购买 nike

我受困于 HAL_Delay() 函数。当我调用此函数 HAL_Delay() 时,控件陷入无限循环。在搜索问题时,我发现了这个

http://www.openstm32.org/forumthread2145#threadId2146

在这个特别的评论中,我引用了“链接器文件有问题,请使用附件。你需要分别映射两个内存组,所以首先是 SRAM1 96K,然后是 SRAM2 的 32K。我认为这应该被报告作为 CubeMX 中的错误,因为它会生成错误的链接器文件。”并且有两个扩展名为 .ld 的文件。

我正在寻找的是如何在我的项目中使用这些文件或处理此问题的任何其他更好的选择。

附言。我正在使用 stm32l476 探索板、Cube Mx 5.0.0 和 Attolic True Studio。

编辑

我的项目有一个 RS485 通信,我从那里获取数据,我有两个任务处理该数据,将其显示在 MAX7219 显示器上并使用 sim800 gsm 模块将其发送到互联网。

控件卡住​​的代码。请注意,此函数仅在执行 GSM 任务时调用。

void vMyDelay(uint16_t ms)
{
HAL_UART_Transmit(&huart2, (uint8_t*)"\r\n", strlen("\r\n"), 1000);
HAL_UART_Transmit(&huart2, (uint8_t*)"In Delay", strlen("In Delay"), 1000);
HAL_UART_Transmit(&huart2, (uint8_t*)"\r\n", strlen("\r\n"), 1000);
for (int i = 0; i < ms; i++ ) HAL_Delay(1);
HAL_UART_Transmit(&huart2, (uint8_t*)"\r\n", strlen("\r\n"), 1000);
HAL_UART_Transmit(&huart2, (uint8_t*)"Out Delay", strlen("Out Delay"), 1000);
HAL_UART_Transmit(&huart2, (uint8_t*)"\r\n", strlen("\r\n"), 1000);
}

此函数在终端上写入In Delay,但不显示Out Delay。但我还有一个定时器,它每 2 秒调用一次以在 MAX72219 上显示数据。

下面的代码是

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
HAL_UART_Transmit(&huart2, (uint8_t*)"\r\n", strlen("\r\n"), 1000);
HAL_UART_Transmit(&huart2, (uint8_t*)"HAL_TIM_PeriodElapsedCallback()", strlen("vRS485_CollectInverterData()"), 1000);
HAL_UART_Transmit(&huart2, (uint8_t*)"\r\n", strlen("\r\n"), 1000);
if (htim->Instance == htim3.Instance)
{
vMax7219_ClearDisplay();
switch (uiMax7219Index)
{
case 0: vMax7219_SendNumberToString(ucFreq7219,1); break;
case 1: vMax7219_SendNumberToString(ucInVolt7219,1); break;
case 2: vMax7219_SendNumberToString(ucOutVolt7219,1); break;
case 3: vMax7219_SendNumberToString(ucOutCurr7219,1); break;
case 4: vMax7219_SendNumberToString(ucLoadSpd7219,1); break;
case 5: vMax7219_SendNumberToString(ucOutPwr7219,1); break;
}
uiMax7219Index++;
if (uiMax7219Index > 5) uiMax7219Index = 0;
}
}

控件卡住​​后,这个函数总是在 2 秒后触发。因此得出的结论是,控件以某种方式卡在 HAL_Delay() 中。

小东西

问题每次都会发生,但没有具体时间,即控制可能会在 5 分钟、10 分钟或 15 分钟后卡住。它不会因特定功能而卡住。功能可能不同。即有时它可能会因函数名称 getIMEI() 而卡住,或者有时它可能会因 get service provider

而卡住

最佳答案

修复:

总结:
提高 SysTick_Handler NVIC 优先级(通过降低其 NVIC 数值,范围为 0 到 15)。

详情:
@P__J__ 在他的回答 here 中所说的是正确的,我也怀疑这是你的问题。要修复它,您需要使您的 SysTick 中断具有 NVIC(嵌套 vector 中断 Controller ) 优先级 高于 进行 HAL 调用的任何其他中断可能依赖在系统滴答递增上。 这包括所有具有超时的 HAL 调用,例如,以及 HAL 延迟。较高的 NVIC 优先级意味着您必须将其设为较低的数值,因为在默认配置下,STM32 芯片的最高 NVIC 优先级为 0,最低为 15。

要在 STM32CubeMX 5 中设置 NVIC 优先级,请转到 Pinout & Configuration --> System Core -->(单击微小的向上/向下箭头进入显示 NVIC 的页面),然后单击 NVIC -->将“抢占优先级”值降低到低于(高于)任何其他依赖 HAL 调用的 ISR。

这是一个截图。请注意,您也可以通过单击“Pinout view”旁边的“System view”按钮,然后单击“System Core”部分下的“NVIC”来进入此屏幕。

截图:

enter image description here

关于 HAL_IncTick(); 的更多信息:

您将从“stm32f4xx_it.c”文件中看到,SysTick_Handler ISR 调用 HAL_IncTick();:

/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
HAL_IncTick();
}

如果您按住 Ctrl 并单击它(至少在 System Workbench/Eclipse 中)以跳转到 HAL_IncTick() 的实现,您将看到以下内容,它提供了一些额外的见解评论:

/**
* @brief This function is called to increment a global variable "uwTick"
* used as application time base.
* @note In the default implementation, this variable is incremented each 1ms
* in Systick ISR.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @retval None
*/
__weak void HAL_IncTick(void)
{
uwTick++;
}

HAL_IncTick() 函数可在文件“...STM32Cube_FW_F4_V1.19.0/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c”中找到,该文件还包含HAL_InitTick() 函数就在 HAL_IncTick() 之上。它的评论非常有见地:

/**
* @brief This function configures the source of the time base.
* The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority.
* @note This function is called automatically at the beginning of program after
* reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
* @note In the default implementation, SysTick timer is the source of time base.
* It is used to generate interrupts at regular time intervals.
* Care must be taken if HAL_Delay() is called from a peripheral ISR process,
* The SysTick interrupt must have higher priority (numerically lower)
* than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
* The function is declared as __weak to be overwritten in case of other
* implementation in user file.
* @param TickPriority Tick interrupt priority.
* @retval HAL status
*/
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
/* Configure the SysTick to have interrupt in 1ms time basis*/
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
{
return HAL_ERROR;
}

/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
uwTickPrio = TickPriority;
}
else
{
return HAL_ERROR;
}

/* Return function status */
return HAL_OK;
}

特别注意:上面写着的部分:

Care must be taken if HAL_Delay() is called from a peripheral ISR process,
The SysTick interrupt must have higher priority (numerically lower)
than the peripheral interrupt. Otherwise the caller ISR process will be blocked.

那正是我学到这个的地方。

确保有时跳转代码并查看 ST 的 HAL 源代码本身内部的函数和文档,以找到像这样隐藏的洞察力。当然,除了引用以下核心文档外,还要这样做:

芯片的主要 STM32 文档,按优先顺序排列(最重要的在前):

  1. 引用手册:RM0351
  2. 数据表:DS10198
  3. UM1725 - Description of STM32F4 HAL and LL drivers
  4. 编程手册:PM0214

这些和其他重要手册很容易在 ST 的网站 (https://www.st.com/en/microcontrollers/stm32l476vg.html) 上找到,或者更方便:在 STM32CubeMX 中通过帮助 --> 文档和资源(快捷方式:Alt + D).

关于c - HAL_Delay() 陷入死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53899882/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com