首页 > 其他分享 >FreeRTOS系列补充2:重点API函数的应用代码范例(特特特详细)

FreeRTOS系列补充2:重点API函数的应用代码范例(特特特详细)

时间:2024-04-01 18:29:32浏览次数:18  
标签:优先级 函数 FreeRTOS 句柄 void 特特特 任务 API 原型

目录

1、任务创建和删除API函数

 动态创建任务函数原型

 动态创建任务函数使用范例

 静态创建函数原型

静态创建任务函数使用范例

任务删除函数原型

任务删除函数使用范例

2、任务挂起和恢复函数

任务挂起函数原型

任务恢复函数(任务中恢复)原型

任务恢复函数(中断中恢复)原型

任务恢复函数(中断中恢复)使用范例

任务恢复和挂起函数总结

3、临界区的代码保护函数

任务级进入和退出临界段函数原型

任务级进入和退出临界段函数使用范例

中断级进入和退出临界段函数原型

中断级进入和退出临界段函数使用范例

4、任务调度器的挂起和恢复

 任务调度器的挂起和恢复函数原型

任务调度器的挂起和恢复函数的使用范例

6、任务调度器的开启

开启任务调度器函数原型

7、时间片调度配置

注意:使用时间片调度需把宏 configUSE_TIME_SLICING 和 configUSE_PREEMPTION 置1

8、Freertos任务相关API函数

获取任务优先级的函数原型

获取任务优先级函数优先级的函数使用范例

改变某个任务的任务优先级函数原型

改变某个任务的任务优先级函数原型的使用范例

获取系统中任务数量的API函数原型

获取系统中任务数量的API函数使用范例

获取所有任务状态信息函数原型

获取所有任务状态信息函数原型使用范例


前言

其实在网上已经有很多相关的博文了,不过我还是决定自己动手来记录一下。按照之前的经验,需要达到的目的为切题,详细。否则回看的时候不清楚。好多,整理的好累。

 动态创建任务函数原型

BaseType_t xTaskCreate
( 	TaskFunction_t 				pxTaskCode,		/* 指向任务函数的指针 */					
    const char * const 				pcName, 		/* 任务名字,最大长度configMAX_TASK_NAME_LEN */
	const 	configSTACK_DEPTH_TYPE 		usStackDepth, 	/* 任务堆栈大小,注意字为单位 */
	void * const 					pvParameters,	/* 传递给任务函数的参数 */
	UBaseType_t 					uxPriority,		/* 任务优先级,范围:0 ~ configMAX_PRIORITIES - 1 */
	TaskHandle_t * const 			pxCreatedTask 	/* 任务句柄,就是任务的任务控制块 */
)

返回值

描述

pdPASS

任务创建成功

errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY

任务创建失败

 动态创建任务函数使用范例

将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1

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


	//创建开始任务
    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);   //任务句柄     


//开始任务任务函数
void start_task(void *pvParameters)
{
    taskEXIT_CRITICAL();            //退出临界区
    //代码执行逻辑
    taskENTER_CRITICAL();           //进入临界区

}

 静态创建函数原型

TaskHandle_t xTaskCreateStatic(
    TaskFunction_t pxTaskCode,         /* 指向任务函数的指针 */
    const char *const pcName,          /* 任务函数名 */
    const uint32_t ulStackDepth,       /* 任务堆栈大小注意字为单位 */
    void *const pvParameters,          /* 传递的任务函数参数 */
    UBaseType_t uxPriority,            /* 任务优先级 */
    StackType_t *const puxStackBuffer, /* 任务堆栈,一般为数组,由用户分配 */
    StaticTask_t *const pxTaskBuffer   /* 任务控制块指针,由用户分配 */
);

返回值

描述

NULL

用户没有提供相应的内存,任务创建失败

其他值

任务句柄,任务创建成功

静态创建任务函数使用范例

不全,有点多,先放着静态的

#define START_TASK_PRIO 1                   // 任务优先级
#define START_STK_SIZE 128                  // 任务堆栈大小
StackType_t StartTaskStack[START_STK_SIZE]; // 任务堆栈
StaticTask_t StartTaskTCB;                  // 任务控制块
TaskHandle_t StartTask_Handler;             // 任务句柄
void start_task(void *pvParameters);        // 任务函数

