使用STM32,C程序运行卡死。
现象是:
主循环卡死,但中断和串口还能有效触发和工作的,问题复现概率很低,可能连续运行10个小时才复现一次,想接上debuger来调试显然不合适
想排除卡死在哪里方便分析根因,于是我在程序中埋点,复现后通过按键触发外部中断来打印输出程序运行后的埋点结果。然后等复现后,提供按键中断打印出埋点队列,结果显示程序运行最后是卡在HAL_Delay(20); HAL_Delay函数应该是没问题的,毕竟一直运行着。
add_buried_point(1);
program_a();
add_buried_point(2); // 问题复现后,最后显示到点2
HAL_Delay(20);
add_buried_point(3);
program_b();
add_buried_point(4);
/**
* @brief This function provides minimum delay (in milliseconds) based
* on variable incremented.
* @note In the default implementation , SysTick timer is the source of time base.
* It is used to generate interrupts at regular time intervals where uwTick
* is incremented.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @param Delay specifies the delay time length, in milliseconds.
* @retval None
*/
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait)
{
}
}
推测1:是HAL_Delay有关的系统时钟卡住,导致HAL_Delay等待不到?
于是在外部中断函数中同时打印埋点队列和HAL_GetTick()结果,结果HAL_GetTick()是正常刷新递增的,系统时钟是正常工作的。
推测2:是程序出错,进入HardFault之类的中断里了?
于是调整了中断优先级,把按键的外部中断优先级调低,结果再次复现后,按键中断是能使用的,说明不是进入HardFault之类的死胡同里,不然低优先级的外部中断(按键)抢占不了HardFault之类的高优先级中断。
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
希望大能们提供个解决思路,我很想要定位出程序卡死的位置和原因