28-FreeRTOS内核控制-延时-临界区

一、FreeRTOS的内核控制接口分析

1.1 函数taskYIELD

        此函数用于进行任务切换,此函数本质上是一个宏。它允许当前任务主动放弃CPU使用权,将控制权转移给调度器,以便调度器可以选择另一个就绪任务运行。taskYIELD通常用于协作式多任务系统中,任务在没有更多工作可做或需要等待某些事件时调用此函数。通过调用taskYIELD,任务可以显式地让出CPU资源,从而提高系统的响应性和效率。此外,taskYIELD的实现通常依赖于特定的硬件平台和操作系统,以确保任务切换的原子性和正确性。

1.2 函数taskENTER_CRITICAL

        进入临界区(即共享资源区),用于任务函数中,此函数本质上是一个宏,它通过禁用中断来确保任务在临界区内执行时不会被其他任务或中断打断,从而保护共享资源的完整性和一致性。在进入临界区后,任务可以安全地访问和修改共享数据,而不会受到并发访问的干扰。完成临界区操作后,应调用taskEXIT_CRITICAL函数来恢复中断并退出临界区,以允许其他任务和中断继续执行。这种机制在多任务系统中尤为重要,尤其是在实时操作系统中,用于确保任务之间的同步和资源的正确管理。

1.3 函数taskEXIT_CRITICAL

        退出临界区,用于任务函数中,此函数本质上是一个宏,用于在任务执行过程中安全地退出临界区,确保在退出临界区时不会发生任务切换或中断,从而保护共享资源的完整性。该宏通常会taskENTER_CRITICAL配对使用,以确保在进入和退出临界区时的一致性。taskEXIT_CRITICAL的实现通常依赖于特定的操作系统或实时内核的底层机制,以提供高效的临界区管理。

1.4函数taskENTER_CRITICAL_FROM_ISR

进入临界区,用于中断服务函数中,此函数本质上是一个宏。

1.5函数taskEXIT_CRITICAL_FROM_ISR

退出临界区,用于中断服务函数中,此函数本质上是一个宏。

1.6函数taskDISABLE_INTERRUPTS

关闭可屏蔽的中断,此函数本质上是一个宏。

1.7函数taskENABLE_INTERRUPTS

打开可屏蔽的中断,此函数本质上是一个宏。

1.8函数vTaskStartScheduler

启动任务调度器,且会创建空闲任务。

1.9函数vTaskEndScheduler

关闭任务调度器。

1.10函数vTaskSuspendAll

挂起任务调度器,调用此函数不需要关闭可屏蔽中断即可挂起任务调度器。

1.11 函数xTaskResumeAll

此函数用于将任务调度器从挂起状态恢复。

临界区指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个线程访问的特性。当有线程进入临界区段时,其他线程或是进程必须等待(例如:bounded waiting 等待法),有一些同步的机制必须在临界区段的进入点与离开点实现,以确保这些共用资源是被互斥获得使用

二、睡眠延时函数

1.1 vTaskDelay(常用)

        在UCOSIII 中延时函数OSTimeDly()可以设置为三种模式:相对模式、周期模式和绝对模式。在FreeRTOS中延时函数只有相对模式和绝对模式,在FreeRTOS中不同的模式用的函数不同,其中函数 vTaskDelay()是相对模式(相对延时函数),函数 vTaskDelayUntil()是绝对模式(绝对延时函数)。函数vTaskDelay()在文件 tasks.c中有定义,要使用此函数的话宏INCLUDE_vTaskDelay必须为1,函数代码如下:

//xTicksToDelay:要延时的时间节拍数,该数值须大于0。void vTaskDelay( const TickType_t xTicksToDelay )

注意延时的时间为:节拍数*系统节拍时间

系统默认时间节拍:1ms(正常情况1ms请求一次任务切换)

系统已经使用配置Systick 1ms中断一次,用于系统节拍时间,任务是基于系统节拍时间进行任务调度。

SysTick->LOAD,下图是如何配置自己的时间节拍

