打印
[应用相关]

基于RTOS的软件开发理论

[复制链接]
楼主: 黑心单片机
手机看帖
扫描二维码
随时随地手机跟帖
41
黑心单片机|  楼主 | 2022-5-1 14:04 | 只看该作者 回帖奖励 |倒序浏览
5.1.2 计数信号量

只要产品的平均生产时间比产品的平均消费时间长,所有的产品就都会被消费掉。但仍然有可能在某个时间段内出现临时的“产品积压”。如产品的生产时间为 20-40 秒(平均30秒),产品的消费时间为 10-30秒(平均 20 秒),总体上看是生产慢、消费快,但在某个时间段,生产速度维持在高水平状态(每20秒生产一个),而消费速度偏偏维持在低水平状态(每30秒消费一个),这时就会临时出现产品积压现象。

二值信号量不能处理“信号积压”现象,未及时响应的信号将会被遗弃,有效响应次数少于实际发出的信号次数。在这种情况下,采用计数信号是一个有效的选择,在总体上能够使控制方对被控制方进行同步控制,在特殊情况下也不失去控制,保证每次控制信号都能够得到响应,尽管响应时间偶尔会有延误。

计数信号最初始值为 0,控制方需要发出同步信号时,就调用“发出一个信号量”的服务函数,使计数信号量的值加 1,被控制方在任务的“同步点”调用“等待一个信号量”的服务函数。如果计数信号量的值不为 0,就将计数信号量减 1,并继续运行下去;如果计数信号量的值为0,便使自己挂起,等待控制方的信号。

计数信号量适用于被控制方不能保证在下一次信号到来之前处理完本次控制方发出的信号,但总体上可以响应所有信号。


使用特权

评论回复
42
黑心单片机|  楼主 | 2022-5-1 14:05 | 只看该作者
5.1.3 事件标志组

需要将两个以上的信号进行某种逻辑运算,且用逻辑运算结果作为同步控制信号时,简单的通信方式难以实现,可采用“事件标志组”来实现,事件标志组是若干二值信号的组合,可以实现多个任务(包括 ISR)协同控制一个任务,当各个相关任务(包括ISR)先后发出自己的信号后,使事件标志组的对应标志有效,预定的逻辑运算结果有效,触发被控制的任务。

事件标志组的使用方法很灵活,可以将标志定义为“1 有效”,也可以将标志定义为“0 有效”,逻辑关系可以为“逻辑与”(全部标志均有效),也可以为“逻辑或”( 只要任何一个标志有效)。可以简单理解为某个变量,多个控制任务共同控制变量的对应的位,被控制任务在全部或者某一位满足要求时触发运行。


使用特权

评论回复
43
黑心单片机|  楼主 | 2022-5-1 14:06 | 只看该作者
5.1.4 消息邮箱

用信号量进行行为同步时,只能提供同步的时刻信息,不能提供内容信息,当控制方对被控制方进行控制,需要向被控制方提供内容信息时,消息邮箱是一种有效的方案。

关于邮箱,不同的RTOS其功能定义有一定差异。大多数RTOS的邮箱不支持缓存,后面发送的会覆盖前面;但有的类似简化版的消息队列,支持缓存,只是消息内容固定为一个指针,可以多次发送;有的RTOS不支持邮箱。


使用特权

评论回复
44
黑心单片机|  楼主 | 2022-5-1 14:06 | 只看该作者
5.1.5 消息队列

消息队列是应用比较多,队列可以存放多个消息,能够有效解决消息的临时堆积问題,但仍然需要满足一个条件,消息的平均生产时间比消息的平均消费时间长,否则,再长的消息队列也会溢出。

特别注意,当需要传输的数据量较大时,传输其内容指针,而不是内容本身。


使用特权

评论回复
45
黑心单片机|  楼主 | 2022-5-1 14:07 | 只看该作者
5.1.6 通信方式的选择

以上用于行为同步的通信方式,根据实际情况来选择:

