02_FreeRTOS 任务管理

02_FreeRTOS 任务管理


本文将介绍:
a. 创建任务
b. 任务执行
c. 挂起任务和恢复任务
d. 在一定状态停止任务一段时间

附录:
如何在STM32CubeIDE中加入printf打印
解决STM32CubeIDE 用串口printf 进入hardfault

  1. 配置STM32CubeIDE,把vTaskDelayUntil 设置为Enabled

  2. 创建任务
    分三部:
    2.1 创建任务ID
    2.2 使用osThreadDef定义线程
    2.3 创建线程并将ID分配给任务处理程序。
    参照01_FreeRTOS 任务优先级

  3. 任务执行
    osDelay()会让当前的线程进入阻塞模式,到时间后就会退出阻塞模式。比如Task2 中延时2s Task1 中延时1s,所以当Taks2进入阻塞状态,Task1此时优先级最高运行一次后,Task1也进入阻塞状态,过去1s后再次运行Task1。当过去2s,两个Task都退出阻塞状态,此时由于Task2的优先级要比Task1的优先级高,故开始先运行Task2。如此往复。

优先级定义部分:

  /* definition and creation of Task1 */
  osThreadDef(Task1, Task1_init, osPriorityNormal, 0, 512);
  Task1Handle = osThreadCreate(osThread(Task1), NULL);

  /* definition and creation of Task2 */
  osThreadDef(Task2, Task2_init, osPriorityAboveNormal, 0, 512);
  Task2Handle = osThreadCreate(osThread(Task2), NULL);

printf部分:

uint8_t indx = 0;

void send_task1(void){
	printf("task1 running...\n");
}
void send_task2(void){
	printf("task2 indx= %d \n ",indx ++);
}

输出结果:

  1. 挂起任务和恢复任务

当Task被挂起后,它一直处于挂起状态,用osThreadSuspend函数挂起一个Task,参数是线程ID,用osThreadResume退出挂起状态。
在Task2 入口函数加入:

void Task2_init(void const * argument)
{
  /* USER CODE BEGIN Task2_init */
  /* Infinite loop */
  for(;;)
  {
	send_task2();
	osDelay(2000);
	if (indx==4)
	{
       printf ("suspending Task1Handle\n");
       osThreadSuspend(Task1Handle);

	}
	if (indx ==7)
	{
	   printf ("Resuming Task1Handle\n");
	   osThreadResume(Task1Handle);
	   indx = 0;
        }
  }
  /* USER CODE END Task2_init */
}

输出结果:

  1. 停止任务一段时间

osDelayUntil (uint32_t *PreviousWakeTime, uint32_t millisec)函数来实现,PreviousWakeTime指向开始停止的时候。

Task入口函数:

/* USER CODE END Header_Task2_init */
void Task2_init(void const * argument)
{
  /* USER CODE BEGIN Task2_init */
  /* Infinite loop */
  for(;;)
  {
	send_task2();
	osDelay(2000);
	if(indx == 5)
	{
	  uint32_t PreviousWakeTime = osKernelSysTick();
	  osDelayUntil(&PreviousWakeTime, 4000);
	}
  }
  /* USER CODE END Task2_init */
}

结果:

附录:

如何在STM32CubeIDE中加入打印串口printf

只需要在main.c中加入如下部分就可以实现串口printf:

// 把这部分加入主函数初始化中

  /* 禁用STDOUT流的I/O 缓冲,以便在打印字符时立即发送。*/
  setvbuf(stdout, NULL, _IONBF, 0);

// …



/* USER CODE BEGIN 0 */

#include "errno.h"
#include "stdio.h"

#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
int _write(int file, char* ptr, int len) {
	 /* 禁用STDOUT流的I/O 缓冲,以便在打印字符时立即发送。*/
	if (file == STDOUT_FILENO || file == STDERR_FILENO) {
		HAL_StatusTypeDef hstatus;
		hstatus = HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY);
		if (hstatus == HAL_OK)
		  return len;
		else
		  return EIO;
	}
	errno = EBADF;
	return -1;
}

/* USER CODE END 0 */

解决STM32CubeIDE 用串口printf 进入hardfault

分析:由于给Task分配的堆栈太小。
把堆栈加大到512,并且先要在main中执行一次printf才行,否则直接Hard Fault异常。 如图:

STM32CubeIDE其他设置,进入Project->Properties,如下设置:

即可使用printf向串口1打印数据。

Code下载地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gkbytes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值