当前位置: 首页 > news >正文

优秀网站模板中国10大装修公司排名

优秀网站模板,中国10大装修公司排名,网站开发的实例教程,站长之家seo概况查询五、FreeRTOS的任务恢复与挂起 5.1 任务挂起与恢复的API函数 5.1.1 任务挂起函数 void vTaskSuspend( TaskHandle_t xTaskToSuspend ) xTaskToSuspend:待挂起任务的任务句柄,为NULL表示挂起任务自身。需将宏INCLUDE_vTaskSuspend配置为 1。5.1.2 任务恢复函数 void vTaskRe…

五、FreeRTOS的任务恢复与挂起

5.1 任务挂起与恢复的API函数

5.1.1 任务挂起函数

void vTaskSuspend( TaskHandle_t xTaskToSuspend )

  • xTaskToSuspend:待挂起任务的任务句柄,为NULL表示挂起任务自身。
  • 需将宏INCLUDE_vTaskSuspend配置为 1。
5.1.2 任务恢复函数

void vTaskResume( TaskHandle_t xTaskToResume )

  • INCLUDE_vTaskSuspend必须定义为 1。
  • 不论任务被使用 vTaskSuspend() 挂起多少次,只需调用 vTaskResume() 一次,即可使其继续执行。被恢复的任务会重新进入就绪状态。
5.1.3 任务恢复函数(中断中恢复)

1)函数说明

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )

返回值如下:

  • pdTRUE:任务恢复后需要进行任务切换。
  • pdFALSE:任务恢复后不需要进行任务切换。

2)注意事项

  • INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1。
  • 在中断服务程序中调用FreeRTOS的API函数时,中断的优先级不能高于FreeRTOS所管理的最高中断优先级。
5.1.4 挂起与恢复调度器
  • vTaskSuspendAll():挂起任务调度器,调度器不会进行任务切换,当前任务一直运行。
  • xTaskResumeAll():恢复任务调度器,调度器继续任务切换。
5.1.5 查看任务状态

/* 开启跟踪task信息 */

#define configUSE_TRACE_FACILITY 1

#define configUSE_STATS_FORMATTING_FUNCTIONS 1

void vTaskList( char * pcWriteBuffer )

名称           状态    优先级  堆栈使用  任务编号

'X'(运行)    'B'(阻塞)、'R'(就绪)、'S'(挂起\暂停)或 'D'(删除)

示例函数:

/*** @description: 判断按键按下逻辑,KEY1按下,挂起task1,按下KEY2在任务中恢复task1,KEY3按下,挂起调度器,KEY4按下,恢复调度器,并打印任务的状态* @param {void} *pvParameters* @return {*}*/
char task_info[500]; //定义一个字符数组,用于接收任务信息字符串
void task3(void *pvParameters)
{uint8_t key = 0;while (1){printf("task3运行...\r\n");key = Key_Detect();if (key == KEY1_PRESS){/* key1按下,挂起task1 */printf(">>>>挂起task1....\r\n");vTaskSuspend(task1_handle);}else if (key == KEY2_PRESS){/* key2按下,恢复task1 */printf(">>>>恢复task1....\r\n");vTaskResume(task1_handle);}else if (key == KEY3_PRESS){/* key3按下,挂起调度器 */printf("<<<<挂起调度器....\r\n");vTaskSuspendAll();}else if (key == KEY4_PRESS){/* key4按下,恢复调度器 */printf("<<<<恢复调度器....\r\n");xTaskResumeAll();}/* 打印任务的状态 */vTaskList(task_info);printf("%s\r\n",task_info);vTaskDelay(500);}
}

六、中断处理

6.1 FreeRTOS中断

6.1.1 FreeRTOS的中断管理

        在STM32中,中断优先级是通过中断优先级配置寄存器的高4位 [7:4] 来配置的。因此STM32支持最多16级中断优先级,其中数值越小表示优先级越高,即更紧急的中断。(FreeRTOS任务调度的任务优先级相反,是数值越大越优先)

        FreeRTOS可以与STM32原生的中断机制结合使用,但它提供了自己的中断管理机制,主要是为了提供更强大和灵活的任务调度和管理功能。

        FreeRTOS中,将PendSV和SysTick设置最低中断优先级(数值最大,15),保证系统任务切换不会阻塞系统其他中断的响应。

        FreeRTOS利用BASEPRI寄存器实现中断管理,屏蔽优先级低于某一个阈值的中断。比如: BASEPRI设置为0x50(只看高四位,也就是5),代表中断优先级在5~15内的均被屏蔽,0~4的中断优先级正常执行。

