粉丝8303获赞2.4万

逼自己一个月学完,你的 free r t o s。 水平就很牛了,存下吧,真的很难找全的!本系列课程耗时三个月,制作共计四百三十分钟,全场七小时, 带你一口气从零基础入门进阶,掌握 free r t o s。 操作系统所有重难点知识。课程内容全是行业刚需,包括任务创建与调度、信号量与呼气所消息队列、通信、实时中断处理等高频实用知识点,不讲废话,只讲重点。 由于视频较长,分为六期发布,为了让零基础的小伙伴学习起来没有负担,教程中配套资料以及我整理的全套学习资料, 对零基础超有帮助的学习路径以官家评论,我需要即可全部带走。如果你看到了这,还请支持一下主播,让更多想要学习 free r t o s。 的 小伙伴看到这个视频。 接下来我们开始这套系统课的学习吧!进入式中的 r t o s。 为何如此重要呢?作为一种轻量级操作系统, r t o s。 专注于实时任务处理, 广泛应用于工业控制、智能家居和自动驾驶等领域。与普通系统不同, r t o s。 以任务优先级为核心,确保关键任务优先执行,响应速度可达微秒级。 其具有多个核心技术特性,例如任务调度、中断处理、内存管理以及多任务并发任务调度。而 t o s。 根据优先级动态分配资源,确保高优先级任务优先执行,中断处理。而 t o s。 能快速响应中断,确保系统实时性,例如工业设备的紧急制动。 内存管理。 r t o s。 在 资源受限的环境中高效管理内存,确保任务隔离和资源利用率。多任务并发, r t o s。 在 同一时间异形多个任务,例如自动驾驶系统中同时处理传感器数据和路径规划。 r t o s。 如何开发使用呢? 开发工具,使用 k o c i a r embedded workbench 等工具轻松进行 r t o s。 应用程序开发。开发流程,从硬件设计到软件编程、项目驱动教学,让你快速掌握 r t o s。 开发流程优化技巧,通过任务优先级调度和减少任务切换开销, 提升系统性能。随着智能化产业的涌现与升级, r t o s。 在 未来的发展中前景非常可观。在互联网、人工智能和自动驾驶中将更加智能化和轻量化,在智能家居、智能穿戴等领域将为其提供强大的实时支持。在医疗设备等高安全性领域, r t o s。 将确保系统的可信和安全性。 r t o s。 还将与人工智能深度融合,支持边缘计算,让设备更智能、更高效。在最后,小编为您准备了渐入式学习资料包,欢迎滴滴小编哦,今天就到这里了,我们下期见, 大家好呃,欢迎回来呃,我讲解的 rto 系他的课程呃,今天我开始讲第一讲,了解单片机运行的底层逻辑 啊,单片机的话相信大家读过哎,关于关于我们的电子技术啊,这些课程的话都会有所了解,但单片机它究竟是怎样的运行的?它的底层逻辑是怎样的 啊?今天我来讲解一下。假如我这里,我这个右右边这个图,左边这个框框这里, 它是一个我们采用的一个呃断片机,它是一个 c 八 t 六 st 公司的三十二位 g f 幺零三 c 八 t 六这个型号的断片机,它的内核是 cotas n 三内核, 这个图是一个比较简单的粗略的一个图, 比如我们这个单片机它会包含什么东西呢?包含一个 cpu 是 吧?一个 cpu cpu 是 什么?它是一个呃处理指令的一个地方, 就是处理指令的一个地方,是吧?这个一条指令过来,是吧?它就处理这个指令, 它有什么?它里面就有这个东西,这个东西它是一些 通用计算器跟一些特殊功能,计算器里面就是有一些存放数据的东西, 你可以把它理解成用来存放数据临时处理的一些地方,或者是描描写我们程程序或者硬件它状态的一些东西就好了。 第一点就是 cpu 是 要有的,第二点就是 flash, flash 是 什么?它是一个储存单元,这个储存单元里面存储的是什么呢?可以是我们的程序代码, 我们程序把,呃,就是我们用软件编辑好程序之后,把程序稍写到我们的单片机里面,而这个稍写到单片机里面,那它放在就是 fashion 里面, 它是相当于电脑里边的一个硬盘,里面存放的就是我们的代码, 就是存放我们代码,是吧?加上那我能程序运行的话,就把这些代码一条一条的放过来我们的 cpu 里面,是吧? cpu 执行这个代码,执行我们代码之后 怎么了?他会通常会有一些读写的一些东西,他的一些数据他会放到我们的内存里面,这个是内存 ram 内存, 这个就是我们的呃读写数据的一个内存,这个内存是比较重要的,我们玩单片机就是玩的就是这个数据链,这个数据块里面的东西, 你要计算机吗?单面机也叫计算机吗?计算机就是把东西计算得出一些结果,那结果就是放在我们这个内存里面,明白没用。 而这个 m v i c 是 什么呢? m v i c 是 我们的一个中断控制器,中断嵌套控制器,它是一个呃中,可以把它理解成一个中断控制器, 因为我们的单片机有一个机制叫做中断机制,这个中断就是呃,我们俗称的前后台系统,就是一个中断限量表,这个限量表里面呢?对应有呃每一个中断符函数的地址啊, 我一产生一个中断,我就会跳到这个服务历程里面去执行这个相对应的服务,呃就是中断服务函数处理一些内容,它相当于一个控制器,可以这样说吧, 这个控制器里面有什么呢?有很多的一些中断。呃,这个中断包括一些系统的, 呃,系统的中断跟一些外部的一些中断,那例如是系统的大底寄出去,这些系统的拼打, sv 中断,这些都系统而一些外部中断。 所以我们的单片机它的核核心就是这样一个框架, 根据这个核心我们看这里在这两段是一个代码,是我们的呃返回边代码,看一下我们程序是如何运行的这面函数的返回边,你看这 这些地方,它就是一个指令啊,不是说错了,不好意思,这个是我们的 fetch 里面的指令,就是这个指令。哎,我刚才都说了指令是放在 fetch 里面的,这个就是 fetch 的 地址, 明白没有?这个是 fast 的 地址,而这个才是指令,这个上去知道这个这个东西才是指令,我们的指令, 我们,呃,关于指令的话我下一节才讲,我现在说这这部分就是我们的指令,这个指令会我们放到我们的 cpu 里面,比如这个 是吧?第一条指令 f 七 f 一、 f d 八一是吧? 它会放到 cpu 里面, cpu 会根据这个指令指令码会执行相应的动作,明白没有?而相应的动作其实就是我们后面这里 这个就是跳转,就是进行跳转指令的意思。 还有所以我们整个它面积,它运行内核运行的话,其实是不是很复杂的?简单的来说就是 cpu 曲子曲, 指令就是曲子接着运行指令,一个曲子一个运行, 就是这么简单,曲子运行,曲子运行,它的内核就是这样一个循环。 好,现在看一下下面,这里,它就是我们这里就是我们的 cpu 里面的一些寄存器, 刚才说了一包括一些通风积存器,还有一些程序状态的积存器,特殊功能积存器这些组成的。 这个右边这个表就是我们的中断相关的东西。呃,异常清单嘛?就是异常中断这些 它的一些表,一些清单,刚才有我说的一些这个 kind of s v c s t 系统的集成性, 还有一些外部中断清单。所以,呃,整个运行的话其实不难,单片机整个运行的话它是不难的, 这个曲子运行,但运行的话,你,你想运行他是在哪里啊?一个外循环是吧? 里面运行是吧?当我外循环的话,他会,会什么时候产生中断?是不知道。他一产生中断,一产生这里,一产生中断,他就会跳转到我们的对应的服务函数里面, 会有一个我们说的一个中断限量表里面就会有相对应的中断服务函数的地址,他一产生中断,哎,是哪?这个 mac 判断是哪个中断了,他就跳转到哪个中断服务书里面。 呃,这个地址里面,接着取这个地址运行,跳转到对应的服务函数里面 去运行,运行完之后又跳回来外循环,是吧?又运行完又跳回来外循环去进行外循环的这些东西。 所以单面机它的整体的运行的逻辑就是这样的,其实不复杂,是吧? 好,今天的课程到此结束。哎,下一节我接着讲关于,呃,是,下一节讲的是我们的双对战机制。好,今天的课程到此结束,谢谢大家。 大家好,呃,欢迎回来我的课程,今天我要打算讲一下第二课, coach n 三,它的双对战机制。这个课程是非常重要的,对于学习 rto s 的 话, 对于学习 rto s 来说是非常重要的。好,现在开讲它有四点,我们的 rto, 呃,我们的继承器组还有归战。 第二点是我们的 push 入账,还有呃 put 出账,还有第三点,我的 psp 积分,还有 msp 积分。第四点,模式选择好,现在开始。呃, 大家先这个关于我们的入站,出站这两个呃哈指令的话,先大概了解一下就行,因为下一节我会继续。呃,比较详细的讲一下会编指令,这两个就是会编指令啊,现在可以讲 啊,左边这里,左边这里,这里就是我们的 cpu, 它的一些继电器,刚才上一节已经说了, cpu 有 通用继电器,还有特殊功能继电器 啊,也不多,就十,十,十七个,十七个,对,十七个。好,这里就是。呃,中间这里,中间这里 它是一个,你可以把它了解成一个内存这里中间这里 你把它了解成一个内存,看吧,看不看到这里内存地址,这里是内存地址。好,右边这里,右边这里。它是一个图啊,等一下,会减的。 这位右下角,他这里是一个。呃, 成,呃,我们的看一下啊,他是一个符。嗯,看一下,等一下,这里,哎,怎么有个东西, 哦,对,中断,呃,它的一个中断限量表,对,它是一个中断限量表。哦,哦,不是,它不是中断限量表,它是一个。你看这里 零八零零,它是一个 flash 地址,这也是一个 flash 地址,就是我们复位之后 我们程序跳转到的。呃,第一个位置就是我们 cpu 从这个位置取第一条指令,就是这条指令,这是我们 cpu 取的第一条指令,从这里开始的。零八零零零零零。 这个是是一个 face 地址。好,现在开讲。嗯,出站,入站, 我们怎样出站?怎样入站?我们先讲入站,我们的。呃,这里是 cpu, 是 不是?那 cpu 什么时候发生出站入站呢? 呃,大家想一下什么时候会出现出站入站 是不是要跳转到另外一个函数啊?它就会处在一张,比如呢?我们现在我们程序码是不是一个外循环,是吧? 那它会有很多个语句啊,某一条语句它就是一个函数,比如这里,呃, f, y c, 是 吧?呃,它这个函数是吧? 啊?他执行到这里来了,他就会跳转到这个函数里面去执行,是吧?那他跳转的过程他其实会出征于战,这是第一种情况。第二种情况是什么呢? u y 循环也是 y 循环,是吧?它程序执行,执行执行,是吧?突然外部来了一个中断, 是吧?那中断是什么?中断它其实也是一个函数, 它是一个函数,那会它跳,它也会跳转到函数里面啊?中断函数咯,是不是 i r q i r q 啊?是吧?这个函数里面去执行一些东西,是吧?它会跳转到这里来,它也会出账、入账,是吧?这种两种情况,那我们 r t o s, 它是哪种情况? 我们是不是希望他,他学习性很强?是不是?我们希望 r t o g, 他的学习性是很强的?所以是不是新冠他是中断引起的一个切换了,是不是?这里的中断? 我们一般来说是拼打 sv 中断,拼打 sv p d s v 引起了一个中断,它是一个远中断,它,呃,触发了某个位,它就可以引起一个中断,在中断里面进行一个切换 啊?中断服务函数里面进行切换。所以大家首先要明白什么时候会进行出站入站,这是第一点。那出站入站基金是怎样呃运行的呢?你看,首先 这个,是啊,我们 cpu 的 一些计算器,是吧?首先它会最从最底端这里,这个是程序状态计算器 pr, 它会先把这个东西放到我们的内存里面,这个是你内存地址 放到内存里面,是吧?你看,我都已经写好了 p s r 这接着这个是 pc 寄存器,八十五是 pc 程序寄出器, 它会把它放到这里来,是吧?第二个这里 l r 是 吧?它是,呃保存我们的返回地址的 l r 寄存器,它放在里面来,是不是 接着 r 十三?不是 r 十三,它只是一个指征, 它是,呃,我们当前指向这个指征指向我们内存的某些地方,它的地址,明白没有?这个我们不是出站入站的,我们 r 十二 来到了二十二是吧?现在我们出站,入站多少个了啊?入站多少个了?一二三四,入站了四个是吧? 那第五个呢?从哪里开始?阿三,从这里开始,这里开始。阿三,阿二 二一二零。好了,八个, 八个。这八个是我们一开始把 rto 写 rto s 产生中断,拼打 s b, 中断它进进行入账是吧?拼打 s b 这个函数进入函数之前 就是它之前,进入函数之前它是硬件自动入账的,明白没有?那硬件自动入账是吧?那现在我们的呃 msp 之争 啊?不是。呃,我们的 p s p, 不是 l s p。 说错了,不好意思啊,因为,呃,刚才我说纸张,我还没说,所以我先剪剪个答案给你, 我们现在我们的 p s p 指直线这个位置, 接着我们要做什么?下一步要做什么?我们才入了八个啊,总共是多少个?总共是。呃,总共十七个,减去这个二十三,是不是十六个?是不是总共十六个? 现在我们还有八个还没入账的,那这八个要不要入账?肯定要的嘛,是不是这个八个?这八个的话是我们保存的一些临时,这个继承期里面保存一些临时数据,如果你不让不入账是吧?你不保存它 下次程序运行产生的一些中间的一些变量,他是不是会把它覆盖?是不是?所以我们一定要把它入账,入账。怎么入账?你看 我们进入了我们的服务函数,我们需要做的是什么呢?我们在服务函数这里, 我们首先进入好之后,我们首先要在这一开始这一段要手动的,手动啊, 手动的去保存,我们剩下这些计算器哪些?这这几个是不是 r 四到 r 十一这几个, 这八个手动的保存到我们的内存里面。保存,手动保存。大家记住没有? 如何手动保存的话,到时候我在程序里面。呃,会详细的来说,因为它设置到会编的指令。好吧,它设置到会编的指令,到时候我程序里面会说的, 你看,接着看一下右边这个图,右边图它是一个堆赞,这个一个堆赞图, 你看对战图第一个位置,这个位置就是我们的。 呃,我们的内存第一个内存地址是吧?这内存内存地址放的是什么?嗯, 哦,不好意思,选一下。对,这个是我们的 flash 的, 刚才说了吗? 我闪存的地址,闪存地址是存放这个,存放这内存它的地址,这个内存地址存放在闪存里面, 明白没有?哎?这地偏移的四位,四位之后存放的是这里, 这个就是一个 v c 函数,它的一个地址。明白没有? v c 函数,它的一个地址,先不管这个。呃, v c 函数之后,这里会跳转到这里来,是吧?会进行复位,接着启动引导程序,引导代码, 我们主要关心的是这个位置,不好意思,暂停一下。 嗯,不管了,先不管,先装完它吧。呃,你看我们这个位置 是我们的内存地址,是吧?接着我们从内存地址这个位置会写入我们的 psr, 是 吧?接着第二个入站,这个 pc 是 吧?第三个入站是 lr 这样,所以堆站它是往下生长的,就是 他这个就是站顶吗?是不是我们的站顶?接着我每写一个他就往下去扩展我们的内容, 明白没有?而堆他是不一样的,堆他是往上的,但我们现在不说堆,我们说的是站,所以我们了解站就行了,我们每写一个就是每入站一个,每入站一个就往下生长,所以到了这里是吧? 所以最后 psp 就 指向了这里。大家我先问一下,问一个问题给你们,到时候再陈述你们再你们再得出一个答案,我们 psp 我 这个值,我需不需要去保存它 啊?我需不需要去保存它保存到哪里?大家想一下,因为我们呃保存的这个占内存嘛,是不是我们下次 需要读的嘛?这个是入站,我们出站怎么办?我出站是下次啊,从这个位置开始读是吧?从这个位位置开始读,一个一个一个一个的读出去是吧? 读完之后,呃,接着这个就是自动出站了,上面上面这八个就是自动出站了, 这就是一个呃任务切换它的一个流程。下面也其实也不用讲了,刚才已经讲的很清楚了,这是出站入站啊,讲一下这里,这里也很重要, 这个是一个控制计算器,这个控制计算器是 quarters m 三,它的比较重要的一个计算器, 它只要两个位,一个位,这个它是一个选择我们的呃模式,它是呃现成的用户级模式还是呃现成的特呃特权级模式, 用户级跟特权级啊。首先说现成模式是什么? 大家想一下现成模式是什么?除了现成模式还是什么?什么模式?从这个图可以看得出 hunter 模式, 所以我们的单片机程序里面有两种模式,一个是现成模式,又是 hunter 模式。 hunter 模式简单来说就是我们的中断, 我们进入中断之后,他就自动进入进入了 hold 模式,而中断以外的都是我们的现成模式, 大家明白没有?所以就两种很简单嘛,一个是中断,你把它理解成进入中断就行了嘛。一个是没有进入中断,就这么简单。而特权级跟用户级又是什么? 特权级,他的意思是我可以访问一些高级的寄存器,他叫特权级,如果级就是我不能访问一些高级的寄存器里面高级的寄存器就是指特特殊功能寄存器。 呃,例如是中断相关的啊,中断相关的继承器啊,或者是程序状态继承器,这些就是特殊功能的嘛, 我们就不能反问,如果你是用户机,特权机它才能访问,明白吧?那大家想啊,他我为会您怎么只都是只能设置 现成现成模式不能设置。呃,嗨的模式肯定是不能的吗?中断他是自动进入的吗?是吧?自动进入嗨的模式的吗? 我们只能选择什么呢?选择现成模式,它现成模式它只能选择特权级和用户值,而 hand 模式它是肯定是一个特权级的,它肯定是可以访问一些特殊功能计算器, 只有现成模式才有的选择,我们一般的话也会把它选择选择成特权级, 系统默认也是可以选择,呃,也是选择特权机,就是你可以去访问他,访问一些特殊功能计算器。好,呃,接着卫 卫仪,卫仪是选择我们的,呃, m s b 指征就是主堆站指征,呃,县城堆,县城堆站指征。这两个堆站指征其实就是 r 十三,刚才说的 r 十三, 呃,我们 cotz n 三,它是双对称直角的,呃,你,你选择零的话, 那它就是选择了主单向直角,呃,直角,而选择一的话就选择了,呃,近程对称直角。 那我问大家,我,我进入了中断之后,那我这个 r 十三代表的是 r 十三代表的是什么?代表的是 msp 主堆栈子帧,就不用问我,它程序就是这样设置的, 听到没有?但我,我又要问你,我进入了中断之后,那你刚才说嘛?我拼到 sv, 它是进行用户切换的,是不是?我拼到 sv 进行用户切换,那用户切换?假如我, 呃,我的任务是用 psp 指征的,那你说我进入任务,呃,呃,终端之后,我怎么去用 psp 呢?你不是说用 nsp 吗?其实,呃,我们可以 选择用 psp 的, 进入终端之后,我们也可以对 psp 进行读写, 明白没有?是可以进行读写的,但你,你想啊,它,呃它的入站出站,它入站出站它是默认使用 nsp 的, 这个它会前置变为 nsp, 但你可以设置设置为 psp, 但不知道大家明不明白这个道理,嗯,到时候在程序里面我会呃详细的讲一下。好,这里是一个呃 呃现模式的一些转换模式转换图其实也刚才也说了, 我们,呃,看这里就知道了他的模式,他这是一个中断,他有异常的时候就会进入他,就这么简单。 好,呃,今天的课程到此结束。呃,下一节讲一下我们的会变语言。好,谢谢大家。 大家好,欢迎回来我的 ios 课程,今天我要讲解一下第三课,掌握基本的会编指令。 呃,我想先问大家一个问题,会编指令它究竟分呃,哪种?哪几种?好了,回,回到上上一节课看看, 看看这个图,你看我之前说过了吗?这里,呃, 这个位置就是我们的指令,是吧?这个位置就是我们的指令。那指令你看有些他是多少个位?呃, 八八乘四,八乘四,三十二位,是不是有一些他是三十二位的?你看有一些四乘四十六位。哎,为什么有一些指令他是三十位,有些指令他是十六位的。 大家有没有想过这个问题?其实我们的会变指令其实是好多种的, 这只是我们单片机他的一些指令机, 还有其他的指令呢?你看 x 八六,我们经常用的计算机,他也有会编指令的,他也有一个指令机啊,所以会编指令他的范畴是很大。那如果你 说你会不会编指令,那觉得你反而人家觉得你读他会。会编指令,应该说你会会编指令。哪一个指令集就是会编指令,是吧?嗯,指令集, 你要说明你会的是哪些指令集,明白没有?因为会编指令范围是很广的。 好,现在讲一下我们简单的一些基础的一些会变指令。 好,会变指令总量,它有很多种的,很多种的。现在我讲的刚才说的。哎,有一些三十二位的,是吧?有一些十六位的, 而十六位的我们通常接触的单边只有二指力,它是十六位的,也有三百指力,它也是十六位的,也有三百二指力,它是三十二位的。 呃他是。哎,错了吧?说错了,不好意思啊。哎,这里怎么这么搞?说错了,调过来 调过来。对, 三十二位也是三十二位,这才是十六位, 我们的三百二才是十六位的。大家清楚三百二才是十六位,它是比较新的一个指令级十六位。十六位跟三十二位它的区别就是 十六位比三十二位。他的指令他的呃指令密度啊,就比较紧凑。明白,没有他指令他的密度就比较紧凑一点。 好,呃点一下我们指令它的类别有哪些?主要有四大类,就是一个数据处理,就是数据操作的。数据操作类一个是内存读写的,一个是跳转的,还有一些其他的 啊数据操作主要是什么?加法啊,减法啊,乘法啊,一起加载啊,逻辑运算啊, 你看逻辑运算还有什么?呃左移啊,右移啊呃这些左移右移啊那些 呃还有一些暗微操作啊暗微啊,暗微操作啊暗微语啊那些啊这些暗微。暗微语也叫逻辑运算嘛,它也是暗微操作 加载就是把一个数加载到另外一个继承器里面啊。乘法不用说了,加减乘嘛就没有除的,反正就不见有除的操作。 你别说我们的,我们都会编指定有个除法的指令,但是没有的只有加减乘啊。呃除了我们的数据操作还有一个内存读写,内存读写就更简单,也很少, 主要就是读内存写内存。内存嘛。内存不是寄存器哇,大家要清楚啊,我们寄存器通常说的就是我们的 cpu 啊,就那么几个,刚才说了啊,十十七个减去一个 s b 的, 就这 r 十三的, r 十三是一个直角嘛,其他的就是一个 r 十六个除张除张, 所以我们通常说这个数据操作就是应用在这里,应用在我们的计算机,而我们数据内存读写主要的就是对账, 这里就是对账。什么读内存啊?读对账嘛就是读内存就是读对账嘛。啊就写啊啊读啊, 读啊,读到哪里啊?读到姬存希里,读到姬存希里面嘛,是不是写啊?把姬存希写进来嘛, 是不是?所以这个数据操作主要是操作的就是我们的同城集选区啊,内存操作,内存读写槽主要是我们的对账啊,出账入账啊,出账入账。 没?不用说了,就跳转就更简单了,就一个无条件跳转一个一个,还有一个有条件的,条件的条件的。有个有条件的。这里没有说我 啊。什么有一些 eq 啊,是吧? eq 啊,还有什么? 哎,忘记了,反正就它根据有。有四个状态位嘛有四个状态位 有四个状态位,呃标志也不算状态位。四个标志哪四个?一个是复数标志, 一个是除了复数还有一个。呃呃进位好像是进位进位,呃。一个溢出 还有一个,嗯忘记了,反正就四个,哎。这个这里啊,好多种的,十五种, 这个就标。呃。这个是叫什么?嗯条件嘛?对的十五个条件嘛, 它有十五个条件嘛?这个是相等, 呃对,呃。还有一些是否负数啊什么的,是否进位啊?呃是否溢出啊这些所以它有十十十五种条件嘛, 它会把这些条件码放到我们的 b 后面,这里后面会有 e q 是 吧? e q 是 不是相等是吧?它会根据这个条件码来跳转,如果它先等了,它就会跳转到 呃,相应的一个位置里面,明白没有啊?这个位置是哪里啊?就是我们的 l r 吗? 跳转到我们的 l r 里面嘛。而这个 b l r 是 什么? b l r 是 它跳转了 l r, 经常更新的 l r 就是 这个意思。而 it, it 什么?类似于 if 是 吧? f 如果是条件福利了,成立了就执行这个,如果不成立了, 他就执行这个是吧?那么他还有还可以这里又加一点 i n f 是 吧?这又加一个条件,又跳, 它有好几个的,这个 i t 还有 t 啊,你加加几个也可以,它就这样,它是一个语句块 啊,与巨款大家不不清楚的话可以去酷特斯 n 三塔神的一个呃指令机里面去详细的去了解,它里都有很详细的说明的,或者去去百度搜索一下也行 啊。其他指令就不多说了,就一个开中断和关中断用的比较多的, 开中断,半中断这两个 c p s i i e c p s i d 啊, i d i e 嘛,这中断 enable 嘛,中断 disable 其实就会变指令也不多,主要是,呃,你们多可以把一些 你们写的一些习语言程序经过反馈编之后,他会生成一些会编码,你可以多去把那些会编码去呃,学一下,看一下,熟练一下, 就基本上可以掌握了。能写能看就行,写的话其实不不太需要自己去写会编的 啊,大家明白,其实不太需要进行写会编,哪些需要呢?就是哪些需要去写会编呢?就是出站入站。刚才说了这些要访问一些特殊功能计算器啊,这些 特福特访问特殊功能计算器这里好像没说哎。还有一个,这个 m s r m r s 这两个指令,这个就是写的 写特殊的功能的计算器的,这个就是读的读特殊功能计算器的, 明白没有?刚才上一节我讲出站入站怎么说的,你进入了憨憨的模式, 那它指 r 十三变成了 nsp 是 不是?那我 r 十变成 nsp, 我 怎么去处理 psp 的 数据啊? 怎么办?我读嘛,我可以通过这个汇编指令,是不是 r m r s 读我们的 p s p 指征是吧?读之后那我们是不是可以保存呢?是不是保存 或者呃,读取嘛?接着我不要,我需要保存了,我去保存它啊,我去写它。那我写呃 psr 嘛,是不是? 是不是我保存完了我写一下 psr 现在的词是不是?所以就是,所以说有一些地方它还是要优惠,变成 有些呃,大部分的不需要,有一些关键的还是要。嗯,也不多,大家自己去消化一下。今天的课程到此结束,谢谢大家。 大家好。呃,欢迎回到我的课程,今天我继续来讲最后一节课第四课,手把手教你如何编成一个 r t o x。 呃,上几点已经讲解了好呃,比较多的一些内容,关于算对账啊,会编啊呃之类的,今天的内容也是非常硬核的 呃,这七个步骤都是比较重要的。接着最后还有一个呃,我字的编辑,好的,一个 小型的 r t o s 我 会展示给大家看看之前要先了解这些内容。好,先看点。第一,原子操作。什么是原子操作?原子操作就是 让我们的读且改是一个完整的过程。读且改啊,不好意思,读改写, 读改写,它是一个完整的过程,不可以打断。明白没有?这一点, 就是他这三步骤是同时进行啊,不是同时进行,他是连续进行,不可以被打断,他叫软式操作, 这是对于 r t o s 来说是非常重要的,因为 r t o s 它是一个怎么一个情况?它是不断的去切换任务,切换任务就是出站入站,出站入站是吧?那出站入站的话,假如我在任务 这里有一个任务一,这有一个任务二,是吧?任务一跟任务二前面有一个, 呃变量,这是全变量,我对全变量进行写一操作,但,呃呃,或者这样加加吧, 我对他操作,我也对他操作,那操作这个的时候他是一个读改写,操作这个的时候也是一个读改写, 他在读改写,比如我任务一,他在读改写的时候被打断了,读改写,是吧? 行,这也是读改写, 对吧?我读 读改写,改了之后我没有写进去,我又读,我读的是什么?是他写之后的诗吗?不是,是他原本的值,对吧?原本值,他又改又写 又写回去了,是吧?那我现在改完之后,我写的值是哪个? 我问大家写的是哪个?是他当前堆在里面继承器的值,明白没有?他,所以他只写了一次, 明白,没有。这个我这个写了没用了,我这个写没用了。其实写的就是我堆在里面这个值,这个阿里他这个值我写的没用了,我把它覆盖了, 它就不是一个原子操作了,明白没有?它一定要是连续的做完了这三个步骤,你才能做其他连续的操作,这叫原子操作,这个对于 rtv 来说非常重要。 好,废话不多说。下一个 用户状态,用户状态有哪些?我们 rtv 用户状态有哪些? 一个是就绪。 哎,就 就字怎么写?打出来了忘记 就绪。一个是就绪态,第二个呢? 延时,延时差,呃。不是,就是一个,是我们的运行 三,还有我们的挂机 四,我们的通道五,我们的删除, 我们的任务状态只有这五种,明白?没有?我们任务一个任务他只有这五种状态, 大家机器人没有这五种状态,它是可以,有一些是可以相互转换的,有一些只能单向,也有有些是双向。 比如我就绪是吧?就绪之后它到到达了最高优先级,它就变成了转运行了,是吧?当我发生了挂运行之后,它发生挂起了,它也会被挂起, 对吧?如我中弹来了,他会打断这个运行, 他会打断这个运行,但我删除也会把就是他里面东西删除,他就不能运行了。所以他是互相可以会转换的,也不是说互相,他有一些地方是可可以转换的, 大家了解一下就行。呃,这个任务状态好。呃。下一点, 下一个我们的优先级,这个是非常重要,其实这两个都非常重要,我们的优先级。任务优先级跟终端不一样,任务优先级他是可以无限多的,大家可以 啊,可以无限去设置我们的用户优先级。呃。假如我设置了三十二个用户优先级,我可以用一个变量来表示我们的优先级,什么意思?只要我这个变量它是三十二位的, 这里是位三十一是吧?这,呃,下面这个位三十是吧?最后位一位一是吧? 那假如我用一个变量去表示,表示优先级是怎样表示?嗯, 我这个优先。呃,我这个任务,这个任务,假如这个任务 一,这个任务一他优先只是五,那五十在哪里?数一下这个二、三、四是吧?五,五在这里,五, 我这个任务就会放到五的就绪列表里面,他一创建他就是一个就绪状态,明白没?我,我今我会任务会插入到我们的就绪列表里面,那我就绪列表 会让这个变念致意,致意的意思代表我就绪列表里面有任务就绪了的意思。那我假如我优先寄回你,我对应的也有一个就绪列表, 这个就绪列表假如它是有就绪任务的,那它它也致意, 因为我这个三十二位的变量,他就变成有三十二位,他的对应的位,他表示当前这个位里面任务的就绪列表有没有就绪任务, 那我现在为的,比如我为零有就绪任务了, 我为您代表是就优先级为零的。呃,继续那个,那我,那我是不是也现在优先执行?他是不是?所以他就是一个寻找这个,呃,变念 变脸,哪个位有优先级就执行哪个就绪列表里面第一个任务它的意思,所以这里优先级说完之后我是不是延伸了一个任务列表, 是不是现在开始任务列表了?大家要注意一下。