系统节拍修改宏为configTICK_RATE_HZ, 系统节拍时间为:1/configTICK_RATE_HZ。系统节拍时间最好在1~10ms之间。过短,就是出现不是在切换任务就在切换任务的路上,过长,系统的实时性差。

1.2 vTaskDelayUntil(绝对延时)-了解

        函数 vTaskDelayUntil()会阻塞任务,阻塞时间是一个绝对时间,那些需要按照一定的频率运行的任务可以使用函数vTaskDelayUntil(),即使任务中执行的代码逐渐添加,也能让任务按照固定的频率运行(要求:任务总的执行时间要小于延时时间)。


void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,const TickType_t xTimeIncrement )

代码示例:

static void app_task1(void* pvParameters)
{for(;;){printf("app_task1 is running ...,tick count = %u\r\n",xTaskGetTickCount());/* 相对延时:任务延时2000个节拍,每个节拍为1ms,所以延时2000ms */vTaskDelay(2000);}
}   static void app_task2(void* pvParameters)
{uint32_t i=0,j=1;TickType_t xLastWakeTime;/* 初始化上次唤醒时间为当前时间 */xLastWakeTime = xTaskGetTickCount();//一次循环时间为2Sfor(;;){for(i=0; i<j*10000; i++);j+=10;printf("app_task2 is running ...,tick count = %u\r\n",xTaskGetTickCount());/* 绝对延时:任务延时2000个节拍,每个节拍为1ms,所以延时2000ms */		vTaskDelayUntil(&xLastWakeTime, 2000);}
} 

实验效果:可知,每次延时2s(误差可以省略)

app_task2 is running ...,tick count = 0app_task1 is running ...,tick count = 47app_task2 is running ...,tick count = 2002app_task1 is running ...,tick count = 2096app_task2 is running ...,tick count = 4005app_task1 is running ...,tick count = 4150

总结:

任务2使用绝对延时能够给按照逼近2000个节拍频率固定运行(当前计数值:0-2002-4005-6007-8009-10012),任务1使用相对延时每次运行相隔时间不保证固定(当前计数值:47-2096-4150-6206-8264-10326)。

1.3 相对延时与绝对延时对比

相对延时:只会延时其任务的相对时间

绝对延时:会把其他突发事件的时间也计算进来

三、自定义延时函数

2.1 微秒延时

void delay_us(uint32_t nus)
{		uint32_t ticks;uint32_t told,tnow,tcnt=0;uint32_t reload=SysTick->LOAD;	//系统定时器的重载值	    	 ticks=nus*(SystemCoreClock/1000000);//需要的节拍数 told=SysTick->VAL;        	//刚进入时的计数器值/* 挂起调度器[可选,会导致高优先级任务无法抢占当前任务,但能够提高当前任务时间的精确性] */vTaskSuspendAll();	while(1){tnow=SysTick->VAL;if(tnow!=told){	 /* SYSTICK是一个递减的计数器 */if(tnow<told)tcnt+=told-tnow;		else tcnt+=reload-tnow+told+1;	  told=tnow;/* 时间超过/等于要延迟的时间,则退出。*/if(tcnt>=ticks)break;			}  }/* 恢复调度器[可选] */xTaskResumeAll();
}  

使用us级延时,不要超1000us,过长时间的微秒延时会导致系统实时性。

2.2 毫秒延时

void delay_ms(uint32_t nms)
{vTaskDelay(nms);
}

延时整个项目的代码示例:

https://download.csdn.net/download/m0_63622771/90887340

四、FreeRTOS共享资源的基本概述

1.1 基本概念

        共享资源典型的共享资源有:全局变量、I/O设备中的寄存器、多个任务访问的函数、缓冲区等。共享资源的可靠访问,任务必须对数据具有独享权变得极其重要,否则将可能导致任务间的竞争与数据损坏,进而引发系统崩溃、数据不一致、死锁、资源泄露等问题。

        为确保共享资源的安全访问,通常需要采用互斥锁、信号量、条件变量、原子操作等同步机制,以及设计合理的资源管理策略,如优先级继承、资源分配协议等,以避免任务间的冲突并保证系统的稳定性和可靠性。

