HAL_Delay() 陷入无限循环

2024-04-08

我被 HAL_Delay() 函数困住了。当我调用此函数 HAL_Delay() 时,控制陷入无限循环。 在寻找问题的过程中,我发现了这个

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

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

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

附言。我正在使用 stm32l476 discovery board、Cubemx 5.0.0 和 Atollic True Studio。

EDIT

我的项目有一个 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


The fix:

Summary:
增加SysTick_HandlerNVIC 优先级(通过减小其 NVIC 数值,范围为 0 到 15)。

Details:
@P__J__ 在他的回答中说了什么here https://stackoverflow.com/a/53903790/4561887是正确的,我也怀疑这是你的问题。要修复它,您需要使 SysTick 中断具有NVIC(嵌套向量中断控制器)优先事项higher than 进行 HAL 调用的任何其他中断可能依赖于系统滴答增量。例如,这包括所有具有超时的 HAL 调用以及 HAL 延迟。更高的 NVIC 优先级意味着您必须将其设为lower数值,因为默认配置下STM32芯片的NVIC优先级最高为0,最低为15。

要在 STM32CubeMX 5 中设置 NVIC 优先级,请转至引脚分配和配置 --> 系统核心 -->(单击微小的向上/向下箭头进入显示 NVIC 的页面),然后单击 NVIC --> 减少“抢占优先级”值为低于(优先级高于)任何其他依赖 HAL 调用的 ISR。

这是一个屏幕截图。请注意,您还可以通过单击“引脚视图”旁边的“系统视图”按钮,然后单击“系统核心”部分下的“NVIC”来进入此屏幕。

截屏:

更多信息:HAL_IncTick();:

您将从“stm32f4xx_it.c”文件中看到,SysTick_HandlerISR 呼叫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++;
}

This 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;
}

特别注意:这部分说:

如果从外围 ISR 进程调用 HAL_Delay(),则必须小心,
SysTick 中断必须具有较高的优先级(数字较低)
比外设中断。否则调用者ISR进程将被阻塞。

这正是我学到这一点的地方。

确保有时跳过代码并查看 ST 的 HAL 源代码本身内部的函数和文档,以找到像这样隐藏的见解。当然,除了参考以下核心文档之外,还要这样做:

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

  1. 参考手册:RM0351
  2. 数据表:DS10198
  3. UM1725 - STM32F4 HAL 和 LL 驱动程序说明 https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-mcu-packages/stm32cubef4.html
  4. 编程手册:PM0214

These and other critical manuals are easily found on ST's website (https://www.st.com/en/microcontrollers/stm32l476vg.html https://www.st.com/en/microcontrollers/stm32l476vg.html), or, even more convenient: inside STM32CubeMX via Help --> Docs & Resources (shortcut: Alt + D).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HAL_Delay() 陷入无限循环 的相关文章