大家好,欢迎来到 esp 三二入门系列教程。今天我们将深入探索 esp 三二开发的核心 free r t o s。 实时操作系统。无论你是刚接触 esp 三二的新手,还是希望提升系统开发能力的工程师,掌握 free r t o s。 都是必经之路。 本次教程将带你从零开始,一步步揭开 r t o s。 的 神秘面纱。本次教程将分为六个部分,首先,我们会介绍学习 free r t o s。 的 背景和重要性,接着探讨为什么在复杂项目中需要 r t o s。 然后,我们将深入学习 free r t o s。 的 核心概念任务,之后会详细讲解队列、信号量、互斥所、事件组和任务通知等关键的通信与同步机制。让我们开始吧! 首先,让我们进入第一章节前沿。在这一部分,我们将了解为什么 free r t o s。 对 于 e s p。 三二开发直观、重要,以及它为我们的项目带来了哪些核心价值。 e s p i d f。 框架与 free r t o s。 是 密不可分的,我们开发的每一个应用本质上都是在 free r t o s。 的 环境中运行。 学习 free r t o s 不 仅能让我们更好地利用 esp 三二的硬件资源,更重要的是它是一项可迁移的技能。由于其开源免费的特性, free r t o s。 已成为嵌入式领域的事实标准,掌握它将极大地拓展你的职业道路。 接下来,我们探讨一个根本性问题,为什么我们需要 r t o s? 在 资源有限的低端设备上,裸机程序似乎也能工作,那么引入 r t o s 能带来什么好处呢? 这张图直观地展示了两者的区别。左边是裸机程序的大循环模型,一个环节卡住,整个系统就停摆。右边是 r t o s。 的 多任务调度模型,高优先级任务可以随时抢占 cpu, 低优先级任务在等待时会主动释放 cpu, 这种机制使得系统能够高效有序地处理多个任务,这正是 r t o s。 的 核心魅力所在。了解了为什么要用 r t o s 之后,我们来深入学习 free r t o s。 的 核心概念。任务任务是 free r t o s。 应用程序的基本执行单元。 这张状态转换图清晰地展示了任务在四种状态之间如何转换。例如,一个运行中的任务调用 v task delay 后会进入阻设态,当延时结束,它会回到就绪态,等待调度器再次选中它。理解这些状态转换是掌握任务调度的关键。 优先级是任务调度的核心依据,我们可以被不同重要性的任务设置不同的优先级,确保关键任务能够得到及时响应。例如,处理案件中断的任务优先级应该高于一个周期性打印日制的任务。合理的设置优先级是保证系统实施性的关键。 创建任务是使用 free r t o s。 的 第一步。 x task create pinned to core 是 esp 三二特有的函数,它允许我们将任务绑定到特定的核心,这对于双核处理器的性能优化非常重要。 而 vsk delay 是 最常用的让任务主动让出 cpu 的 方法,它让任务进入堵塞状态,等待指定时间后自动回到就绪态。有了任务,我们还需要让任务之间能够相互通信和同步。 接下来,我们将学习 free r t u s 中用于任务间通信和同步的几种核心机制,队列信号量和互斥锁。 这些机制是构建复杂嵌入式系统的基石,能够确保系统运行的正确性与高效性。这张图展示了队列的工作原理。任务 a 和中断服务函数都可以通过 xq send 向队列发送数据,而任务 b 则通过 xq receive 从队列中取走数据。 队列就像一个安全的中转站,确保了数据在不同执行单元之间可靠的传递。通过队列,我们不仅实现了任务间的数据交换,还利用其阻塞特性让任务能以更高效有序的方式协同工作。这些是操作队列最核心的 api。 xq create 用于出使化队列。 xq send to back 和 xq receive 是 最常用的发送和接收函数。特别需要注意的是,在中断中必须使用 from e s r 版本的函数,因为中断上下文与任务上下文不同,需要特殊处理以保证安全。 这张图展示了二进置信号量如何用于任务同步。任务 a 通过 x and f for take 获取信号量,如果获取不到就进入阻涩。中断服务函数在某个事件发生后,通过 x and f for from s i r 释放信号量唤醒等待的任务 a。 这是实现中断服务函数与任务同步的经典模式。 护齿锁是信号量的一种特殊形式,它的关键特性是优先级继承。如右图所示,当低优先级任务 l 持有护齿锁时,高优先级任务 h 请求该锁会被堵塞,此时任务 l 的 优先级会被提升到与 h 相同,确保它能尽快完成工作并释放锁, 从而避免了中等优先级任务 m 的 干扰,这保证了系统的实时性。接下来我们学习事件组,当一个任务需要等待多个事件中的任意一个或全部发生时,使用事件组会比使用多个信号量更加高效和方便。 这张图展示了事件组的应用场景,任务一可以等待事件位零和事件位一都被置位,任务二和任务三可以分别设置这两个事件位。当两个事件都发生后,任务一被唤醒,继续执行。这种等待多个条件的能力是事件组独有的优势。 最后,我们来介绍一种更轻量级、更高效的通线方式,直达任务通知,它可以替代二,禁止信号量技术信号量甚至简单的队列,并且开销更小。 任务通知是 free r t o s。 提供的一种非常高效的通信机制,因为它不需要额外的内核对象,所以速度更快,内存开销更小。对于许多简单的同步场景,比如任务间的简单通知或模拟信号量,使用任务通知是优于传统队列和信号量的选择。 到这里,我们关于 free r t o s。 核心概念的介绍就全部结束了,从任务管理到各种通信同步机制。希望这次教程能帮助大家顺利开启 esp 三二的 r t o s。 开发之路。 技术之路永无止境,希望大家能在实践中不断探索和进步。谢谢大家!现在是问答环节,我是致歉, ai 工作室余生关注我,一起用 ai 玩转介入式。