1.2 种类说明

最常用的独占共享资源的方法有以下几种:
  • 关中断(就可以不会发送中断了。所以独占资源)
  • 禁止任务调度(给调度器上锁,调度器停摆)
  • 使用信号量(计数型的型号量、二值信号量)
  • 使用互斥型信号量(互斥锁)

       获得独占共享资源的方法,取决于代码访问共享资源的速度,即占用共享资源的时间(重点),具体使用说明如下表:

选择题

1.以下请问使用( A )方式保护最为合适。

void T1(void *parg)
{while(1){ ...........喂狗    ...........        }
}A. 关中断、开中断    B.给调度器上锁、解锁    C.信号量    D.互斥锁

2.以下请问使用( D )方式保护最为合适。

uint32 g=0;
void T1(void *parg)
{while(1){ ...........g++;	...........		}
}void T2(void *parg)
{uint32_t a=0;while(1){ ...........a = g;	...........		}
}A. 关中断、开中断    B.给调度器上锁、解锁    C.信号量     D.互斥锁

3.以下请问使用( A )方式保护最为合适。

uint32 g=0;void T1(void *parg)
{while(1){ ...........g++;	...........		}
}void T2(void *parg)
{uint32_t a=0;while(1){ ...........a = g;	...........		}
}void USART1_IRQHandler(void)
{...........g = USART_ReceiveData(USART1);	...........  }A. 关中断、开中断    B.给调度器上锁、解锁    C.信号量    D.互斥锁

4.以下请问使用( D )方式保护最为合适。

void T1(void *parg)
{while(1){ ...........printf("hello teacher.chen\r\n");	...........		}
}void T2(void *parg)
{while(1){ ...........printf("good bye teacher.chen\r\n");	...........		}
}A. 关中断、开中断    B.给调度器上锁、解锁    C.信号量    D.互斥锁

5.以下请问使用( D )方式保护最为合适。

void T1(void *parg)
{while(1){ ...........printf("hello teacher.chen\r\n");	...........		}
}void T2(void *parg)
{while(1){ ...........printf("good bye teacher.chen\r\n");	...........		}
}void T3(void *parg)
{while(1){ ...........printf("he's teacher.chen\r\n");	...........		}
}A. 关中断、开中断    B.给调度器上锁、解锁    C.信号量    D.互斥锁

辨析题

1.请分析以下代码。

//高优先级
void T1(void *parg)
{while(1){ 调度器上锁printf("hello teacher.chen\r\n");delay_ms(1000)	调度器解锁		}
}
//低优先级
void T2(void *parg)
{while(1){ 调度器上锁printf("good bye teacher.chen\r\n");delay_ms(1000)	调度器解锁			}
}调度器上锁,T1任务打印hello teacher.chen,执行delay_ms后导致停止了任务调度器,
导致两个任务都无法执行。

2.请分析以下代码。

void T1(void *parg)
{while(1){ 等待互斥锁printf("hello teacher.chen\r\n");delay_ms(1000);释放互斥锁	}
}void T2(void *parg)
{while(1){ 等待互斥锁printf("good bye teacher.chen\r\n");delay_ms(1000);释放互斥锁			}
}只有得到锁的任务才能执行

3.请分析以下代码。

void app_task_init(void *parg)
{创建信号量,初值为0
}void T1(void *parg)
{while(1){ 等待信号量printf("hello teacher.chen\r\n");释放信号量		}
}void T2(void *parg)
{while(1){ 等待信号量printf("good bye teacher.chen\r\n");释放信号量			}
}只有得到信号量的任务才能执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/80951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NtfsLookupAttributeByName函数分析之和Scb->AttributeName的关系

