FreeRTOS--范例工程文件

这个文档描述标准的RTOS范例工程中各文件的功能。涉及的文件位于Demo/Common/Full目录中,Demo/Common/Minamal目录中的文件具有相似功能 ,只是使用的RAM更少并且不包含任何控制台IO。

 


blockQ.c

创建6个任务,用于对3个队列进行如下操作:

前两个任务发送(接收)一个递增的数字到(从)一个队列。一个任务作为生产者而另一个作为消费者。消费者拥有更高的优先级,并且读队列是挂起。队列只有一个条目的空间——一旦生产者向队列发送一个消息,消费者将从挂起状态恢复,抢占生产者,并且删除条目。

还有两个任务以相反的方向工作。这个队列也是只有放下一个条目的空间。这一次生产者比消费者有更高的优先级。生产者尝试发送条目到队列,当队列满时会挂起。当消费者唤醒时,它会从队列移除条目,这将导致生产者从挂起恢复,抢占消费者,并且立刻重新填满队列。

最后两个任务使用相同的队列生产者与消费者函数。这一次队列有足够的空间用于存放大量条目并且任务运行于相同的优先级。生产者将运行,向队列放置条目。消费者将在队列满(导致生产者挂起)或上下文切换发生(同优先级的任务会用时间片调度)。

 


comtest.c

创建两个任务用于操作一个中断驱动的串口。要使用一个环形链接器来保证任何发送出去的数据会被接收。此串口没有使用任何流控制。在一个标准的9针串口连接座中2脚与3脚应该连起来。

第一个任务将重复向队列发送字符串,每次一个字符。串口中断将清空队列并且发送字符。任务在每次重发字符串前会挂起一个伪随机的时间。

第二个任务在请求队列时挂起来等待一个字符接收的到来。字符被串口中断服务程序接收并且发送到队列——使任务从挂起恢复到就绪状态。如果是这样则最高优先级的就绪任务将立刻运行——在中断服务程序的最后进行上下文切换。接收字符的任务被赋予一个比发送者更高的优先级。

通过适当的环形连接,一个任务发送的字符串将会立刻被另一个任务接收。因为接收的任务知道将收到的是什么字符串,所以可以发现错误。

这里同时创建了第三个任务,用于测试在中断服务程序中使用信号量而不做其他的事情。

 


crflash.c

这个范例程序示范了使用队列来进行联合程序间数据传递,还示范了联合程序索引参量的使用。

创建N个‘预定延时’的联合程序以一个预定的 的优先级阻塞然后发送一个数量的LED到一个队列。每个这种联合程序使用其索引参数作为数组的索引,用于LED闪烁的时间。另一个已创建的独立的‘闪烁’联合程序会在同一个队列上阻塞,等待其为下一个LED闪烁的编号。在接收到编号后它会简单的闪烁指示LED然后在同一队列上再次挂起。这样,从LED0到LED N-1的LED会以一个不同的速度闪烁。

‘预定延时’的联合程序创建为联合程序优先级0,而闪烁联合程序为优先级1.这意味着队列永远也不会包含多余1个条目。因为发送到队列会是有更高优先级的‘闪烁’联合程序从挂起恢复,只有当队列为空时才会再次阻塞。如果尝试向队列发送数据失败会指示一个错误——指示队列已经满。

 


crhook.c

这个范例示范了如何在中断服务程序与联合程序见发送数据。一个时间滴答钩子函数用于定时的在RTOS时间片与一定数量的‘钩子’联合程序见发送数据。

将创建hookNUM_HOOK_CO_ROUTINES个联合程序,每个联合程序均挂起等待在中断服务程序中从队列接收一个字符,检验保证接收到的为预料中的字符,然后把编号从另外一个队列发回中断服务程序。

时间片中断程序检查从‘钩子’联合程序接收到的编号是否与先前发送的吻合。

无论在任何时候队列函数返回一个非期望的值,或者时间片钩子或联合程序接收到一个错误的数据,都会产生一个错误。

这个例子依赖于在每个hookTICK_CALLS_BEFORE_POST时间片中断间运行的‘钩子’联合程序。这样繁复的在中断服务程序中使用队列可能会导致在一个低速的目标上由于时间问题而检测到有错误发生。

 


death.c

创建一个固定的任务用于周期性的动态创建另外4个任务。前面的任务称为创建者任务,新建的4个任务称为自杀任务。

新创建的自杀任务中的两个会各自杀掉一个自杀任务然后自杀——只留下最初的一个任务。

创建者任务会一直检查正在受调度控制的任务数量,并且会再次创建其他的范例任务。正常情况下创建者任务所期望的正在运行的任务数量永远不会比其创建任务时的数量加上4要多,否则就会标识出一个错误。

 


dynamic.c

第一个测试首先创建3个任务——两个计数任务(一个连续计数,一个受限计数)与一个控制任务。三个任务间共享一个“计数”。两个计数任务不会在同一时间处于“就绪”状态。控制任务与连续计数任务运行于同一优先级,并且比受限的计数任务优先级低。

其中一个计数任务不定时的循环,在每次循环中增加共享计数变量的值。为了可以独占的访问变量,它会在增加变量前把自身的优先级提升到比控制任务高,访问完后再恢复到原来的优先级,然后进行下一次循环。