简单使用下 freertos 队列,队列是 freertos 数据传输方式的一种,可以用于任务间数据传输,也可用于任务与中断间数据传输。在之前的视频中,我们使用串口打印信息,在每个任务中都有使用,也就是这种结构。 这种结构中每个任务既需要产生数据,比如处理传感器数据等,又需要关心数据的显示,导致任务逻辑层次不清晰。每个任务都有显示程序,我们就可以使用对列,将程序分层一下,把显示相关程序单独拿出来,组成一个显示任务, 其他几个任务只需要将各自要显示的数据都写入队列。显示任务只需要从队列中读取数据进行显示,这样整体结构就变得很清晰。 任务一到三就可以专注自己的数据产生,而不需要关心怎么显示数据。显示任务就只关心怎么显示数据,而不需要关心数据怎么产生的。下面我们就使用对列简单实现一下这种结构。这是之前多任务视频的代码,我们先删除多余的程序, 每个任务只保留打印程序,然后保存编译一下没有错误,就可以开始本期实验了。 我们需要使用队列,所以要先包含一下队列的头文件。本次实验实现一下任务一任务二写队列,任务三读数据并打一显示。 首先我们需要创建一个队列,使用 x q create 可以动态创建一个队列。我们右键转到定义,看 下他的参数,这里他是使用了一个红定义,定义了一下这个函数,方便了我们的使用。第一个参数就是对列的长度,也就是对列可以存放多少个数据。第二个参数是每个数据的大小,单位是字节, 所以这里的参数就可以这样写。上面有两个任务需要写数据,对列长度我们就设置为二,而每个任务要写的数据是一个字符串,我们就设置二十个字节的数据大小吧。 现在创建队列参数已经写好了,可是创建的队列我们去哪里找呢?其实这个函数的返回值就是我们创建的队列,我们可以看一下函数原形,右键跳转过去,这里返回值是这种类型,我们也要定义这样一个变量,用来接收创建好的队列句柄, 复制一下回到我们的代码,在上方定义一个变量,随便起一个对列名字, 用这个变量接收一下返回值,这样一个队列就创建好了。更严谨的写法,还需要在下方判断一下返回值是否为空为空,队列创建失败,我这里就不写了。队列创建好后就可以写队列了, 现在开始修改任务函数,将打印程序注释掉,写对列。我们使用 xq 三的函数,可以右键转到定义,看下参数, 也是一个红定义函数。第一个参数是堆列句柄,第二个参数是数据的地址,这个数据的值会被复制进堆列。第三个参数是阻塞时间, 对列满无法写入新数据时,会阻塞我们设定的时间,回到我们的代码。第一个参数我们填入对列句柄, 第二个参数是数据地址,我们要先定义一下数据,在上方定义一个字符数组,数组大小就是创建对列时指定的数据大小,二十字节,不能随便定义大小。 我们初始化为这个字符串,将数组名填入第二个参数,第三个参数是组色时间,我这里写零,也就是无法写入数据时,函数会立刻返回,这样写入对列就完成了。我们把任务二同样的操作修改一下, 这里字符串改为任务二,写入对列完成后,就开始读对列并显示数 据了。我们修改一下任务三,读对列,使用 xq receive 函数,同样转到定义看下参数,这里和写对列参数基本一致,就不过多介绍了。回到我们的代码,直接写参数,第一个是对列句柄, 第二个是读取的数据存放地址。我们也定义一个二十字节字符数组,用来接收读取的数据。将数组名填入参数, 第三个阻塞,我们填入一个 port max delay, 也就是读不到数据就一直阻塞在这里。这样做的目的是没有数据时,就等在这里有数据才会继续执行下方的显示程序,这样就不执行无用代码,提高效率。 现在读对列已经完成了,我们开始写显示程序。显示之前要先判断一下是否读取成功。 右键转到定义,看下返回之类型。我们定义一个这种类型的变量,用来接收返回的状态。回到代码,在这里定义一下, 用这个变量接收一下返回值,读取成功会返回 p d two。 在下方判断一下返回值, 这里应该是 p d 处,写 p d pass 也没问题。然后把下方的显示代码放到 f 判断里面,修改一下,打印函数,打印接收数据 data 数组中的字符串, 这样就可以了,由于独对列没有数据是一直阻塞的,下方的 delay 也可以不需要了,现在我们编译一下,没有错误,我们点击进入 debug 看下现象,点击全速运行,可以看到串口是正常打 音数据的,这样就实现了任务键传输字符串。那要是需要传输很多不同类型的数据该怎么办呢? 大家可以暂停思考下,我这里告诉大家答案,可以使用结构体,具体怎么做,我们现在来写一下代码。首先我们要定义一下要传输数据的结构体类型,在上方定义一下结构体, 结构体中定义要传输的数据,我这里传输一下这个字符串和一个 int 变量。定义好结构体后,要修改一下创建对列,这里的数据大小,数据大小我们使用 size of 来计算一下结构体大小, 这样修改后再修改一下任务函数,先定义一个结构体变量,再 初始画一下结构题的字符串参数,下方这里数据要取地址这里我们再让变量艾字加下方的任务二,同样的方法修改一下, 然后修改一下显示任务,这里也要定义一个结构体变量,用来接收读对列数据,这里别忘了要取地址, 下方这里我们就打印一下读取的结构题数据,这样修改就可以使用对列传递结构题数据了。我们编译一下,进入 debug 看下现象,点击全速运行, 可以看到现象是正确的,这样就实现了任务间依次传递多种阐述了。本期的视频就到这里了,欢迎留言评论,我们下期见。

