Freertos 软件定时器进入HardFault_Handler

在一个项目中使用到了Freertos,但是在gui界面显示1秒后切换界面,用到了freertos软件定时器,使用了队列来夸任务传递标志位,导致进入HardFault_Handler,经历了四天时间才找到问题,开始网上各种搜搜,HardFault_Handler定位方法,最后使用CmBacktrace库找到问题

经过层层帅选,和层层测试,下面代码是导致HardFault_Handler中断的最终问题

static void vTimerCallback(xTimerHandle pxTimer)
{
	time_struct *ptMsg;
	ptMsg = &time;
	Lcd_struct *userptMsg;
	userptMsg = &Lcd_flag;
	switch((uint8_t)Lcd_flag.auto_pwer_off_flag)
	{
		case true:
			if (ptMsg->time_sec_count > 0)
			{
				ptMsg->time_sec_count--;
			}
			else
			{
				
				if (ptMsg->time_min_count <=0)
					{
		//				POWER_OFF;		//关掉电源
		//				ptMsg->time_sec_count = 0;
		//				ptMsg->time_min_count = 0;
					}
				else
					{
						ptMsg->time_min_count--;
						ptMsg->time_sec_count = 59;
					}
			}
			if( xQueueSend(xQueue_timer,(void *) &ptMsg,(TickType_t)2) != pdPASS)
			{
			
			}
			else
			{
				/* 发送成功 */
			}
			break;
		case false:
			break;
		default:;
	}
	if (userptMsg->power_save_flag == true)
	{
		if (userptMsg->save_lv_dis_timer < 1)		/*保存界面显示时间*/
		{
			userptMsg->save_lv_dis_timer++;
		}
		else
		{
			userptMsg->power_save_flag = false;
			if( xQueueSend(xQueue_button,(void *) &userptMsg,(TickType_t)5) != pdPASS)
			{
			
			}
			else
			{
				//xQueueReceive(xQueue_button,(void *)&userptMsg,5);/*这里是导致进入HardFault_Handler的最终关键问题*/
				/* 发送成功 */
			}
			
		}
	}
	else
	{
	}
	
}

查找方法:

一、先把CmBacktrace库加载到工程里面去,参考http://t.csdnimg.cn/zkPPK

二、使用串口打印出来错误信息

固件名称:CmBacktrace,硬件版本号:V1.0.0,软件版本号:V0.1.0
在线程(Tmr Svc)中发生错误异常
=========== 线程堆栈信息 ===========
  addr: 2000bfb8    data: a5a5a5a5
  addr: 2000bfbc    data: a5a5a5a5
  addr: 2000bfc0    data: 0000a5a5
  addr: 2000bfc4    data: 00001f6b
  addr: 2000bfc8    data: 00000000
  addr: 2000bfcc    data: 0802ad33
  addr: 2000bfd0    data: a5a5a5a5
  addr: 2000bfd4    data: 00000000
  addr: 2000bfd8    data: 2000bfec
  addr: 2000bfdc    data: a5a5a5a5
  addr: 2000bfe0    data: a5a5a5a5
  addr: 2000bfe4    data: 0802aed1
  addr: 2000bfe8    data: 0802aec1
  addr: 2000bfec    data: 00000000
  addr: 2000bff0    data: a5a5a5a5
  addr: 2000bff4    data: a5a5a5a5
====================================
========================= 寄存器信息 =========================
  R0 : 00000001  R1 : 00000000  R2 : ffffffff  R3 : 000000a5
  R12: 2000a69e  LR : 08031b31  PC : a5a5a5a4  PSR: 21000000
==============================================================
发生存储器管理错误,原因:企图从不允许访问的区域取指令
查看更多函数调用栈信息,请运行:addr2line -e CmBacktrace.axf -afpiC a5a5a5a4 08031b30 0802ad32 0802aed0 0802aec0 

三、使用Windows命令工具进行查找

确定了和队列接收函数和定时器函数有关,然后在锁定在定时器创建函数,一步步屏蔽,仿真调试,经过十多次的反复操作最终确定了xQueueReceive函数的问题。

总结:软件定时器的回调函数是在定时器服务任务中执行的,所以一定不能在回调函数中调用任何会阻塞任务的 API 函数! 比如,定时器回调函数中千万不能调用 vTaskDelay ()、vTaskDelayUnti (),还有一些访问队列或者信号量的非零阻塞时间的 API 函数也不能调用。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值