另一个计数任务会在每次循环中增加共享计数变量的值,直到变量增加到0xff——此时它会挂起自身。直到控制任务通过调用vTaskResume ()再次将其置为“就绪”状态,才会开始新的循环。这个计数任务比控制任务有更高的优先级,因此不用担心访问计数变量的互斥问题。

控制任务由两部分组成。第一部分控制与监控连续计数任务,当此部分工作时,受限的计数任务是暂停的。同样地,第二部分控制和监控受限的计数任务,当此部分工作时连续计数任务暂停。

控制任务的第一部分首先会复制共享计数变量 。为了独占的访问计数变量,控制任务会先挂起连续计数任务,复制完变量后再将其恢复。然后控制任务休眠一个固定的时间,期间连续计数任务会运行并且增加共享变量的值。控制任务从睡眠中唤醒后会通过对比计数变量此时的值与先前保存的值来检查连续计数任务的运行。此时,为了保证互斥,调用vTaskSuspendAll ()来挂起调度器。这只是作为演示用途,并不是一个推荐的方法,因为这样没有效率。

在一个预定数量的循环后,控制任务挂起连续计数任务,进入第二部分。

在第二部分的开头共享变量被清零。通过调用vTaskResume (),受限的计数任务从挂起唤醒。因为这个计数任务运行与一个比控制任务更高的优先级,因此控制任务在共享变量增加到受限值、计数任务自己挂起前不会运行。因此在调用vTaskResume ()后就检查共享变量来保证一切都在按照预期的方式运行。

第二个测试有一些简单的任务组成,它们会在调度器挂起时发送数据到队列。增加这个测试是为了弥补第一个测试没有做到的调度器部分的训练。

 


flash.c

创建8个任务,每个任务以不同的频率闪亮一个LED。第一个LED每125ms闪亮,第二个每250ms闪亮,第三个375ms,如此类推。

LED的闪烁提供一个可是的反馈,显示调度器依然在运转。

PC平台使用标准的并口来输出。Flashlite 186平台使用IO端口F。

 


flop.c

创建8个任务,每一个不断循环进行(模拟)浮点数运算。

所有任务都运行于idle任务的优先级并且不会阻塞或让出处理器。这使得八个任务与idle任务一起进行时间片调度。运行于idle优先级意味着任务会在任何其他任务就绪或时间片到时被抢占。更常见的是在计算的中途被抢占,这样可以对调度器上下文切换进行很好的测试——如果某个计算产生一个意料之外的结果就意味着某个任务的上下文切换出现问题。

 


integer.c

与flop.c类似,只不过使用的变量是长整型而不是浮点数。

与flop.c类似,这个文件中创建的任务可以对调度器的上下文切换机制进行很好的测试。处理器通过两或四次操作来对一个32位的变量进行访问(依赖于所用的处理器)。这些任务的优先级低,意味着很有可能会在计算的中途发生上下文切换。参考flop.c的文档获取更多的信息。

 


pollQ.c

这是一个很简单的队列测试,更复杂的版本可以参考BlockQ.c。

创建两个任务,使用单个队列进行通讯。其中一个任务为生产者,另一个为消费者。

生产者循环运行3次,每次循环发送一个递增的数据到队列。然后延时一个预定的时间再继续进行上述的操作。

消费者循环运行,清空队列。它会检查每个从队列中清除的条目,以保证包含的是一个预期的值。当队列为空的时候,它会挂起一个预定的时间,然后再按照上述的方式运行。

所有的队列访问都是无阻塞的进行。消费者每次运行都会完全清空队列,所以生产者永远也不会发现队列为满。

如果消费者得到一个非预期的值或者生产者发现队列为满,一个错误会标识出来。

 


print.c

管理一个等待显示的字符串队列,这用于控制台输出时的互斥。

如果一个任务希望显示一个消息它会调用vPrintDisplayMessage (),使用一个字符串指针作为参数。这个指针会发送到xPrintQueue队列。

main.c中的任务会在xPrintQueue上阻塞。当一个消息可用会调用pcPrintGetNextMessage ()来获取下一个字符串的指针,然后使用硬件层FileIO.c 文件中定义的函数来发送信息。

注意: 使用控制台IO会破坏实时性——取决于各个平台。标准的C IO程序并不是为实时应用而设计。然而标准IO在示范与调试时十分有用,因此如果你需要在你的应用中使用控制台IO,应该选用一种替代的方式。

 


semtest.c

创建两组任务,每组内部的任务共享一个变量,通过一个信号量来监控其访问。

每个任务以尝试获取信号量来开始。获取到信号量的任务会检查变量是否是一个预期中的值,然后把变量清零,接着每次把变量递增1,直到其初始值。在每次递增后任务会检查变量是否为刚刚设定的值。当变量值达到初始值时任务会释放信号量使得其他任务有机会来进行同样的事情。初始值必须足够大,使得时间片中断可能在变量增加的循环中发生。

如果在处理的过程中发现共享的变量包含的不是预期中的值,一个错误会标识出来。这表明在访问受限的变量时互斥机制发生错误。

两组任务中的第一组以轮询的方式访问信号量,第二组用阻塞的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值