STM32-FreeRTOS使用独立看门狗实现多任务监护

问题:如何实现多任务下,存在一个或者多个任务异常时,触发看门狗。

环境:STM32F407VET6,IWDG,FreeRTOS。

思路:任务内部进行对事件组操作,看门狗任务来维护事件组,当超过设定的最大喂狗时间还没有喂狗的话,程序会重启。

辅助代码:

typedef struct __BIT32
{
	uint8_t bit0:1;
	uint8_t bit1:1;
	uint8_t bit2:1;
	uint8_t bit3:1;
	uint8_t bit4:1;
	uint8_t bit5:1;
	uint8_t bit6:1;
	uint8_t bit7:1;
	
	uint8_t bit8:1;
	uint8_t bit9:1;
	uint8_t bit10:1;
	uint8_t bit11:1;
	uint8_t bit12:1;
	uint8_t bit13:1;
	uint8_t bit14:1;
	uint8_t bit15:1;
	
	uint8_t bit16:1;
	uint8_t bit17:1;
	uint8_t bit18:1;
	uint8_t bit19:1;
	uint8_t bit20:1;
	uint8_t bit21:1;
	uint8_t bit22:1;
	uint8_t bit23:1;
	
	uint8_t bit24:1;
	uint8_t bit25:1;
	uint8_t bit26:1;
	uint8_t bit27:1;
	uint8_t bit28:1;
	uint8_t bit29:1;
	uint8_t bit30:1;
	uint8_t bit31:1;
}BIT32;

typedef union __UINT32_BT
{
	BIT32 Bit;
	uint32_t uStatus;
}UINT32_BT;

// 事件
EventGroupHandle_t  EventGroupHandler;

// 事件标志位
#define EVENTBIT0  			(1 << 0)
#define EVENTBIT1  			(1 << 1)
#define EVENTBIT2  			(1 << 2)
#define EVENTBIT3  			(1 << 3)
#define EVENTBIT4  			(1 << 4)
#define EVENTBIT5  			(1 << 5)
#define EVENTBIT6  			(1 << 6)
#define EVENTBIT7  			(1 << 7)
#define EVENTBIT8  			(1 << 8)
#define EVENTBIT9  			(1 << 9)
#define EVENTBIT10  		(1 << 10)
#define EVENTBIT11  		(1 << 11)
#define EVENTBIT12 			(1 << 12)

//任务优先级
#define START_TASK_PRIO			1
//任务堆栈大小	
#define START_STK_SIZE 			256  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);


//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区	
    
	EventGroupHandler = xEventGroupCreate(); // 创建事件组
	
	__CreateOutputIoTask();			// 创建TASK1任务					需要看门狗监护	
	__CreateIwdgEventGroup();		// 创建看门狗任务			独立看门狗
				
    vTaskDelete(StartTask_Handler); //删除开始任务
    
    taskEXIT_CRITICAL();            //退出临界区
}

void xSystemTaskCreate(void)
{
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 抢占优先级0-15 响应优先级0
	xSystemTaskCreate();//创建系统任务
}

看门狗任务:

/*任务优先级*/
#define IWDG_TASK_PRIO		3			// 该值越大优先级越高
/*任务堆栈大小*/
#define IWDG_STK_SIZE    	128  
/*任务句柄*/
TaskHandle_t IwdgTask_Handler;
/*任务函数*/
void IwdgTask(void *pvParameters);

void IwdgTask(void *pvParameters)
{
	UINT32_BT EventBit32;
	EventBit32.uStatus = 0;
	
	//
	//  需要增加独立看门狗初始化
	// 例如: ST_IWDG_Init(4,400);
	// 
	
	// 设置需要等待的事件	这里只等待一个事件 可以根据自己的实际情况来选择是否开启等待事件
	EventBit32.Bit.bit1 = 1;	// 任务1
	//EventBit32.Bit.bit2 = 1;	// 任务2
	//EventBit32.Bit.bit3 = 1;	// 任务3
	//EventBit32.Bit.bit4 = 1;	// 任务4
	//EventBit32.Bit.bit5 = 1;	// 任务5
	//EventBit32.Bit.bit6 = 1;	// 任务6
	
	for(;;)
	{		
		if(EventGroupHandler != NULL)
		{	
			// 这里需要注意 
			// 因为 xEventGroupWaitBits采用的是等待所有事件,
			// 所以xEventGroupWaitBits函数会阻塞等待所有事件都被xEventGroupSetBits()过。
			xEventGroupWaitBits( (EventGroupHandle_t) EventGroupHandler,
							    ( EventBits_t) (EventBit32.uStatus),	// 需要等待的事件
								( BaseType_t ) pdTRUE,	// 等待后 清零
								( BaseType_t ) pdTRUE,	// 等待所有事件
								( TickType_t ) portMAX_DELAY );
			
			// 
			// 需要增加喂狗处理
			// 例如:  iwdgFeed();	// 所有线程运行正常 开始喂狗
			//
		}

		vTaskDelay(100);					//延时100ms,也就是100个时钟节拍
	}
}

void __CreateIwdgEventGroup(void)
{
	taskENTER_CRITICAL();	//关中断
	
	xTaskCreate((TaskFunction_t )IwdgTask,            //任务函数
                (const char*    )"IwdgTask",          //任务名称
                (uint16_t       )IWDG_STK_SIZE,       //任务堆栈大小
                (void*          )NULL,                //传递给任务函数的参数
                (UBaseType_t    )IWDG_TASK_PRIO,      //任务优先级
                (TaskHandle_t*  )&IwdgTask_Handler);  //任务句柄        
	taskEXIT_CRITICAL();	//开中断
}

需要监护的任务
任务1:

/*任务优先级*/
#define TASK1_PRIO		3			// 该值越大优先级越高
/*任务堆栈大小*/
#define TASK1_STK_SIZE    	128  
/*任务句柄*/
TaskHandle_t Task1_Handler;
/*任务函数*/
void Task1(void *pvParameters);

static void __SetEventGruopBit1(void)
{
	if(EventGroupHandler != NULL)
	{
		// 设置事件组Bit1
		xEventGroupSetBits(EventGroupHandler,EVENTBIT1);
	}
}

void Task1(void *pvParameters)
{
	for(;;)
	{	
		__SetEventGruopBit1();// 设置事件组Bit1
		vTaskDelay(50);	//延时50ms,也就是50个时钟节拍	
	}
}

void __CreateOutputIoTask(void)
{
    taskENTER_CRITICAL();	//关中断
	
	xTaskCreate((TaskFunction_t )Task1,            //任务函数
                (const char*    )"Task1",          //任务名称
                (uint16_t       )TASK1_STK_SIZE,   //任务堆栈大小
                (void*          )NULL,             //传递给任务函数的参数
                (UBaseType_t    )TASK1_PRIO,       //任务优先级
                (TaskHandle_t*  )&Task1_Handler);  //任务句柄        
	taskEXIT_CRITICAL();	//开中断
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值