关于FreeRTOS的延时函数vTaskDelay使用问题

项目场景:

` 最近在准备找工作,没有实际的项目和经验,就买了几个模块结合FreeRTOS来拼凑拼凑整成一个项目——基于ESP8266的远程温度监控,使用MQTT协议和搭载FreeRTOS系统。

省流:vTaskDelay的使用需要放在任务中,否则运行不了!


问题描述:

使用ESP8266时候,按照oneNET的例程移植到STM32上,能够很好的运行,但是把代码复制到FreeRTOS时候却一直初始化不了,等于说是卡在初始化了。下图为初始化函数摆放位置。

在这里插入图片描述

原因分析:

在使用串口函数一步一步的在每一个函数内外部设置打印信息后,初步发现问题是出在vTaskDelay函数上,如下图所示
在这里插入图片描述

就是进入了延时函数vTaskDelay之后就没出来。
分析:
进入延时函数查看问题(函数是官方的,不可能有问题,所以问题大概出在哪里任务没弄好或者其他冲突),发现延时函数有vTaskSuspendAll函数和xTaskResumeAll函数的,初步感觉到了问题应该是出在任务的调度上,所以就把ESP8266_Init函数放在开启任务调度函数vTaskStartScheduler后边,结果还是没有用,查资料后才知道任务调度函数后不执行后边的语句。
再接着看延时函数里面的后续函数时候发现prvAddCurrentTaskToDelayedList,看着名字想起来了问题所在了:由于ESP8266_Init函数在主函数内,而且里面还有延时函数,所以此时没有任务创建和运行,无法进行延时函数里面的任务阻塞。延时函数vTaskDelay里的prvAddCurrentTaskToDelayedList是将当前任务加入到延时列表中。所以任务都没有,何来的延时。更具体的后续函数和原理我也疏于学习就没有了解,就不分析了,直到这一步已经能够解决问题了。

	延时函数部分内容:
	void vTaskDelay( const TickType_t xTicksToDelay )
	{
	BaseType_t xAlreadyYielded = pdFALSE;
		if( xTicksToDelay > ( TickType_t ) 0U )
		{
			configASSERT( uxSchedulerSuspended == 0 );
			vTaskSuspendAll();    //任务挂起
			{
				traceTASK_DELAY();
				prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );//问题就出在这里
			}
			xAlreadyYielded = xTaskResumeAll();//任务恢复
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}


总结:

由于目前主要任务是找工作而完成项目,对于更深层次的学习就只能在后边学了。目前对于FreeRTOS的掌握程度只是要求会移植会使用,满足项目的需求而已。
最后的解决方式:将ESP8266的初始化有关函数放在一个任务里,完成后删除该任务或者放在创建任务的函数中,例如:

void start_task(void *pvParameters)
{
	
    taskENTER_CRITICAL();           //进入临界区
    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
								
	ESP8266_Init();					//初始化ESP8266
	while(OneNet_DevLink())			//接入OneNET
		vTaskDelay(500);
	OneNet_Subscribe(topics, 1);
	
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
								
}

最后运行成功:
在这里插入图片描述

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值