在中断服务函数中调用FreeRTOS的API函数需注意:

  • 中断服务函数的优先级需在FreeRTOS所管理的范围内,阈值由configMAX_SYSCALL_INTERRUPT_PRIORITY指定。
  • 建议将所有优先级位指定为抢占优先级位,方便FreeRTOS管理。
  • 在中断服务函数里边需调用FreeRTOS的API函数,必须使用带“FromISR”后缀的函数。

6.1.2 FreeRTOS的开关中断

 FreeRTOS 开关中断函数其实是宏定义,在 portmacro.h 中有定义,如下:

#define portDISABLE_INTERRUPTS()                  vPortRaiseBASEPRI()

#define portENABLE_INTERRUPTS()                   vPortSetBASEPRI( 0 )

  • 调用portENABLE_INTERRUPTS() 它, FreeRTOS会打开管理的所有中断
  • 调用portDISABLE_INTERRUPTS() 它, FreeRTOS会关闭管理的所有中断

 6.1.3 FreeRTOS的临界段代码

临界段代码,又称为临界区,指的是那些必须在不被打断的情况下完整运行的代码段。例如,某些外设的初始化可能要求严格的时序,因此在初始化过程中不允许被中断打断。在FreeRTOS中,进入临界段代码时需要关闭中断,在处理完临界段代码后再重新开启中断。FreeRTOS系统本身包含许多临界段代码,并对其进行了保护。在编写用户程序时,有些情况下也需要添加临界段代码以确保代码的完整性。

与临界段代码保护有关的函数有 4 个:

  • taskENTER_CRITICAL() :进入临界段。
  • taskEXIT_CRITICAL() :退出临界段。
  • taskENTER_CRITICAL_FROM_ISR() :进入临界段(中断级)。
  • taskEXIT_CRITICAL_FROM_ISR():退出临界段(中断级)。

进入和退出临界段是成对使用的。每进入一次临界段,全局变量uxCriticalNesting都会加一,每调用一次退出临界段,uxCriticalNesting减一,只有当 uxCriticalNesting 为 0 的时候才会调用函数 portENABLE_INTERRUPTS()使能中断。这确保了在存在多个临界段代码的情况下,不会因为某个临界段代码的退出而破坏其他临界段的保护。只有当所有的临界段代码都退出时,中断才会被重新使能。

6.1.4 挂起和恢复任务调度器

挂起和恢复任务调度器, 调用此函数不需要关闭中断:

  • vTaskSuspendAll():挂起任务调度器。
  • xTaskResumeAll():恢复任务调度器。

与临界区不同的是,挂起任务调度器时未关闭中断;这种方式仅仅防止了任务之间的资源争夺,中断仍然可以直接响应;挂起调度器的方法适用于临界区位于任务与任务之间的情况;这样既不需要延迟中断,同时又能确保临界区的安全性。

6.2 中断实验

1.目标:

学会FreeRTOS中断管理:

  • 设置管理的优先级范围:5~15。
  • 使用两个定时器,一个优先级为4,一个优先级为6。
  • 两个定时器每1s,打印一段字符串。
  • task1:按下KEY1,关中断,按下KEY2,开中断。

观察两个定时器的打印情况。

2.添加定时器

 

 

添加完定时器,重新注释掉stm32f1xx_it.c的SVC_Handler和PendSV_Handler函数。

3.示例代码:

注意:关于延迟函数:使用HAL_Delay前提:HAL时钟修改成其他定时器,并且中断优先级高于freertos的管理范围

//#main.c
/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2)
    {
       printf("TIM2优先级为4,运行中...\r\n");
    }
    else if(htim->Instance == TIM3)
    {
       printf("TIM3优先级为6,运行中...\r\n");
    }
}
/* USER CODE END 0 */  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);  
  HAL_TIM_Base_Start_IT(&htim3);  
  /* USER CODE END 2 *///#FreeRTOSConfig.h
/*3. 中断嵌套行为相关配置 cm3内核:我们要求4个优先级位全部为抢占优先级位
    最高优先级是 0
    最低优先级是 15
*/
/* 设置 RTOS 内核自身使用的中断优先级。 一般设置为最低优先级, 不至于屏蔽其他优先级程序*/
#define configKERNEL_INTERRUPT_PRIORITY (15 << 4)
/* 设置了 调用中断安全的 FreeRTOS API 函数的最高中断优先级。 FreeRTOS 的管理的最高优先级 */        
#define configMAX_SYSCALL_INTERRUPT_PRIORITY  (5 << 4)
/* 同上. 仅用于新版移植。 这两者是等效的。 */  
#define configMAX_API_CALL_INTERRUPT_PRIORITY   configMAX_SYSCALL_INTERRUPT_PRIORITY//#freertos_demo.c//1.任务配置
/* 启动任务函数 */
#define START_TASK_PRIORITY 1
#define START_TASK_STACK_DEPTH 128
TaskHandle_t start_task_handler;
void Start_Task(void *pvParameters);/* Task1 任务 配置 */
#define TASK1_PRIORITY 2
#define TASK1_STACK_DEPTH 128
TaskHandle_t task1_handler;
void Task1(void *pvParameters);//2.入口函数
/**
 * @description: FreeRTOS入口函数:创建任务函数并开始调度
 * @return {*}
 */
