HAL_Delay()陷入无限循环

时间:2018-12-22 22:51:52

标签: c linker infinite-loop stm32 hal

我对HAL_Delay()函数感到困惑。当我调用此函数HAL_Delay()时,控件陷入无限循环。 在寻找问题时,我发现了

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

在此特别声明中,我引用“链接器文件存在问题,请使用所附的链接。您需要分别映射两排内存,因此首先是SRAM1 96K,然后是32K SRAM2。我认为应该报告作为CubeMX中的错误,因为它会生成错误的链接器文件。”还有两个扩展名为.ld的文件。

我正在寻找的是如何在项目中使用此文件,或者如何使用其他更好的选项来解决此问题。

PS。我正在使用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

2 个答案:

答案 0 :(得分:1)

SysYick处理程序中增加的所有延迟和超时HAL功能在计数器上进行中继。如果在另一个中断中使用这些功能中的任何一个,则必须确保SysTick中断优先级高于处理程序调用这些功能的中断的优先级。否则,永远不会调用SysTick处理程序,并且由于计数器永远不会增加,您将陷入无限循环。

答案 1 :(得分:1)

修复:

摘要:
增加SysTick_Handler NVIC优先级(通过减小其NVIC数值(范围为0到15)。

详细信息:
@P__J__在他的回答here中说的是正确的,我也怀疑这是您的问题。要解决此问题,您需要使SysTick中断的NVIC(嵌套矢量中断控制器)优先级比要使HAL调用的其他中断(可能依赖于系统滴答增量)的更高。 / em>包括所有具有超时的HAL调用,例如HAL延迟。较高的NVIC优先级意味着您必须将其设为较低的数值,因为对于默认配置的STM32芯片,最高NVIC优先级为0,最低为15。

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

这是屏幕截图。请注意,您还可以通过单击“ Pinout视图”旁边的“系统视图”按钮,然后单击“系统核心”部分下的“ 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”中,该文件还包含位于{{1}上方的HAL_InitTick()函数}。它的评论很有见地:

HAL_IncTick()

尤其要注意:表示以下内容的部分:

  

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

这正是我学到的地方。

请确保有时会跳过代码,并查看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 )。