第一部分&#xff1a; VOID FindFirstIndexEntry ( IN PIRP_CONTEXT IrpContext, IN PSCB Scb, IN PVOID Value, IN OUT PINDEX_CONTEXT IndexContext ) { 。。。。。。 // // Lookup the attribute record from the Scb. // if (!NtfsLookupAt…

关闭 Ubuntu 20.04 的 GNOME Shell和PulseAudio

一、GNOME Shell GNOME Shell 是 Ubuntu 20.04 默认的桌面环境管理器。关闭它会失去图形界面&#xff08;回到纯终端模式&#xff09;&#xff0c;但可以节省内存和 CPU 资源。 方法 1&#xff1a;临时关闭&#xff08;当前会话生效&#xff09; sudo systemctl stop gdm #…

Dijkstra算法——不带负权的单源最短路径

目录 算法学习 算法原理 稠密图Dijkstra模板 稀疏图Dijkstra模板 练习 1 网络延迟时间 2 到达最后一个房间的最少时间Ⅰ 3 到达最后一个房间的最少时间Ⅱ 4 访问消失节点的最少时间 5 设计可以求最短路径的图类 6 概率最大的路径 7 最小体力消耗路径 8 从第一个节…

【安全攻防与漏洞​】​​Heartbleed漏洞复现与修复

Heartbleed漏洞复现与修复 一、漏洞原理 Heartbleed漏洞&#xff08;CVE-2014-0160&#xff09; 是 OpenSSL 1.0.1 至 1.0.1f 版本中的一个严重内存泄漏漏洞。它源于 TLS 心跳扩展&#xff08;Heartbeat Extension&#xff09;协议中对请求长度字段的未校验&#xff0c;导致攻…

力扣-最大连续一的个数

1.题目描述 2.题目链接 1004. 最大连续1的个数 III - 力扣&#xff08;LeetCode&#xff09; 3.代码解答 class Solution {public int longestOnes(int[] nums, int k) {int zero0,length0;for(int left0,right0;right<nums.length;right){if(nums[right]0){zero;}while…

虚拟机Centos7:Cannot find a valid baseurl for repo: base/7/x86_64问题解决

问题 解决&#xff1a;更新yum仓库源 # 备份现有yum配置文件 sudo cp -r /etc/yum.repos.d /etc/yum.repos.d.backup# 编辑CentOS-Base.repo文件 vi /etc/yum.repos.d/CentOS-Base.repo[base] nameCentOS-$releasever - Base baseurlhttp://mirrors.aliyun.com/centos/$relea…

Node.js 库大全

在当今快速迭代的软件开发领域&#xff0c;Node.js 凭借其强大的异步 I/O 处理能力和繁荣的生态系统&#xff0c;已成为全栈开发的核心技术。社区中涌现的无数实用库&#xff0c;如同开发者手中的“瑞士军刀”&#xff0c;能显著提升效率、优化性能并保障安全。本文将系统梳理 …

如何评估物联网框架的交互体验?

物联网&#xff08;IoT&#xff09;技术的快速发展推动了各类物联网框架的涌现&#xff0c;但如何评估其交互体验却成为开发者和企业面临的重要挑战。交互体验不仅涉及用户界面&#xff08;UI&#xff09;的直观性&#xff0c;还包括设备接入效率、协议兼容性、数据交互流畅度以…

3D个人简历网站 6.弹出框

3D个人简历网站 6.弹出框 在components下创建HomeInfo.jsx用于控制主页弹出框信息 输入rafce快速生成代码块 import React from reactconst HomeInfo () > {return (<div>HomeInfo</div>) }export default HomeInfo修改Home.jsx代码实现弹出简单效果 ……re…

在 ABP VNext 中集成 OpenCvSharp:构建高可用图像灰度、压缩与格式转换服务

&#x1f680; 在 ABP VNext 中集成 OpenCvSharp&#xff1a;构建高可用图像灰度、压缩与格式转换服务 &#x1f389; &#x1f4da; 目录 &#x1f680; 在 ABP VNext 中集成 OpenCvSharp&#xff1a;构建高可用图像灰度、压缩与格式转换服务 &#x1f389;&#x1f3af; 一、…