// 创建开始任务
StartTask_Handler = xTaskCreateStatic((TaskFunction_t)start_task,     // 任务函数
                                      (const char *)"start_task",     // 任务名称
                                      (uint32_t)START_STK_SIZE,       // 任务堆栈大小
                                      (void *)NULL,                   // 传递给任务函数的参数
                                      (UBaseType_t)START_TASK_PRIO,   // 任务优先级
                                      (StackType_t *)StartTaskStack,  // 任务堆栈
                                      (StaticTask_t *)&StartTaskTCB); // 任务控制块                                           // 开启任务调度

// 开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL(); // 进入临界区
    // 创建TASK1任务
    taskEXIT_CRITICAL(); // 退出临界区
}

任务删除函数原型

void vTaskDelete(TaskHandle_t xTaskToDelete);

形参

描述

xTaskToDelete

待删除任务的任务句柄

任务删除函数使用范例

vTaskDelete(Task2Task_Handler);

这里调用这个函数的话,只需要传入需要删除的函数句柄就好了。这里的Task2Task_Handler只是为了进行演示使用的,大家可以根据自己的实际情况调整。以后这种只需要传入单个参数且参数为任务句柄同时无返回值时就不再写使用范例了,大家看到这里应该都是有基础的。

2、任务挂起和恢复函数

任务挂起函数原型

void vTaskSuspend(TaskHandle_t xTaskToSuspend) 

形参

描述

xTaskToSuspend

待挂起任务的任务句柄

此函数用于挂起任务,使用时需将宏 INCLUDE_vTaskSuspend  配置为 1。

无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复 。

注意:当传入的参数为NULL,则代表挂起任务自身(当前正在运行的任务)

任务恢复函数(任务中恢复)原型

void vTaskResume(TaskHandle_t xTaskToResume) 

形参

描述

xTaskToResume

待恢复任务的任务句柄

使用该函数注意宏:INCLUDE_vTaskSuspend必须定义为 1

注意:任务无论被 vTaskSuspend() 挂起多少次,只需在任务中调用  vTakResume() 恢复一次,就可以继续运行。且被恢复的任务会进入就绪态!

任务恢复函数(中断中恢复)原型

BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)  

形参

描述

xTaskToResume

待恢复任务的任务句柄

函数:xTaskResumeFromISR返回值描述如下:

返回值

描述

pdTRUE

任务恢复后需要进行任务切换

pdFALSE

任务恢复后不需要进行任务切换

使用该函数注意宏:INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1

该函数专用于中断服务函数中,用于解挂被挂起任务

注意:中断服务程序中要调用freeRTOS的API函数则中断优先级不能高于FreeRTOS所管理的最高优先级

任务恢复函数(中断中恢复)使用范例

#include <Arduino_FreeRTOS.h>

TaskHandle_t xTaskToResume = NULL;

void MyInterruptHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    // 尝试从 ISR 中恢复任务,这里注入的参数为函数句柄就可以了
    xHigherPriorityTaskWoken = xTaskResumeFromISR(xTaskToResume);

    // 如果需要,请求上下文切换,因为这个时候被恢复的任务优先级可能比正在执行地任务优先级更高。
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void setup()
{
    // 初始化任务、中断等
    // 将中断处理函数与相应的中断连接
    attachInterrupt(digitalPinToInterrupt(2), MyInterruptHandler, RISING);
}

void loop()
{
    // Empty. Things are done in tasks.
}

任务恢复和挂起函数总结

3、临界区的代码保护函数

应用场景:FreeRTOS在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断

任务级进入和退出临界段函数原型

函数

描述

taskENTER_CRITICAL()

任务级进入临界段

taskEXIT_CRITICAL()

任务级退出临界段

任务级进入和退出临界段函数使用范例

taskENTER_CRITICAL() ;
{
        … …	/* 临界区 */
}
taskEXIT_CRITICAL()	;	

中断级进入和退出临界段函数原型

函数

描述

taskENTER_CRITICAL_FROM_ISR()