当同步过程不需要传输具体内容时,可选择二值信号量、计数信号量和事件标志组。

当同步过程需要传输具体内容时,可选择消息邮箱、消息队列。

当“任何时候同步信息的生产速度都比同步信息的消费速度慢”时,可选择二值信号量 、事件标志组。

对于非周期性同步信息,当不能保证“任何时候同步信息的生产速度都比同步信息的消费速度慢"时,可选择有缓冲功能的计数信号量、消息队列。

当同步信号为多个信号的逻辑运算结果时,采用事件标志组作为同步手段


使用特权

评论回复
46
黑心单片机|  楼主 | 2022-5-1 14:08 | 只看该作者
5.2 行为同步

合理安排同步点和任务的优先级是获得预期同步效果的关键。


使用特权

评论回复
47
黑心单片机|  楼主 | 2022-5-1 14:09 | 只看该作者
5.2.1 ISR 与任务之间的同步

一个任务(或 ISR)为控制方,发出控制信息,另一个任务为被控制方,获取控制信息后即进入就绪状态,若优先级足够高就可以很快进入运行状态,必要时可在ISR退出前进行一次任务切换。

一个由异步亊件触发的ISR 通常与一个任务关联,它们之间就是单向同步关系,与ISR关联的任务总是处于等待状态,每当ISR发出信息就被触发,其任务结构为事件触发型。


使用特权

评论回复
48
黑心单片机|  楼主 | 2022-5-1 14:09 | 只看该作者
5.2.2 两个任务之间的单向同步

如果单向同步发生在两个任务之间,同步效果与两个任务的优先级有关。当控制方任务的优先级低于被控制方任务的优先级时,控制方任务发出信息,被控制方任务进入就绪状态,并立即发生任务切换进人运行状态,瞬时同步效果较好。当控制方任务的优先级高于被控制方任务的优先级时,控制方任务发出信息后,虽然被控制方任务进入就绪状态,但并不发生任务切换,只有当控制方调用系统服务休眠或其它使自己挂起时,被控制方任务才有运行机会,瞬时同步效果较差。不过,控制方在发出信息后立即调用延时函数( 延时时间大于被控制方任务的处理时间),主动使自己挂起来,让低优先级的被控制方任务尽快得到运行机会,可改善同步效果。


使用特权

评论回复
49
黑心单片机|  楼主 | 2022-5-1 14:10 | 只看该作者
5.2.3 两个任务之间的双向同步

在单向同步过程中,必须保证消息的平均生产时间比消息的平均消费时间长,否则再长的消息队列也会溢出。如果消息的生产者是外部物理世界,其消息生产速度是客观的,为了不遗漏消息,只能提高系统处理速度来应对。

如果消息的生产者是系统内部的某个任务,则可以通过协调生产者与消费者的关系来建立一个产销平衡的理想状态。通信的双方相互制约,生产者通过“提供消息”来同步消费者,消费者通过“回复消息”来同步生产者,即生产者必须得到消费者的回复后,才进行下一个消息的生产,这种运行方式称为“双向同步”,这和UART串口的流控比较类似,其实现方式是单向同步操作的两倍。


使用特权

评论回复
50
黑心单片机|  楼主 | 2022-5-1 14:10 | 只看该作者
5.2.4 多任务同步一个任务

当需要两个以上任务同步一个任务时,简单的通信方式难以实现,可采用“事件标志组”来实现。只要被同步任务的执行速度足够快,其执行次数就可以“等于”各个同步任务发出信号次数的总和,否则也会遗漏个别消息。


使用特权

评论回复
51
黑心单片机|  楼主 | 2022-5-1 14:11 | 只看该作者
5.2.5 多个任务相互同步

多个任务的运行频度保持一致,即一组关联任务在特定点互相等待,每个相关任务在运行到同步点时都必须等待其他任务,只有相关任务都到达同步点,才可以按优先级顺序依次离开同步点,从而达到相关任务的运行频度保持一致的目的。类似一组人各自独立的到达指定集合点,都到齐统一签到,再各回各家。