void FreeRTOS_Start(void)
{
    xTaskCreate((TaskFunction_t)Start_Task,
                (char *)"Start_Task",
                (configSTACK_DEPTH_TYPE)START_TASK_STACK_DEPTH,
                (void *)NULL,
                (UBaseType_t)START_TASK_PRIORITY,
                (TaskHandle_t *)&start_task_handler);
    vTaskStartScheduler();
}
//3.初始任务函数
void Start_Task(void *pvParameters)
{
    taskENTER_CRITICAL(); /* 进入临界区 */
    xTaskCreate((TaskFunction_t)Task1,
                (char *)"Task1",
                (configSTACK_DEPTH_TYPE)TASK1_STACK_DEPTH,
                (void *)NULL,
                (UBaseType_t)TASK1_PRIORITY,
                (TaskHandle_t *)&task1_handler);    vTaskDelete(NULL);  
    taskEXIT_CRITICAL(); /* 退出临界区 */
}
//4.4)task1任务函数
/**
 * @description: 开关中断
 * @param {void *} pvParameters
 * @return {*}
 */
void Task1(void *pvParameters)
{
    uint8_t key = 0;
    while (1)
    {
        key = Key_Detect();
        if (key == KEY1_PRESS)
        {
            /* 关中断 */
            printf(">>>>关中断.....\r\n");
            portDISABLE_INTERRUPTS();
        }
        else if (key == KEY2_PRESS)
        {
            /* 开中断 */
            printf(">>>>开中断.....\r\n");
            portENABLE_INTERRUPTS();
        }        /* 为了观察实验现象,不要调用freertos的延时函数,底层会去开关中断,影响现象 */
        // vTaskDelay(500);
        /* 使用HAL_Delay前提:HAL时钟修改成其他定时器,并且中断优先级高于freertos的管理范围 */
        HAL_Delay(500);
    }
}

 

七、 FreeRTOS时间片调度

7.1 时间片调度

在FreeRTOS中,同等优先级的任务会轮流分享相同的CPU时间,这个时间被称为时间片。在这里,一个时间片的长度等同于SysTick中断的周期。

7.2 时间片调度实验演示(掌握)

  • start_task:用来创建其他的2个任务。
  • task1:通过串口打印task1的运行次数,设置任务优先级为2。
  • task2:通过串口打印task2的运行次数,设置任务优先级为2。

为了更好观察现象,滴答定时器的中断频率设置为50ms中断一次(一个时间片)。

(1000/20)ms

FreeRTOSConfig.h代码

#define configUSE_TIME_SLICING                          1

#define configUSE_PREEMPTION                            1

#define configTICK_RATE_HZ          ( ( TickType_t ) 20 )  

freertos_demo.c代码清单

//1.任务配置
/* 启动任务函数 */
#define START_TASK_PRIORITY 1
#define START_TASK_STACK_DEPTH 128
TaskHandle_t start_task_handler;
void Start_Task(void *pvParameters);/* Task1 任务 配置 */
#define TASK1_PRIORITY 2
#define TASK1_STACK_DEPTH 128
TaskHandle_t task1_handler;
void Task1(void *pvParameters);/* Task2 任务 配置 */
#define TASK2_PRIORITY 2
#define TASK2_STACK_DEPTH 128
TaskHandle_t task2_handler;
void Task2(void *pvParameters);​​​​​​​//2.入口函数
/**
 * @description: FreeRTOS入口函数:创建任务函数并开始调度
 * @return {*}
 */
void FreeRTOS_Start(void)
{
    xTaskCreate((TaskFunction_t)Start_Task,
                (char *)"Start_Task",
                (configSTACK_DEPTH_TYPE)START_TASK_STACK_DEPTH,
                (void *)NULL,
                (UBaseType_t)START_TASK_PRIORITY,
               (TaskHandle_t *)&start_task_handler);
    vTaskStartScheduler();
}​​​​​​​//3.初始任务函数
void Start_Task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
    xTaskCreate((TaskFunction_t         )   Task1,
                (char *                 )   "Task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_DEPTH,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIORITY,
                (TaskHandle_t *         )   &task1_handler );
    xTaskCreate((TaskFunction_t         )   Task2,
                (char *                 )   "Task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_DEPTH,                (void *                 )   NULL,                (UBaseType_t            )   TASK2_PRIORITY,                (TaskHandle_t *         )   &task2_handler );
    vTaskDelete(NULL);                  
    taskEXIT_CRITICAL();                /* 退出临界区 */
}//4.task1任务函数
/**
 * @description: 打印任务1执行次数
 * @param {void *} pvParameters
 * @return {*}
 */