随机推荐

  • 如果 NSString stringWithContentsOfFile 已被弃用,那么它的替代品是什么?

    我有一些来自 Tuaw 的示例代码 可能是 3 个版本的旧版本 编译器发出警告 表明该方法已被弃用 但我没有看到 SDK 文档中提到这一点 如果不推荐使用 则必须有替代方法或替代方法 有谁知道这个方法的替代品是什么 具体代码是 NSArra
  • Eclipse Kepler 在加载工作台时自动退出并出现错误

    当我启动 Eclipse 时 在启动加载窗口中 eclise 自动退出并出现错误 SESSION 2013 09 05 14 52 04 771 eclipse buildId 4 3 0 I20130605 2000 java versi
  • 使用正则表达式查找包含五个字母 abcde 的单词,每个字母以任意顺序仅出现一次,中间没有中断

    例如 这个词debacle会起作用 因为debac but seabed不起作用 因为 1 在任何可以形成的 5 个字符序列中都没有 c 并且 2 字母 e 出现了两次 再举个例子 feedback会起作用 因为edbac 请记住 解决方案
  • 为什么 Objective-C 没有命名空间?

    为什么 Objective C 没有命名空间 这似乎是一个简单的功能 可以使某些类名更具可读性 AVMutableVideoCompositionLayerInstruction有人吗 并删除类名上愚蠢的字母前缀 这主要是因为向后兼容吗 实
  • 集中式和分布式版本控制系统之间的比较[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何让我的 tkinter 原型系统计算出正确的总价

    我是一名初学者 我正在使用 Tkinter 为 DIY 商店创建一个原型系统 作为我任务的一部分 该应用程序的工作原理是填写一份简单的调查来创建订单 单击 输入数据 按钮后 页面底部应显示您的选择结果 包括总价 我需要一些关于如何编写系统计
  • 使用 serde 序列化时如何按字母顺序对字段进行排序?

    我有一个 API 要求对象的字段按字母顺序排序 因为必须对结构进行哈希处理 在 Java Jackson 中 您可以在序列化器中设置一个标志 MapperFeature SORT PROPERTIES ALPHABETICALLY 我在 S
  • 聚合物全局变量

    我正在开发一个 Polymer 应用程序 它从 RESTful API 中提取数据并使用它来构建界面 我在概念上坚持的一个特定领域是单态模式的实现 描述于http www polymer project org docs polymer p
  • BigQueryTable.InsertRows 间歇性地抛出未找到表 xx

    我们只是删除表 创建表 然后使用插入数据 BigQueryTable table try table dataset GetTable tableName table Delete catch finally table dataset C
  • 如何在 .NET Framework 4.7.1 中使用 Azure KeyVault 覆盖 Web.config 值

    如何在 ASP NET Framework 4 7 1 WebForms 应用程序中实现 Microsoft 的 Azure KeyVault 以覆盖中的值web config使用 KeyVault 中的值 我确实看到参考资料表明我们需要最
  • Youtube iOS 播放器帮助程序库无法正常工作

    我尝试实现 youtube ios player helper 库来在我的应用程序中播放视频 我可以准备好播放器并加载视频 并且可以显示起始缩略图 但是 当我尝试播放视频时 却收到以下错误消息 SendDelegateMessage NSI
  • 通过尾指针添加到链表,无需 3 级间接

    我正在开发一个需要实现链表的项目 在开始这个项目之前 我正在回顾创建链表的经典方法 我意识到过去我一直通过head遍历列表直到到达空指针的指针 我发现没有必要这样做 并以涉及的方式实现它tail指针 但我能想到的唯一方法是涉及三重指针或全局
  • Jquery Multiselect:如何知道选择/取消选择哪个值

    我有多选下拉菜单 每当有选择或取消选择时 我都需要获取该值 我正在使用更改事件 但很难确定选择 取消选择了哪个选项 all options var all multiple each function i selected all i se
  • 如何在 C# 中附加 xml 文件?

    我正在为一个简单进程添加跟踪 以进行审计 我将其构建为 exe 并在调度程序中设置为每 10 分钟运行一次 我想让应用程序将结果输出到 xml 文件中 如果文件存在 则打开并向其追加数据 如果不存在 我想创建一个新的 xml 文件 该文件将
  • C/C++ 中的动态位向量

    我正在寻找一个可以使用的现成的 C 或 C 动态位向量 不幸的是 由于各种原因 我目前无法使用 BoostT 库 std bitvector 看起来很有希望 但它是模板化的 所以我无法动态设置位向量的长度 有人可以建议吗 谢谢 您不必仅仅为
  • 安装SSDT(SQL Server数据工具)时出错

    我在安装 SQL Server Data Tools for Visual Studio 2017 过程中遇到问题 我收到以下错误 已翻译 The requested meta file operation is not supported
  • SwiftUI:两个并排列表和一个导航视图出现意外行为

    我的屏幕有两个List并排 在一个NavigationView 布局渲染正确 我可以独立滚动两个列表 问题是 当我滚动第一个列表时 它位于导航栏后面 而没有触发对其应用背景颜色的效果 下面的 gif 展示了正在发生的事情 这是我用于此视图的
  • request.getSession() 在 sendRedirect() 之后创建新会话

    我们正在开发旅行应用程序 通过这个航班 可以预订酒店 巴士票 它是基于产品的应用程序 我们有近 25 个客户 3 个客户正在使用 其余仍在开发中 我们为所有客户维护一台服务器 一台服务器 应用程序 多个客户端是我的应用程序中的伟大成就 但问
  • 使用 jq 将 JSON 对象转换为 Prometheus 指标格式

    考虑一个 JSON 对象 例如 foo 42 baz 12 bar label1 value1 12 34 建造者jq https github com stedolan jq使用一些数据源 实际的键名称及其数量可能会有所不同 但结果将始终
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt