bas*_*bas 4 microcontroller stm32 freertos
我花了一段时间才让我的程序稳定运行。我的程序运行时遇到硬故障。我正在兜圈子。
我的项目:
一些 freertos 配置
并使用定义将免费 rtos 中断处理程序映射到 CMSIS
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
Run Code Online (Sandbox Code Playgroud)
我的程序按顺序执行以下操作:
然后“StartLwIP”执行以下操作:
“测试”任务的作用是:
当我使用 vTaskDelay(100) 时,程序可以毫无问题地运行几个小时(运行过夜,没有问题)。
当我使用 vTaskDelay(10) 时,程序会运行一段时间(1 分钟到 5 分钟之间)。然后它会崩溃并挂在硬故障处理程序中。
当我删除 vTaskDelay(这将是首选解决方案)时,它会崩溃得更快。同样,它会有所不同,但在几秒到一分钟之间。
我 99% 确定问题与堆/堆栈无关。高水位线和堆消耗看起来非常好。甚至无法接近堆/堆栈之外。
LWIP 的内存管理让我有些困惑,但由于我只是不断地打开和关闭连接,所以我不敢相信 LWIP 中的 PBUF 已经用完了。无论如何,我扩大了数字。
我挣扎了几周,最终开始怀疑 STM HAL。然后我偶然发现了__HAL_LOCK外围库(在我的例子中是 uart)。例如在HAL_UART_Transmit_IT
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart); <<<<======
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Process Unlocked */
__HAL_UNLOCK(huart); <<<<======
/* Enable the UART Transmit data register empty Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
Run Code Online (Sandbox Code Playgroud)
当我查看锁宏的定义时,我有点担心:
#if (USE_RTOS == 1U)
/* Reserved for future use */
#error "USE_RTOS should be 0 in the current HAL release"
#else
#define __HAL_LOCK(__HANDLE__) \
Run Code Online (Sandbox Code Playgroud)
我读过几个关于此的主题。例如这里和这里。我还可以阅读很多主题,认为锁定机制实现得很差并且根本不是线程安全的。有趣的是,即使没有 RTOS,但使用中断也会是一个潜在的问题。
我下载了STMCube最新版本来检查现在是否可以解决这个问题。但一切仍处于同一个状态。STM HAL 似乎对其 USE_RTOS 宏没有做太多事情。
在我的程序中,我使用不同的任务来读取和写入同一 uart 实例。LWIP TCP 线程将发送数据,而 LWIP RX 线程将不断从 uart 读取数据。我的串口以中断模式接收数据(逐字节传递到环形缓冲区)。
最后我的问题:
有没有可能这个锁定机制就是我的硬故障的根本原因?我试图找到遇到同样问题的人,但找不到可以证实这一点的“证据”。所以也许“可怕的锁定机制”不是最好的实现,但不是我的问题的根本原因。
是否需要采取“步骤”来从硬故障中获取更多详细信息?我真的很想找到有问题的代码行。我发现这个页面解释了如何继续,但我不知道如何获取电脑(我正在使用VScode,我可以在 while(1) 循环中中断,但然后呢...?)。
它总是在这里崩溃:
HardFault_Handler
prvPortStartFirstTask
xPortStartScheduler
Run Code Online (Sandbox Code Playgroud)
抱歉问了这么长的问题,但我至少想彻底地回答,并希望有人可以确认一些事情,或者甚至可以帮助我朝正确的方向克服这个问题......
提前谢谢了!
任务切换时出现HF的常见原因有3种:
我个人更喜欢在调度程序启动时在任务中进行初始化。它可以防止许多非常难以跟踪的代码问题。
我使用 freeRTOS 运行 HAL、LWIP、不同类型的网络连接,没有任何问题。