多个任务相互同步,理论上事件标志组可用来实现多任务相互同步,每个相关任务运行到同步点时都要“签到”,即调用“发送标志函数”将对应标志置位;然后调用“获取标志组标志函数”进入等待状态,当最后一个相关任务运行到同步点并“签到”时,通过逻辑运算产生“全部到齐”的信号(多任务同步标志),并将这个同步信号分发给各个相关任务( 进入就绪状态)后,相关任务按优先级次序先后运行。但是,因为各个任务的运行情况是动态变化的,每个任务都有可能最后一个到达同步点,只使用事件标志组无法判断在最后一个到达同步点的任务清除标志,导致后续会不断误触发。

其实使用最简单的全局变量,记录当前已经到达同步点任务的数量,这样数值累加到一定程度,即可判断出最后一个到达同步点的任务,每个任务再同步点判断计数值,再将同步信号分发给各个相关任务。这个全局变量在多个任务操作,也需进行特殊处理,也就是下一章的资源同步。


使用特权

评论回复
52
黑心单片机|  楼主 | 2022-5-1 14:12 | 只看该作者
6、 资源同步

被两个以上并发程序单元(任务或1SR )访问的资源称为共享资源,共享资源一定是全局资源。但全局资源不一定都是共享资源,固定只被一个任务(或 ISR ) 使用的全局资源并不是共享资源,而是这个任务( 或 ISR )的私有资源,对私有资源的读写操作是不受限制的。

任务对共享资源进行访问的代码段落称为关键段落,各个任务访问同一共享资源的关键段落必须互斥,才能保障共享资源信息的可靠性和完整性。这种使得不同任务访问共享资源时能够确保共享资源信息可靠和完整的措施称为资源同步。

资源同步有关中断、关调度、使用互斥信号量、使用计数信号量几种方法,它们都能够在访问共享资源时,保障共享资源信息的可靠性和完整性。

并不是访问所有共享资源都要采取资源同步措施,如共享资源具有“只读”特性,其信息只能读出,不能改写。这类共享资源具有天然的完整性和可靠性,各个任务可以任意读取,如系统内固化的硬件参数信息。需要采取资源同步措施进行访问的必定是动态共享资源,至少存一个任务( 或ISR)可以对其进行“写”操作。


使用特权

评论回复
53
黑心单片机|  楼主 | 2022-5-1 14:12 | 只看该作者
6.1 关中断

一个任务在对共享资源进行访问前将中断关闭,然后执行访问共享资源的关键段落代码,操作结束后再打开中断。

当中断被关闭后,系统失去了对所有事件的反映能力,不能进行任务切换,从而保证了对共享资源的独占式访问。(优先级非常高的硬件中断不受操作系统关中断控制,具体与RTOS实现及其配置有关)

当参与访问共享资源的并发程序单元中包含ISR 时,关中断是任务访问共享资源的最简单方法,也是唯一的方法。

关中断的优点是简单,缺点是影响系统的实时性。为了减轻对系统实时性的不利影响,访问共享资源的关键段落代码必须尽量简短,绝对不允许在关键段落代码中包含有可能使自己挂起的系统服务函数,否则将使系统死机。

当需要对共享资源进行“写”访问时,先将需要“写入”的信息提前准备好,存放在自己的局部数据结构内,这个局部数据结构与共享资源的被访问部分的数据结构相同,然后关中断,在关键段落代码中只需要完成将局部数据结构的内容复制到共享资源中的操作即可,复制完毕就可以开中断;由于两者数据结构相同,所以执行复制功能的关键段落代码自然非常简单、 快捷。

当需要对共享资源进行“读”访问时,先准备一个与共享资源被访问部分的数据结构相同的局部数据结构,然后关中断,在关键段落代码中只需要完成将共享资源的有关内容复制到局部数据结构中的操作即可,复制完就可以开中断。退出关键段落代码后,再对复制到局部数据结构中的信息进行相关处理。

