刚解了个FreeRTOS Timer Queue 满的Bug

博客内容描述了一个在FreeRTOS系统中遇到的Timer Queue满的Bug,导致板子无法发送CAN/LIN报文和心跳灯不闪烁。通过代码分析和调试,发现问题是由于一个ADC读取操作在timer回调中使用os_thread_sleep导致timer任务被挂起。解决方案是优化该ADC读取函数,避免在timer回调中阻塞。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现象:板子不发送任何CAN/LIN报文,心跳灯不闪烁,严重怀疑Aurix TC367 挂掉了。

动作:劳特巴赫 attach上午后发现是asert在prvProcessReceivedCommands( void )函数里面。

                        if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )
                        {
                            xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
                            configASSERT( xResult );
                 &nbs

### nRF52840 上使用 FreeRTOS 和定时器 当在 nRF52840 设备上配置并使用 FreeRTOS 时,了如何正确设置和管理定时器至关重要。这不仅涉及到硬件资源的有效利用,还关系到系统的稳定性和性能优化。 #### 配置 FreeRTOS 的基础架构 为了使 FreeRTOS 能够高效运作于 nRF52840 平台上,需先掌握其核心组件——任务(Task)、信号量(Semaphore)、互斥锁(Mutex)、事件标志组(Event Flags),以及队列(Queue)[^2]。这些机制共同作用以支持多线程编程环境下的进程间通信与同步操作。 #### 设置 HAL 基础时钟 尽管上述信息主要针对 STM32 系列微控制器,但在其他平台如 nRF52840 中也有相似考量。对于基于 ARM Cortex-M 架构的设备而言,推荐采用独立于 SysTick 外设的时间基准源来驱动操作系统调度程序;这样做可以避免因中断优先级冲突而导致潜在问题的发生[^1]。 #### 实现 APP 定时器模块初始化 下面展示了一段简单的 C++ 代码片段,用于演示如何初始化应用程序级别的计时服务: ```cpp // 初始化APP定时器模块 static void timers_init(void){ // 初始化APP定时器模块 ret_code_t err_code = app_timer_init(); // 检查返回值 APP_ERROR_CHECK(err_code); } ``` 此函数通过调用 `app_timer_init()` 来启动 SDK 提供的标准时间管理功能,并借助宏定义 `APP_ERROR_CHECK` 对可能产生的错误情况进行处理[^3]。 #### 创建自定义周期性回调任务 接下来是一个更具体的例子,它展示了怎样建立一个每秒触发一次的任务实例: ```c #include "nrf.h" #include "app_error.h" #include "app_timer.h" #define ONE_SECOND_IN_MS (uint32_t)(1000) void my_periodic_task(void * p_context) { // 用户定义的具体逻辑放在这里... } int main() { uint32_t err_code; // 初始化定时器子系统 timers_init(); // 注册新的定时器句柄 static app_timer_id_t periodic_timer_id; // 创建具有固定间隔重复执行特性的软件定时器 err_code = app_timer_create(&periodic_timer_id, APP_TIMER_MODE_REPEATED, my_periodic_task); APP_ERROR_CHECK(err_code); // 启动该定时器,设定初始延迟时间为零毫秒 err_code = app_timer_start(periodic_timer_id, APP_TIMER_TICKS(ONE_SECOND_IN_MS), NULL); APP_ERROR_CHECK(err_code); while(true) { __WFE(); // 进入等待状态直到被唤醒 } } ``` 这段代码实现了如下目标: - **timers_init()**: 如前所述完成必要的准备工作; - **my_periodic_task()**: 自定义的工作负载函数体; - **main()**: 主循环里包含了创建及激活指定频率(即一秒)下自动重启型软定时器的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值