IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> FreeRTOS【学习笔记1】——操作系统与裸机的差别和任务的引用。 -> 正文阅读

[嵌入式]FreeRTOS【学习笔记1】——操作系统与裸机的差别和任务的引用。

1.操作系统与裸机的关系

1.1一心一用

一心一用的就是裸机。一般情况下,裸机代码的执行都是通过在main函数中的大while循环中执行子函数的方式来实现的。如下代码所示:

int main()
{
	init();  //初始化一些外设或者变量等
	while(1)
	{
		a();  //函数a
		b();  //函数b
		c();  //函数c
	}
}

在main函数中的这些代码,我们可以称为后台系统,裸机除了main函数中的这些代码,还有中断服务函数,我们称为前台系统,如下代码就是一个串口中断服务函数。

void USART1_2_HANDLER()
{
	//当串口接收到数据之后,就会到串口中断服务函数中执行相关代码。
}

Alt
如上图所示,该图是前后台系统(裸机)任务执行流程图。
该图来源于其他CSDN博客。该CSDN博客链接

如果现在你需要通过代码实现以下任务:
task1:在电脑上回复客户信息
task2:做晚饭
task3:给孩儿子喂隔夜饭
task4:回复女朋友信息

我们这边假设回复客户信息是一件非常重要的事情,所以我们要放在中断中。

int main()
{
	init();//完成一些初始化
	while(1)
	{
		做晚饭();
		给孩子喂隔夜饭();
		回复女朋友信息();
	}
}

void 做晚饭()
{
	if(判断饭菜是不是熟了)
	{	
		熟了饭菜捞出来();
	}
	else
	{
		//没熟跳过
	}
}

void 给孩子喂隔夜饭()
{
	if(孩子饿了)
	{
		用勺子铲一勺饭();
		放进孩子嘴里();
	}

}

void 回复女朋友信息()
{
	if(判断女朋友有没有发来信息)
	{
		回复女朋友的信息();
	}
	else
	{
		发送信息问女朋友在干吗();
	}
}

//以上code是后台系统,以下代码是前台系统。
void 客户发来信息就会进入这个中断服务函数_HANDLER()
{
	回复客户信息();
}

我们可以可以看到以上的4个任务,组成了一个前后台系统。回复客户信息作为重要任务,于是就放到中断中,其他三个不是很重要的任务采用轮询的方式执行。

我在执行做菜任务的时候,我是不知道孩子有没有饿,需不需要喂饭;不知道女朋友有没有发消息过来,需要回复。只有我做好了做菜这个任务之后,去执行给孩子喂饭这个任务的时候,才可以去判断孩子有没有饿了。但不管执行什么任务的时候,只要客户发来了消息,触发该任务的中断服务函数,那么会优先执行该中断服务函数的内容。这就是前后台系统(裸机)的任务执行流程。

1.2一心多用

一心多用指的是操作系统(OS),这里以FreeRTOS为例。可以理解为我既可以做饭,也可以给孩子喂饭,也可以回复女朋友信息。学习操作系统是一件很枯燥、烦琐的事情,我会尽量通俗的解释操作系统的原理。在理解操作系统任务调度之前,先去了解一个时间片的概念。我们执行一个任务是需要一个时间的,比如做晚饭函数。

void 做晚饭()
{
	if(判断饭菜是不是熟了)
	{	
		熟了饭菜捞出来();
	}
	else
	{
		//没熟跳过
	}
}

做饭晚执行完这个函数需要a0~a10的时间。
给孩子喂饭执行完这个函数需要b0~b20的时间。
回复女朋友信息执行完这个函数需要c0~c15的时间。

1.3FreeRTOS任务调度的方式

今天介绍两种FreeRTOS任务调度的方式。

Alt
如上图所示,就是FreeRTOS任务执行流程图。
第一种不同优先级任务的任务调度。
在FreeRTOS中任务优先级越高的优先执行,当优先级高的任务执行完成之后,一般会把该任务挂起一段时间,把CPU资源让给其他任务。大概代码如下:

//我们这边假设做晚饭的任务的优先级是最高的。
void 做饭晚()
{
	if(判断饭菜是不是熟了)
	{	
		熟了饭菜捞出来();
	}
	else
	{
		//没熟跳过
	}
	//当做晚饭任务执行完成之后,一般会调用VTaskDelay(1000)函数将该任务挂起一段时间。
	VTaskDelay(1000);
}

现在,尊敬的读者可能不知道将任务挂起是什么意思,你现在可以理解为:你在windows中打开了一个QQ,那么就是执行QQ这个函数。
当你挂起了,就是用任务调度器把这个QQ给结束进程了;
当任务恢复的时候,你可以理解为,又把QQ打开了。

高优先级的做晚饭任务做好并且将该任务 挂起之后,FreeRTOS会自己查找在任务列表中优先级最高的任务,并去执行他。

第二种任务优先级相同的情况下。
如果现在做晚饭、给孩子喂饭、回复女朋友信息这个三个任务优先级相同,那么FreeRTOS会怎么执行呢?我们之前已经知道了这三个函数执行完需要那些时间了。在FreeRTOS中有一个“心脏”,他就是滴答定时器,滴答定时器每滴答到一个时间单位,就会触发一次滴答定时器中断,在这个滴答定时器中断中,主要就是执行任务的切换。

做饭晚执行完这个函数需要a0~a10的时间。
给孩子喂饭执行完这个函数需要b0~b20的时间。
回复女朋友信息执行完这个函数需要c0~c15的时间。

流程如下:
做晚饭();执行了a0~a1;
滴答定时器触发中断,任务切换。
给孩子喂饭();执行了b0~b1;
滴答定时器触发中断,任务切换。
回复女朋友信息();执行了c0~c1;
滴答定时器触发中断,任务切换。
做饭晚();执行了a2~a4;
滴答定时器触发中断,任务切换。
给孩子喂饭();执行了b2~b4。
滴答定时器触发中断,任务切换。

3.结尾

那么此时肯定会有读者想了,在任务切换中,芯片是怎么知道这个函数执行到了哪里呢?
这个就涉及到了函数暂停/回复的概念了,我会在下一篇文章中写出。蟹蟹大家~

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 12:04:46  更:2022-01-28 12:07:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:30:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码