由于关中断直接影响系统的实时性,因此只能用于对简单共享资源的短暂访问,一般用于对全局变量或小规模全局数据结构的访问。


使用特权

评论回复
54
黑心单片机|  楼主 | 2022-5-1 14:13 | 只看该作者
6.2 关调度

当共享资源比较复杂或者规模比较大时,关中断的方式不可取。如果该共享资源的使用者全部是任务( 即不包含 ISR ),就可以采用关调度的方法来访问共享资源。

关调度的方法使操作系统的任务调度器停止工作,不能进行任务切换,从而保障关键段落代码的执行不会受到其他任务的干扰。

由于关调度的方法没有将中断关闭,故系统对各种异步事件仍然可以及时响应,并使相关任务进入就绪状态,但不会立即进入运行状态。这也是关调度的缺点,导致所有任务受到牵连,即使它们的优先级足够高并被ISR 触发到就绪状态也无法运行。

在关调度期间,必须尽可能快速完成访问共享资源的工作,以缩短关调度的时间。如果在关调度期间调用系统服务函数而被挂起,其他任务又不能运行,那么系统将崩溃。关调度的资源同步方法优点不多,缺点不少,尽可能不要使用。


使用特权

评论回复
55
黑心单片机|  楼主 | 2022-5-1 14:13 | 只看该作者
6.3 使用互斥信号量

当需要访问的共享资源比较复杂,且访问过程比较费时时,关中断、关凋度的措施不可取,它对系统实时性产生了严重影响。如果该共享资源的使用者全部是任务( 即不包含 ISR),可采用互斥信号量的方法来访问。

但使用信号量存在一定风险,可能出现优先级反转现象(优先级反转是指一个低优先级的任务持有一个高优先级任务所需要的共享资源,高优先任务必须等到低优先级任务释放资源才能访问。如果此时有个优先级处于两者之间的任务,并且不需要那个共享资源,则该中优先级的任务实际运行效果优先级最高。如果高优先级任务等待资源时不是阻塞等待,而是循环忙检测,则低优先级任务无法执行,一直占用共享资源,造成的后果就是高优先级任务无法获得资源一直处于等待状态,系统进入假死状态)。

解决方案有两种,设置优先级上限,给临界区一个高优先级,进入临界区的任务都将获得这个高优先级,其他试图进入临界区的任务的优先级都低于这个高优先级,也就不存在优先级反转;另一个方案是优先级继承,当一个高优先级任务等待一个低优先级任务持有的资源时,低优先级任务将暂时获得高优先级进程的优先级别,在释放共享资源后,低优先级任务回到原来的优先级别。这块不需要应用程序关注或实现,因为RTOS自带的互斥信号量(mutex)具有处理优先级反转的功能,特别适合对共享资源的互斥访问。

互斥信号量与用于行为同步的二值信号量不同,互斥信号量的初始值为 1(unlock),表示共享资源有效( 尚未被使用),一个任务需要访问某共享资源时,首先获取该共享资源对应的互斥信号量(lock),如果已经被其它任务占用则等待;若获取成功,则说明该共享资源尚未被其他任务占用,就可以对该共享资源进行使用,使用结束后必须及时发送互斥信号量,解除对该共享资源的占用,以便供其他任务使用。可以类比于进公厕,必须确保门未锁,进入后立刻锁门,事毕出来再开锁,其他人才可再进入使用。

使用互斥信号量访问共享资源时,对中断和任务调度没有限制,系统可以正常响应各种异步事件,其他与该共享资源无关的高优先级任务仍然可以及时运行( 即使任务正在运行关键段落代码),因此,使用互斥信号量进行共享资源访问对系统实时性影响最小。

在使用互斥信号量进行资源同步时,任何任务一旦获得共享资源就可以一直使用到不需要为止,其他任务优先级再高也不能夺去使用权。其原因是获得共享资源的任务具有临时的高优先级(优先级继承值),其他需要访问同一个共享资源的任务均达不到这样高的优先级。优先级继承值必须高于所有需要访问这个共享资源的任务的优先级。