中断级进入临界段

taskEXIT_CRITICAL_FROM_ISR()

中断级退出临界段

中断级进入和退出临界段函数使用范例

uint32_t  save_status;
save_status  = taskENTER_CRITICAL_FROM_ISR();
{
        … …	/* 临界区 */
}
taskEXIT_CRITICAL_FROM_ISR(save_status );	

4、任务调度器的挂起和恢复

挂起任务调度器, 调用此函数仅仅只是防止了任务间的资源争夺,中断照样可以响应。挂起调度器的防止,适用于临界区位于任务与任务之间。这样既不会延时中断,又可以做到临界区安全。

 任务调度器的挂起和恢复函数原型

函数

描述

vTaskSuspendAll()

挂起任务调度器

xTaskResumeAll()

恢复任务调度器

任务调度器的挂起和恢复函数的使用范例

vTaskSuspendAll() ;

{

        … …  /* 内容 */

}

xTaskResumeAll()  ; 

5、列表

6、任务调度器的开启

开启任务调度器函数原型

vTaskStartScheduler()

prvStartFirstTask ()   /* 开启第一个任务 */

vPortSVCHandler ()   /* SVC中断服务函数 */

7、时间片调度配置

注意:使用时间片调度需把宏 configUSE_TIME_SLICING configUSE_PREEMPTION 置1

8、Freertos任务相关API函数

获取任务优先级的函数原型

UBaseType_t  uxTaskPriorityGet(  const TaskHandle_t xTask  )

此函数用于获取指定任务的任务优先级,使用该函数需将宏 INCLUDE_uxTaskPriorityGet 置 1

形参

描述

       xTask

要查找的任务句柄,NULL代表任务自身

返回值

描述

整数

任务优先级数值

获取任务优先级函数优先级的函数使用范例

  // 创建任务并获取任务句柄
  xTaskCreate(Task1, "Task1", 100, NULL, 1, &xTaskHandle);

  // 获取任务的优先级并输出
  UBaseType_t priority = uxTaskPriorityGet(xTaskHandle);

改变某个任务的任务优先级函数原型

void vTaskPrioritySet( TaskHandle_t xTask , UBaseType_t uxNewPriority )

此函数用于改变某个任务的任务优先级,使用该函数需将宏 INCLUDE_vTaskPrioritySet  为 1

                     xTask

任务句柄,NULL代表任务自身

uxNewPriority

需要设置的任务优先级

改变某个任务的任务优先级函数原型的使用范例

// 定义任务句柄
TaskHandle_t xTask1Handle, xTask2Handle;
 // 创建任务2
xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, 2, &xTask2Handle);
vTaskPrioritySet(xTask2Handle, 3); // 将任务2的优先级设置为3

获取系统中任务数量的API函数原型

UBaseType_t uxTaskGetNumberOfTasks( void )

形参

描述

                     xTask

任务句柄,NULL代表任务自身

uxNewPriority

需要设置的任务优先级

获取系统中任务数量的API函数使用范例

// 获取当前活动任务的数量并输出
  UBaseType_t numTasks = uxTaskGetNumberOfTasks();

获取所有任务状态信息函数原型

UBaseType_t  uxTaskGetSystemState(   TaskStatus_t * const pxTaskStatusArray,
                                      				const UBaseType_t uxArraySize,
                                      				configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime  )

此函数用于获取系统中所有任务的任务状态信息,使用该函数需将宏 configUSE_TRACE_FACILITY 置 1

形参

描述

xTaskStatusArray

指向TaskStatus_t 结构体数组首地址

uxArraySize

接收信息的数组大小

pulTotalRunTime

系统总运行时间,为NULL 则省略总运行时间值

形参

描述

xTaskStatusArray

指向TaskStatus_t 结构体数组首地址

获取所有任务状态信息函数原型使用范例

#include <FreeRTOS.h>
#include <task.h>

#define TASKS_ARRAY_SIZE 10

TaskHandle_t xTask1Handle, xTask2Handle;

void vTask1(void *pvParameters) {
    // 任务1的代码
    while(1) {
        // 执行任务1的操作
    }
}

