2.5多任务示例编程2

1.CUBEMX配置

2.代码

void StartADC(void const * argument)
{
  /* USER CODE BEGIN StartADC */
	TickType_t  pxPreviousWakeTime=xTaskGetTickCount();
  /* Infinite loop */
  for(;;)
  {
		HAL_ADC_Start(&hadc1);
		if(HAL_ADC_PollForConversion(&hadc1,100)==HAL_OK)
		{
		 uint32_t value=HAL_ADC_GetValue(&hadc1);
		 OLED_ShowNum(18,1,value,4,OLED_6X8);
			OLED_Update();
		}
    vTaskDelayUntil(&pxPreviousWakeTime,pdMS_TO_TICKS(500));
  }
  /* USER CODE END StartADC */
}

/* USER CODE BEGIN Header_StartInfo */
/**
* @brief Function implementing the Task_Info thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartInfo */
void StartInfo(void const * argument)
{
  /* USER CODE BEGIN StartInfo */
	TaskHandle_t taskHandle=Task_ADCHandle;
	TaskStatus_t Taskinfo;
	BaseType_t getFreeStackSpace=pdTRUE;
	eTaskState taskState=eInvalid;
	vTaskGetInfo(taskHandle,&Taskinfo, getFreeStackSpace, taskState)PRIVILEGED_FUNCTION;//获取任务信息的函数
	/*
	该函数输入参数有四个,TaskHandle_t xTask为所要查询任务的任务句柄;
	TaskStatus_t *pxTaskStatus为任务状态结构体,用于存放任务的状态,该结构体需要用户自定义;
	BaseType_t xGetFreeStackSpace为是否计算任务剩余最小堆栈大小,传入参数pdTRUE表示计算,但需要耗费一些时间;
	eTaskState eState为是否获取任务状态,输入参数eInvalid时表示获取任务状态,但同样也会消耗一些时间,否则用户指定任务状态,不会消耗时间。
	*/
	taskENTER_CRITICAL();//开启临界代码段,不允许任务调度CRITICAL主要的,关键的
//  uint8_t temp_str[100];
//	sprintf(temp_str,"Task Name=%s",Taskinfo.pcTaskName);
//		OLED_ShowString(1,9,"*(temp_str)",OLED_6X8);
	
//1	  OLED_Printf(1, 9,OLED_6X8,"Task Name=%s",Taskinfo.pcTaskName);
//		OLED_Printf(1, 18,OLED_6X8,"Task Number=%d",Taskinfo.xTaskNumber);//获取任务编号
//	  OLED_Printf(1, 27,OLED_6X8,"Task State=%d",Taskinfo.eCurrentState);
//	  OLED_Printf(1, 36,OLED_6X8,"Task Priority=%d",Taskinfo.uxCurrentPriority);
//	  OLED_Printf(1, 45,OLED_6X8,"High Mark=%d(word)",Taskinfo.usStackHighWaterMark);
//		OLED_Update();
//2	  taskHandle=xTaskGetIdleTaskHandle();
//	  OLED_Printf(1, 9,OLED_6X8,"Idle Task =%d",uxTaskGetStackHighWaterMark(taskHandle));
//		OLED_Printf(1, 18,OLED_6X8,"Task ADCr=%d",uxTaskGetStackHighWaterMark(Task_ADCHandle));
//	  OLED_Printf(1, 27,OLED_6X8,"Task Info=%d",uxTaskGetStackHighWaterMark(Task_InfoHandle));
//		OLED_Update();
//     OLED_Clear();
	  OLED_Printf(1, 9,OLED_6X8,"uxTaskGet=%d",uxTaskGetNumberOfTasks());//3获取任务的总数
		OLED_Update();
	
	  taskEXIT_CRITICAL();
//	OLED_ShowString(9,9,"taskIofo.pcTaskName",OLED_6X8);
//	OLED_Update();
  /* Infinite loop */
  for(;;)
  {
   for(uint8_t i=0;i<10;i++)
		{
//			OLED_Clear();
		  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
			vTaskDelay(pdMS_TO_TICKS(100));
		}
		break;
  }
//	OLED_Clear();
	OLED_Printf(1, 18,OLED_6X8,"Task_Info is deleted");
	 HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
	OLED_Update();
	vTaskDelete(NULL);
  /* USER CODE END StartInfo */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
//void vApplicationIdleHook(void)
//{
//  OLED_Clear();
//}

/* USER CODE END Application */
#define configUSE_TRACE_FACILITY 1   //vTaskGetInfo
#define INCLUDE_uxTaskGetStackHighWaterMark     1
#define INCLUDE_xTaskGetIdleTaskHandle 1 //xTaskGetIdleTaskHandle()

 使用静态创建函数创建 FreeRTOS 任务时,需要记住一点:必须实现 vApplicationGetIdleTaskMemory 函数来完成空闲任务的内存分配。这是因为在使用静态内存分配时,FreeRTOS 会自动创建一个空闲任务,该任务会在系统空闲时进行调度。
空闲任务可以执行某些不需要 CPU 时间的操作,比如暂时挂起 CPU、等待时钟中断、等待消息等,以便释放 CPU 资源给其它任务使用。
空闲任务需要分配堆栈和任务控制块,而这些内存区域需要手动向 FreeRTOS 系统申请。
在这种情况下,我们需要实现 vApplicationGetIdleTaskMemory 函数,该函数会在空闲任务创建之前被调用。
在该函数中,我们需要声明一个静态的变量作为空闲任务控制块的内存池,
并将该内存池的首地址和大小等信息传递给空闲任务创建函数,以完成空闲任务的内存分配。

任务使用的堆栈将随着任务的执行和中断的处理而增长和收缩。
uxTaskGetStackHighWaterMark()返回自任务开始执行以来任务可用的最小剩余堆栈空间量,
即任务堆栈达到最大(最深)值时未使用的堆栈量。这就是所谓的烟囱“高水位线”。
注意:返回值更新的前提是有新的最小值出现,否则即便初始化新的临时变量,可能也不会刷新这个 HiqhWaterMark 的值(因为 stacksize 减小了,但是没有到刷新最小值的地步)。
注意:Task 本身的 handle、状态管理不消耗这个 stack size(内部用的是malloc),
但是printf()这个函数是消耗 stack size 的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值