需要注意的是,优先级继承值不能与其他任务的优先级相冋,必须使用一个空闲的、高于全部使用该共享资源的任务的优先级值,初始定义优先级时不要将任务的优先级安排得太紧密,中间留些间隔较好。


使用特权

评论回复
56
黑心单片机|  楼主 | 2022-5-1 14:14 | 只看该作者
6.4 使用计数信号量

当同一类型共享资源有多个实体,就允许多个任务同时使用这类共享资源,但每个任务所使用的共享资源实体是不同的,即对每一个实体的使用仍然是互斥的。

在嵌入式应用系统中,多个实体,比如多路ADC,多路UART,其实对应不同的硬件资源,并不是完全相同的,不能随意选择性使用,也就是感觉计数信号量管理多实体共享资源没有实际意义,对于多路ADC或UART,一般是使用多个互斥信号量或者二值信号量各自管理其中一路


使用特权

评论回复
57
黑心单片机|  楼主 | 2022-5-1 14:15 | 只看该作者
7、数据通信

系统运行过程中,ISR与任务之间、 任务与任务之间必然伴随数据通信,可根据实际情况来选择最合适的通信方式。


使用特权

评论回复
58
黑心单片机|  楼主 | 2022-5-1 14:16 | 只看该作者
7.1 全局变量

全局变量(包括全局数组和全局结构体)可以充当一种共享资源,用来在任务之间传输数据,提供数据的任务或ISR对全局变量进行写操作,使用数据的任务或ISR对全局变量进行读操作,从而实现了数据的的传输。这种情况下全局变量作为共享资源,对其进行的访问必须遵循资源同步的规则。

全局变量虽然可以实现数据传输,但不能实现行为同步,即新的数据产生之后并不能自动通知相关使用者,使用者也不知道当前数据是何时更新的,因此,全局变鼂只能用于没有行为同步要求的任务之间,即每次产生的新数据不要求立即使用,甚至可以不被使用。

在没有行为同步要求的前提下,且传输的数据量不大,采用全局变量并配合关中断的资源同步措施是一种最有效的方法。

也有种特殊情况,当对共享资源进行写操作的任务只有一个,且其优先级高于所有其他进 行读操作的任务,可以在进行写操作时不必关中断,因为低优先级执行读操作任务不可能获取运行权,而低优先级执行读操作任务必须使用关中断措施来访问全局变量。


使用特权

评论回复
59
黑心单片机|  楼主 | 2022-5-1 14:16 | 只看该作者
7.2 内存数据块

若需要传输的数据量很大时,采用内存块来存放数据是最合适的选择,也就是内存动态管理函数,操作系统一般会适配动态内存申请、释放的接口,且支持重入。

如果申请的内存空间地址指针作为全局变量,其用法和全局变量一样,必须遵循资源同步的规则。实际它少独立使用,一般情况下是用于消息队列通信方式的内容缓冲区,将申请的内存块地址作为临时变量,作为消息内容的参数传输。


使用特权

评论回复
60
黑心单片机|  楼主 | 2022-5-1 17:12 | 只看该作者
7.3 消息邮箱

当发送的数据要求接收方及时接收和处理,在数据通信的同时发生行为同步,当通信双方的执行均具有周期性(且周期相同)时,消息邮箱是合适的通信工具。(前提是RTOS支持邮箱,且不带缓存,一次只能发送一条)。

使用消息邮箱发送消息时,实际上只发送指针( 消息的地址〉,不管消息本身的数据类型,发送的指针都按 void *处理,接收方得到这个消息指针后,将指针强制类型转换获取真正的消息内容。

邮箱内容可以直接发送常量(或者数据强制转为指针类型,因为变量100和指针100,本质都是100这个数字)。如果发送的是变量的地址,务必确保变量本身不会销毁,一般是全局变量或者静态局部变量的地址。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则