void vTask2(void *pvParameters) {
    // 任务2的代码
    while(1) {
        // 执行任务2的操作
    }
}

void main(void) {
    TaskStatus_t xTaskStatusArray[TASKS_ARRAY_SIZE];
    UBaseType_t uxArraySize;

    // 创建任务1
    xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, NULL, 1, &xTask1Handle);

    // 创建任务2
    xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, 2, &xTask2Handle);

    // 启动任务调度器
    vTaskStartScheduler();

    // 获取系统中所有任务的状态信息
    uxArraySize = uxTaskGetSystemState(xTaskStatusArray, TASKS_ARRAY_SIZE, NULL);

    // 打印任务状态信息
    for (UBaseType_t i = 0; i < uxArraySize; i++) {
        printf("Task Name: %s, Priority: %d, State: %d\n",
               xTaskStatusArray[i].pcTaskName,
               xTaskStatusArray[i].uxCurrentPriority,
               xTaskStatusArray[i].eCurrentState);
    }

    // 任务调度器不会返回,除非发生错误
    for(;;);
}

这里想要提取哪些信息的话需要根据结构体的成员变量改变

typedef struct xTASK_STATUS
{
          TaskHandle_t xHandle; //任务句柄
          const char * pcTaskName; //任务名字
          UBaseType_t xTaskNumber; //任务编号
          eTaskState eCurrentState; //当前任务壮态, eTaskState 是一个枚举类型
          UBaseType_t uxCurrentPriority; //任务当前的优先级
          UBaseType_t uxBasePriority; //任务基础优先级
          uint32_t ulRunTimeCounter;//任务运行的总时间
          StackType_t * pxStackBase; //堆栈基地址
          uint16_t usStackHighWaterMark;//从任务创建以来任务堆栈剩余的最小大小,此
                                        //值如果太小的话说明堆栈有溢出的风险。
} TaskStatus_t;

获取单个任务的状态信息原型

void vTaskGetInfo(
    FTaskHandle_t xTask,
    TaskStatus_t *pxTaskStatus,
    BaseType_t xGetFreeStackSpace,
    eTaskState eState)

形参

描述

xTask

指定获取信息的任务的句柄

pxTaskStatus

接收任务信息的变量

xGetFreeStackSpace

任务栈历史剩余最小值,

当为“pdFALSE” 则跳过这个步骤,

当为“pdTRUE”则检查历史剩余最小堆栈

eState

任务状态,可直接赋值,如想获取代入“eInvalid”

获取单个任务的状态信息使用范例

    TaskStatus_t xTaskStatus;

    // 创建一个任务
    TaskHandle_t xTaskHandle;
    xTaskCreate(vTaskFunction, "Task", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandle);
    // 获取任务的信息
    vTaskGetInfo(xTaskHandle, &xTaskStatus, pdFALSE, eRunning);

    // 打印任务的状态信息
    printf("Task Name: %s\n", xTaskStatus.pcTaskName);
    printf("Task Priority: %d\n", xTaskStatus.uxCurrentPriority);
    printf("Task State: %d\n", xTaskStatus.eCurrentState);

直接获取当前任务的任务句柄函数原型

TaskHandle_t    xTaskGetCurrentTaskHandle( void ) 

此函数用于获取当前任务的任务句柄, 使用该函数需将INCLUDE_xTaskGetCurrentTaskHandle  置 1

返回值

描述

                      TaskHandle_t

当前任务的任务句柄

直接获取当前任务的任务句柄函数使用范例

     TaskHandle_t xTaskHandle;
// 获取当前任务的句柄
    xTaskHandle = xTaskGetCurrentTaskHandle();

    // 打印当前任务的句柄
    printf("Current Task Handle: %p\n", xTaskHandle);

通过任务名获取任务句柄函数原型

TaskHandle_t xTaskGetHandle(const char * pcNameToQuery); 

通过任务名获取任务句柄函数使用范例