void Task1(void * pvParameters)
{
    uint16_t task1_count=0;
    while(1)
    {
        /* 临界区避免printf执行一半被打断 */
        taskENTER_CRITICAL();
        printf("task1运行次数=%d..\r\n",++task1_count);
         // vTaskDelay(500); //为了观察时间片调度,不使用freertos的延时函数
        HAL_Delay(10); // 使用该延时的前提:HAL时钟修改成其他定时器,并且中断优先级较高
        taskEXIT_CRITICAL();
    }}
//task2任务函数
/** * @description: 打印任务2执行次数 * @param {void *} pvParameters * @return {*} */void Task2(void * pvParameters){    uint16_t task2_count=0;    while(1)    {        /* 临界区避免printf执行一半被打断 */        taskENTER_CRITICAL();        printf("task2运行次数=%d..\r\n",++task2_count);         // vTaskDelay(500); //为了观察时间片调度,不使用freertos的延时函数        HAL_Delay(10); // 使用该延时的前提:HAL时钟修改成其他定时器,并且中断优先级较高        taskEXIT_CRITICAL();    }}

 

八、FreeRTOS任务相关API函数

8.1 FreeRTOS任务相关API函数介绍

任务相关的API主要如下:

函数

描述

uxTaskPriorityGet()

获取任务优先级

vTaskPrioritySet()

设置任务优先级

uxTaskGetNumberOfTasks()

获取系统中任务的数量

uxTaskGetSystemState()

获取所有任务状态信息

vTaskGetInfo()

获取指定单个的任务信息

xTaskGetCurrentTaskHandle()

获取当前任务的任务句柄

xTaskGetHandle()

根据任务名获取该任务的任务句柄

uxTaskGetStackHighWaterMark()

获取任务的任务栈历史剩余最小值

eTaskGetState()

获取任务状态

vTaskList()

以“表格”形式获取所有任务的信息

vTaskGetRunTimeStats()

获取任务的运行时间

官网:​​​​​​​​​​​​​​任务实用程序 - FreeRTOS™

8.2 任务状态查询API函数实验

使用 FreeRTOS 任务状态查询相关 API 函数:

  • start_task:用来创建其他的2个任务。
  • task1:LED1每500ms闪烁一次,提示程序正在运行。
  • task2:用于展示任务状态查询相关API函数的使用。

  • FreeRTOSConfig.h代码清单

#define INCLUDE_xTaskGetSchedulerState

http://www.dtcms.com/a/399641.html

相关文章:

  • python++springboot+nodejs微信小程序高校实验室管理系统 实验室预约登记 设备借用管理 实验记录审核系统
  • 外贸精品网站建设网站运营介绍
  • 构建神经网络的两大核心工具
  • 品牌高端网站制作金蝶软件多少钱
  • 基于STM32舞台彩灯控制器设计app控制系统
  • 2D激光定位与建图
  • shell编程:grep - 文本搜索利器(1)
  • 网站建设制作公司地址做照片书网站
  • 鸿蒙Next远端状态订阅开发实例:实现进程状态监控与资源管理
  • 济宁做网站的WordPress重新安装删除哪个
  • Deep Residual Learning for Image Recognition 阅读笔记
  • 【AI】【Java后端】深度解析 RAG 高级功能:从原理到落地实践
  • 微信移动网站建设做电影网站用什么空间
  • 银行测试存款业务(四)
  • C#练习题——匿名方法与闭包实战:函数式编程的优雅实现
  • 西安有哪些网站设计公司seo排名优化推广报价
  • 深圳安鸿源建设网站上海网站建站建设服务
  • H3C 三层VLAN路由实验
  • 深圳做购物网站小米发布会8月
  • 【GPT入门】第71课 autogen介绍与代码实现股票分析汇报多智能体
  • 网页源码 html源码网站 网页源代码模板
  • 北京网站优化前景集团网站策划方案
  • 怎么打帮人做网站开发的广告常熟市住房建设局网站
  • 深度学习(6)pytorch
  • 函数(Num008)
  • MySQL8.0版本在Windows下进行安装
  • 站长seo工具图文素材库免费
  • 前端核心框架vue之(指令篇1/5)
  • 山东小语种网站建设免费高清视频素材app哪里找
  • 嵌入式Python环境深度解读与精益裁剪指南