STM32 【FreeRTOS HAL库】创建任务

一、创建任务的相关函数

1、osThreadDef宏定义的理解

#define osThreadDef(name, thread, priority, instances, stacksz)  \
const osThreadDef_t os_thread_def_##name =  { #name, (thread), (priority), (instances), (stacksz)  }

所以

osThreadDef(Display, DisLCD_Task,osPriorityNormal, 0, 128);
//相当于
const   osThreadDef_t   os_thread_def_Display = { "Display", (DisLCD_Task), (osPriorityNormal), (0), (128)  }

因此

  • osThreadDef相当于定义了一个 os_thread_def_Display常量,并且赋值。
  • 宏定义中,##的作用就是把2个宏参数连接为1个数,或实现字符串的连接
  • #的作用就是将#后面的宏参数进行字符串的操作,也就是将#后面的参数(Display)两边加上一对双引号使其成为字符串("Display")

osThreadDef()这个函数的最后一个参数设为0时表示使用默认栈大小。如果需要的话,也可以通过在线程结构体里定义一个更大的栈来增加额外的存储资源。

osThreadDef(thread1, osPriorityNomal, 1, 0); //分配默认栈大小

osThreadDef(thread2, osPriorityNomal, 1, 1024); //分配1kB的栈大小

当然,如果你分配了更大的栈空间,在RTOS配置文件里就需要增加额外的存储空间。

2、osThreadDef_t 结构体的定义

线程定义结构包含线程的启动信息。

typedef struct os_thread_def  {
  char                   *name;        //任务名
  os_pthread             pthread;      //函数指针指向任务函数
  osPriority             tpriority;    //枚举类型的任务优先级
  uint32_t               instances;    //传递参数
  uint32_t               stacksize;    //堆栈大小;0是默认的堆栈大小
} osThreadDef_t;

//Entry point of a thread.
typedef void (*os_pthread) (void const *argument);

typedef enum  {
  osPriorityIdle          = -3,          ///< priority: idle (lowest)
  osPriorityLow           = -2,          ///< priority: low
  osPriorityBelowNormal   = -1,          ///< priority: below normal
  osPriorityNormal        =  0,          ///< priority: normal (default)
  osPriorityAboveNormal   = +1,          ///< priority: above normal
  osPriorityHigh          = +2,          ///< priority: high
  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
} osPriority;

所以通过osThreadDef相当于当定义了一个结构体变量os_thread_def_Display

3、osThreadCreate

函数原型

osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument)

功能

使用 osThreadDef 宏所定义的结构体变量来创建一个线程。创建好线程后,然后进入 READY 状态,等待任务管理来调度运行。

参数

参数 1:指定osThreadDef所定义结构体变量的指针,通过该指针即可访问结构体变量,然后使用里面的信息来创建线程。由于结构体变量名字的前面有一个os_thread_def_前缀,所以需要使用 osThread宏来添加前缀,如果指定的名字为task1的话,第一个参数应该写为osThread(task1),进行宏替换后的最终效果为&os_thread_def_task1。实际上我们完全可以将第一个参数直接写为&os_thread_def_task1,不过使用osThread宏显然会更方便一些。

参数 2:传递给线程函数的参数。线程函数的参数 argument 的值就来自于这里,如果没有什么参数要传递的,就设置为NULL。

返回值:

函数调用成功就返回唯一标识线程的线程 ID(句柄),如果失败就返回 NULL。

二、创建任务实现


在使用 FreeRTOS 的过程中,我们要使用函数osThreadDef()创建任务,什么是任务函数?任务函数就是完成本任务工作的函数。比如点亮一个LED灯这就是一个任务,我们就可以将他放在任务函数中去执行。

osThreadId AppTaskHandle;//【1】定义任务函数句柄

void AppTask(void const * argument);//【2】声明任务函数

//创建任务函数
osThreadDef(AppTaskName, AppTask, osPriorityNormal, 0, 128);
AppTaskHandle = osThreadCreate(osThread(AppTaskName), NULL);

//任务函数实现
void AppTask(void const * argument)(1)
{
  
  for(;;)(2)
  {
    (3)
    
    osDelay(5);//调用延时才会释放资源(4)
  }
}

(1)任务函数的本质还是一个函数,每一个函数都有自己的名字那么任务函数也有对应的名字,任务函数的返回类型一定要为 void 类型,也就是无返回值,而且任务的参数也是 void 指针类型的!任务函数的名字可以根据自己来定义。

(2)任务函数执行的过程就是一个大循环,for(;;)这和while循环都是差不多的,都是一个死循环。

(3)循环里面执行的是主要代码。

(4)FreeRTOS的延时函数,调用此函数才会释放资源。
 

猜你喜欢

转载自blog.csdn.net/T19900/article/details/130530399