free rts 的 一个系统节拍,也就是一个 tick 是 多长时间? stm 三二中一个 tick 的 时间就是 cs tick 定时器的中断周期。可以在 free rts 配置文件中配置系统节拍频率。当系统节拍频率配置为一千时, 一个 tick 就是 一毫秒。配置为一百时,一个 tick 就是 十毫秒。 free r t s 的 延时函数微 task delay 就是 以 tick 为单位,但我们一般希望以毫秒为延时单位。 free r t s。 提供了一个宏 p d m s two ticks, 可以 把毫秒数转化为 tick 数。这样即使我们修改了系统节拍频率,延时时间依然不会变,代码更灵活。麻烦点赞关注啊。

朋友们大家好,今天我来介绍属于 r t o s 操作系统的任务调度。之前的几期视频中,我们介绍了 r t o s 的概念,以及为什么要使用 r t o s 操作系统,然后介绍了如何在 free r t o s 中创建任务。 那么今天我来介绍 freert os 中任务调度的规则。一个单片机需要同时实现很多功能,比如屏幕显示、串口通信、电机控制、读取传感器数据等。这就如同一个人在同时做很多件事。 我们把单片机比作餐厅的大厨,他在忙碌的时候需要一个人操作好几个锅,同时炒好几道菜。如果让普通人去做这件事,难免会手忙脚乱,但是餐厅的大厨却可以轻松应对。同理, 我们在给单片机编程的时候,也希望一个单片机可以做尽可能多的事情,这样不仅可以简化硬件方案,也可以降低产品的成本,在市场上取得更大的竞争力。就比如一个厨师同时做几道菜这件事情 用裸机编程的思维该如何实现呢?大致流程会是下边这个样子,先进入闷函数,然后各种初始化,直到进入一个 vs 循环,在里边按照事先写死的顺序,一遍一遍重复执行。 这种操作方式的弊端在上期视频中我们已经讨论过,这里不再赘述,因为时间相隔久远,没有印象的同学可以去看之前的视频。如果把上边的代码移至到 freertos 中,则会是下边这样在经过一系列的初始化之后,把所需要的工 以任务的形式创建出来。这些任务在执行的时候没有固定的先后顺序,是通过一系列的规则来确定哪些任务先被执行,哪些任务暂时不能执行。 freerts 中的任务可以有以下几种状态,运行、就绪,阻塞、挂起。第一,运行。他是指当前任务正在执行,他处于运行状态,而且正在使用处理器。 如果运行 rtys 的处理器只有一个内核,那么在任何给定的时间都只能有一个任务处于运行状态。第二,就绪。指任务能够执行,但目前没有被执行, 因为同等或者更高优先级的不同任务已经处于运行状态,就绪状态不同于阻塞或者挂起状态。第三,阻塞。如果任务正在等待 时间或者外部时间,则任务处于阻塞状态。例如,如果一个任务调用 v 塔斯格迪丽函数,他将会被阻塞,直到设定的延时结束。任务也可以通过阻塞来等待队列信号量、事件组通知等。处于阻塞状态的任务通常有个超时时间, 超过这个时间后,任务将被解除阻塞状态,即使该任务所等待的事件没有发生。 阻塞状态下任务不使用处理器,时间也不能进入运行状态。第四,挂起。与阻塞状态下的任务一样,挂起状态下的任务不能被选择进入运行状态,但处于挂起状态的任务不会超时。 任务只有通过 spend 和 resume 函数才能进入或退出挂起状态。再知道一个任务可以处于的四种状态 之后,我们来看如何对任务进行调度。第一种调度方式,人群调度。我们规定一个非常短暂的时间为一个时间片,这里以一毫秒为例,假如有两个任务处于同一个优先级, 每个任务运行一个时间片之后,切换给另外一个任务运行,依次轮流运行,这种方式就是轮巡调度,就是处于同一个优先级的任务,他们依次轮流的执行每个任务,每次执行一个时间片。 第二种调度方式,抢占式调度是指调度器始终运行优先级最高,而且处于就绪状态的任务。当一个低优先级的任务正在执行时,发生外部中断,使一个处于阻塞状态但优先级更高的任务获得了 他正在等待的信号量,那么调度器就会停止当前正在运行的低优先级的任务,切换到高优先级的任务,即便当前任务的时间片并未结束。 freertos 默认使用强战士调度策略 会同等优先级的任务使用时间片。轮巡调度调度器不会永久更改任务的优先级,尽管他可能会因为优先级继承而暂时提高任务的优先级。 最近工作上的事情比较多,所以更新频率很低,后边有空的话会尽可能多做几期视频,那么这期视频就到这里了,谢谢大家。