C++之STL--string

string 深入探索 C STL 中的 std::string一、std::string 的基本概念1. 内存管理2. 安全性 二、std::string 的构造与初始化1. 默认构造2. 从 C 风格字符串构造3. 从字符串的一部分构造4. 使用重复字符构造 三、std::string 的常用操作1. 字符串拼接2. 字符串比较3. 字符串查找…

网络层——蚂蚁和信鸽的关系VS路由原理和相关配置

前言&#xff08;&#x1f41c;✉️&#x1f54a;️&#xff09; 今天内容的主角是蚂蚁&#xff08;动态路由&#xff09;和信鸽&#xff08;静态路由&#xff09;&#xff0c;为什么这么说呢&#xff0c;来看一则小故事吧。 森林里&#xff0c;森林邮局要送一份重要信件&am…

在 Excel xll 自动注册操作 中使用东方仙盟软件2————仙盟创梦IDE

// 获取当前工作表名称string sheetName (string)XlCall.Excel(XlCall.xlfGetDocument, 7);// 构造动态名称&#xff08;例如&#xff1a;Sheet1!MyNamedCell&#xff09;string fullName $"{sheetName}!MyNamedCell";// 获取引用并设置值var namedRange (ExcelRe…

nginx日志

目录 实验要求&#xff1a; 实验1&#xff1a; 1.使用vim打开/etc/nginx/nginx.conf查看内容 2.重新读取文件并且重启软件 3.实时查看nginx日志 实验2&#xff1a; 1.使用vim打开/etc/rsyslog.conf 2.配置此文件 3.保存退出后&#xff0c;将核心防护与防火墙关闭。 4.…

【高德开放平台-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

2024 CKA模拟系统制作 | Step-By-Step | 3、CKA考试系统的技术设置

目录 免费获取题库配套 CKA_v1.31_模拟系统 一、免费提权配置 1、使用vim 编辑/etc/sudoers 二、安装命令 1、安装运行时接口命令 2、安装Etcd命令 3、配置K8S命令自动补全 三、配置Kubectl 访问集群 1、Master节点 2、Node01节点 四、SSH配置 1、Node01节点candi…

微信小程序请求扣子(coze)api的例子

1. 准备工作 在开始之前&#xff0c;确保已经完成了以下准备工作&#xff1a; 创建并发布了 Coze 智能体。获取了个人访问令牌&#xff08;Personal Access Token&#xff09;&#xff0c;这是用于授权的关键凭证。确认目标智能体的 Bot ID 和其他必要参数已准备就绪。 2. 请…

visual studio重新安装如何修改共享组件、工具和SDK路径方案

安装了VsStudio后,如果自己修改了Shared路径&#xff0c;当卸载旧版本&#xff0c;需要安装新版本时发现&#xff0c;之前的Shared路径无法进行修改&#xff0c;这就很坑了 但是却遇到了路径无法修改的问题…真让人头大&#xff0c;当然不修改也可以&#xff0c;有时候&#x…

【Python 算法零基础 4.排序 ② 冒泡排序】

目录 一、引言 二、算法思想 三、时间复杂度和空间复杂度 1.时间复杂度 2.空间复杂度 四、冒泡排序的优缺点 1.算法的优点 2.算法的缺点 五、实战练习 88. 合并两个有序数组 算法与思路 ① 合并数组 ② 冒泡排序 2148. 元素计数 算法与思路 ① 排序 ② 初始化计数器 ③ 遍历数组…

Java设计模式之桥接模式:从入门到精通

文章目录 1. 桥接模式概述1.1 定义与核心思想1.2 模式结构1.3 通俗理解2. 桥接模式详解2.1 为什么需要桥接模式2.2 桥接模式与相关模式对比2.3 桥接模式的优缺点3. 桥接模式实现步骤3.1 实现步骤详解3.2 代码示例:遥控器与电视4. 桥接模式的高级应用4.1 多维度扩展4.2 与工厂模…