void main(void) {
    TaskHandle_t xTaskHandle;

    // 创建一个任务
    xTaskCreate(vTaskFunction, "Task1", configMINIMAL_STACK_SIZE, NULL, 1, &xTaskHandle);

    // 获取任务句柄
    TaskHandle_t xTaskHandle2 = xTaskGetHandle("Task1");

    // 检查句柄是否有效
    if (xTaskHandle2 != NULL) {
        printf("Task1 handle: %p\n", xTaskHandle2);
    } else {
        printf("Task1 not found!\n");
    }

    for (;;) {
        // 主循环
    }
}

标签:优先级,函数,FreeRTOS,句柄,void,特特特,任务,API,原型
From: https://blog.csdn.net/qq_51519091/article/details/137223338

相关文章

  • php获取淘宝详情api接口
    要获取淘宝商品的详情信息,你可以使用淘宝开放平台的接口。具体步骤如下:在淘宝开放平台(https://open.taobao.com)注册开发者账号。创建一个应用,获取appkey和appsecret。使用API中的taobao.item.get接口,传入商品ID以及appkey,即可获取商品的详情信息。示例代码如下(使用淘宝......
  • 基于 Python + Requests + Unitest + HwTestReport的API自动化测试框架
    一、框架目录结构概览 二、框架执行流程简介 三、框架目录结构简介▹case:存放测试用例▹data:存放测试数据及测试数据的处理▹config:存放相关配置文件(Token获取、Excel测试数据读取、requests二次封装等)▹file:存放测试接口信息▹report:存放测试报告▹to......
  • vsphere API 调用创建虚拟机
    1.版本介绍vsphere:vSphereClient版本7.0.3.01100VsphereAPI参考地址:vSphereWebServicesAPI-VMwareAPIExplorervsphereAPI github给的参考例子地址:pyvmomi-community-samples/samples/tools/service_instance.pyatmaster·vmware/pyvmomi-c......
  • cJSON(API的详细使用教程)
    我们今天来学习一般嵌入式的必备库,JSON库1,json和cJSON那什么是JSON什么是cJSON,他们之间有什么样的关联呢,让我们一起来探究一下吧。JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,它易于人阅读和编写,也易于机器解析和生成。JSON采用键值对的方式来表示数据,通常用......
  • 通过企业微信API接口发送消息(通过postman或者企业微信开发者中心《服务端API调试工具
    如何创建一个与企业后台互动的自建应用添加自建应用登录企业微信管理后台->应用管理->自建下创建应用,填写必要的logo,应用名称,在可见范围中选择部门/成员获取应用的相关信息agentid和secret;应用里创建完毕可出现在选择了可见范围的成员的企业微信终端上。使用Postman调试api......
  • 5、SDK、API、组件
    1、SDK,全称SoftwareDevelopmentKit,中文意思为“软件开发工具包”。一般而言,SDK是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。SDK是一个覆盖面相当广泛的术语,可以这么说:辅助开发某一类软件的相关文档、范例和工具的集合都可......
  • Java常用API二
    BigDecimal用于解决浮点数运算时,出现结果失真的问题 传统时间:Date日期类//1、创建一个Date的对象,代表系统当前的时间信息Dated=newDate();System.out.println(d);//2、拿到时间毫秒值longtime=d.getTime();//3、把时间毫秒值转换成日期对象:2s后时间是多少time+=......
  • ChatGPT和OpenAI API将如何颠覆我们的生活?
    重磅专栏推荐:《大模型AIGC》《课程大纲》《知识星球》本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和StableDiffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经验......
  • Scheduling and Traffic Shaping 学习笔记(一)
    Time-AwareShaping  参考:https://inet.omnetpp.org/docs/showcases/tsn/trafficshaping/timeawareshaper/doc/index.html目标:时间感知整形的工作原理是将时间划分为固定的间隔或窗口,并根据帧的优先级在这些窗口内调度帧的传输。通过在单独的窗口中发送优先级较高的帧来......
  • 接口文档神器apidoc
    1、apidoc介绍1、apidoc是什么?api文档生成工具:基于源代码备注创建的接口文档;2、apidoc优势是啥?超简单文档生成器:几乎支持目前主流的所有风格的注释,如可在C#、Go、python、Java、JavaScript、PHP等语言中使用。便于管理和查看:有利于代码的阅读同时,也减轻文档编写工......