fliotus, 你 的 tick 到底代表多长时间呢?这个问题很多初学者都没有搞清楚。在 steam 上平台上, tick 的 时长本质上就是 six tick 定时器的中断触发周期。这个周期并不是固定的,而是由 fliotus 配置文件中的系统节拍频率决定的。把节拍频率设置为五百,那么每个 tick 就是 两毫秒。 设为一千,每个 tick 就 缩短到一毫秒。频率越高,时间力度越细,系统调度也越精确,但相应的开销也会增加。实际写代码的时候呢?延时函数 v t s k delay 接收的参数单位是 tick, 直接填数字的话,一旦每一天改动的节拍频率配置,所有延时时间都会跟着变,维护起来非常麻烦。 fudge 对 此提供了一个很实用的红 p d m s two ticks, 使用它就可以直接传入毫米数, 有红自动完成到 tick 的 欢送。这样无论系统节拍频率怎么调整,延时的实际时长始终保持不变, 代码的可移植性和可维护性都会好很多。这个小细节在项目里很容易被忽略,但养成习惯之后会省去不少麻烦,建议大家从一开始就规范起来,觉得有用的话呢,点个赞,关注一下,后续还有很多实用的内容分享。

r t o s。 核心就两件事,同步和互斥。别再被元马吓懵了!很多人一提到 free r t o s 就 觉得头大,任务调度信号量、消息队列,学了一个月还是晕。 今天说句扎心的话, r t o s。 其实非常简单,半天就能搞明白,你学不会,不是智商问题,是教程太烂。上来就讲 api 贴源码,连为什么需要现成都不解释。一、 r t o s。 到底在解决什么问题? 裸机程序是一个大外循环,所有模块排队执行,但有些是很急,有些是不急。于是我们把程序拆成多个县城,给每个县城标一个优先级调度器,负责让 cpu 永远跑优先级最高的那个就绪县城, 这就是 r t o s。 的 全部核心。剩下的什么任务,站上下文切换,都是为这个目标服务的工程实现。二、县城带来的两个问题, 同步和互斥。把程序拆成现成后,麻烦来了,同步 a 县城,要等 b 县城干完某件事才能继续。怎么等?互斥? 两个县城同时访问同一块内存, a 写到一半被 b 打乱,数据全乱,怎么防?解决方案就一个字,信号量 p 操作,如果计数器大于零,就减一,然后继续,否则等待 v 操作, 计数器加一,然后叫醒正在等待的县城,把信号量出使值设为零, a 县城 p 一下,等 b 县城 v 一下再执行,这就是同步。把出使值设为一, a 县城先 p, b 县城再 p, 就 得等着, 这就是互斥消息队列,互斥所、事件所都是信号量的变体,解决的无非还是同步和互斥,你搞懂信号量,就搞懂了百分之八十的 ipc 机制。三、为什么你学起来这么痛苦? 因为大部分教程是反人类的。第一步,不告诉你为什么要用 r t o s, 而是直接画个任务创建函数的框图。第二步,不讲 p v 操作的物理意义,而是贴一堆 x m a for take 的 圆码,你还没会走,他就让你跑, 结果就是 api 被的滚瓜烂熟,换个场景照样抓瞎。正确的学习路径应该是理解县城和优先级的概念,搞懂同步和互斥需要什么,自己用几十行伪代码模拟一个信号量,再去翻 free r t o s。 的 手册,看 api 怎么用。 做完这四步,你甚至会觉得 free r t o s。 代码太啰嗦。事实上,一个最简 r t o s。 内核,只要四百行代码就能实现任务切换、信号量、消息队列,那些几千行的源码,多半是各种红和移植层。 四、行业现状,会调 api 的 人太多,懂原理的人太少。现在潜入式面试,十个人有八个说熟悉 free r t o s。 一 声问信号量实现原理就卡壳 企业不缺调用 api 的 人,缺的是遇到优先级反转死组战役初期能自己分析定位的人。而这些能力恰恰来自对 r t o s。 底层模型的理解,不是靠被 api 能解决的。 别再把 r t o s。 当黑盒子用了,花半天时间搞懂它,你会发现这东西简单到不可思议。

来下一个题, free r 去 s 任务的几种状态? free r 去 s 一 共有五种状态,分别是就绪态、运行态、阻滞态、挂起态,还有删除态。其中就绪态它就是任务已经完成的,已经完全具备的运行状态,正在等待 cpu 的 使用权。 运行态就是任务正在占用着 cpu, 只剩它自己的代码逻辑,只有处于就绪态的任务才能进入运行态, 然后在单核的 mcu 中,它同一时间内只有一个任务能进入这种状态。组态态就是任务主动放弃了 cpu 的 使用权,暂时不具备这些功能, 然后等待某个特定的事件发生后才能回到就绪态。挂起态就是任务已经被暂停了,处于无期限的等待状态,既不参与任务的调度,也没有超时机制,只能通过 vita 能调用结束挂起。然后删除态,就是任务的生命周期已经结束, 他已经执行完毕,或者被显示删除他占用的那些资源,比如任务控制块、 t、 c、 b 占空间都会被释放。
