第3章第4节 使用Wanlix编写交通红…
来源:互联网 发布:top域名有什么用 编辑:程序博客网 时间:2024/06/06 10:07
目前更新到5.3节,请在http://dl.dbank.com/c02ackpwp6下载5.3节的全部文档
本节源代码请在http://dl.dbank.com/c0sw8nca9k下载
第4节 使用Wanlix编写交通红绿灯控制系统
至此我们已经实现了一个非常简单、小巧的操作系统——Wanlix,简单到它只具备任务切换这一项任务管理功能,而且需要用户自己主动切换,实时性较差。但无论如何,它确实是实现了任务的切换,这是不争的事实,从前面打印的例子就可以证明。
本节我们将使用Wanlix开发一个交通红绿灯的控制程序,通过这个稍微复杂点的程序来应用Wanlix操作系统。
首先,先来了解一下这个交通红绿灯的功能,然后再设计软件结构、编码,最后在单板上运行,观察结果,展示使用Wanlix操作系统开发的第一个嵌入式系统。
功能说明:
图
图20是我们这节所要编写的交通红绿灯控制系统的应用场景,左右方向是主干道,上下方向是从干道,主干道行驶机动车辆,从干道为行人斑马线。主干道上的车多,通行时间长,从干道行人少,通行时间短,主从干道交替通行。顺着前进的方向看,主干道上的3个灯分别是红黄绿,从干道上的2个灯分别是红绿。上下的两个方块是行人横跨主干道时的应急按钮,当行人按下应急按钮时,无论主干道处于什么状态,主干道都会变为停止通行状态,从干道变为通行状态,行人可以从从干道通行,过一会主从干道又恢复为正常的交替通行状态。
表3描述了上述十字路口各个灯的状态运行情况:
主干道红灯
主干道黄灯
主干道绿灯
从干道红灯
从干道绿灯
状态1:主干道通行,从干道停止,30秒。
灭
灭
亮
亮
灭
状态2:主干道将停,从干道将通行,5秒。
灭
亮
灭
亮
灭
状态3:主干道停止,从干道通行,10秒。
亮
灭
灭
灭
亮
状态4:主干道将通行,从干道将停,5秒。
亮
灭
灭
灭
闪烁
表
状态1持续30秒,主干道绿灯亮,从干道红灯亮,指示主干道通行从干道停止;此后转换为状态2持续5秒,主干道黄灯亮,从干道红灯亮,指示主干道将停止,从干道将通行;此后转换为状态3持续10秒,主干道红灯亮,从干道绿灯亮,指示主干道停止从干道通行;此后转换为状态4持续5秒,主干道红灯亮,从干道绿灯闪烁,指示主干道将通行,从干道将停止;此后再转换到状态1,如此周而复始的运行。
另外,当行人按下应急按钮时,无论当前处于什么状态都会转换为从干道通行状态,此后仍按上述4个状态循环运行。
图
软件设计:
在任务设计上,需要尽可能做到任务间的耦合性小,任务之间仅通过少量的接口传递消息。在这个交通灯系统中,我们可以将其功能拆分成2任务,任务1用来控制十字路口的状态,并根据十字路口的状态改变各个灯的状态,任务2用来将各个灯的状态输出到灯上,这样分解的两个任务之间的耦合性小,当我们修改方案,需要改变十字路口各个灯的控制策略时,只需要修改任务1的代码,任务2几乎不受影响,这点在后面的例子中可以看到。
当行人按下应急按钮时会触发中断,在中断里面改变十字路口的状态,退出中断后,任务1会根据十字路口的状态重新更新各个灯的状态,任务2又会将灯的状态输出到灯上,这样就可以完成这个十字路口的软件功能了。
当然,也可以有其它的任务设计方式,但不管如何设计,必须要遵守的是:各个任务之间层次分明,耦合性要小,避免多个任务互相干扰。最差劲的设计是几个任务互相影响,比如一个任务控制主干道的灯,另一个任务控制从干道的灯,每个任务不仅要考虑到自己如何运行,还要考虑与另外一个任务的配合,当任务多的时候,这种配合将变的非常复杂,错误百出,即使功能实现了,这对于以后的维护、功能修改、扩展也将是巨大的考验。
在这个软件系统里,难点在于控制各个灯的状态变化。在所有的十字路口状态中,灯有亮、灭、闪烁3种状态,每种十字路口状态中每个灯有不同的持续时间,为此,我们可以用一个结构体来表示灯的这些状态:
typedef
{
}CROSSSTATESTR;
其中uiRunTime是该状态运行的时间,LEDSTATE结构体是每个灯的状态结构体,LEDNUM是灯的数量,为每个灯定义一个状态变量。
LEDSTATE结构体为:
typedef
{
}LEDSTATE;
uiLedState表示灯的状态,是亮、灭还是闪烁状态,uiBrightness表示当灯处于闪烁状态时当前的亮度,是亮还是灭。
使用上面的这2个结构体就可以表示十字路口的一个状态。使用该结构体,我们定义一个十字路口的当前运行状态:
CROSSSTATESTR
当十字路口状态发生变化时,需要重新获取新状态的各个参数,为此,我们再定义一个结构体数组用来存放十字路口的各个状态初始值:
CROSSSTATESTR
其中CROSSSTATENUM是十字路口状态的数量,这样变量gastrCrossSta中包含了所有灯的所有状态,CROSSINITVALUE是变量gastrCrossSta的初始值,包含了表3中各个灯的所有状态,当程序运行时,各个灯的初始状态就全部被放到了gastrCrossSta变量中。
任务1运行时,若发现当前运行状态变量gstrCurCrossSta中的状态时间参数uiRunTime耗尽,gstrCurCrossSta变量则从gastrCrossSta变量中获取下个状态的初始值,根据图21的状态切换关系改变状态,任务2再将灯的状态输出到灯上,如此循环。
在这个软件系统里,需要根据时间来改变各个灯的状态,我们可以使用硬件定时器每隔100ms产生一次中断,这个中断时间叫做tick,是软件系统的时间单位,由软件在每个tick中断里对时间变量累计,这样在程序里对只要对时间变量进行判断就可以确定时间了。
图
图
大家也可以到网站上去下载视频观看,可以看到各个灯按照我们的设计循环亮灭,当行人按下应急按钮时,可以中断主通道的通行,让行人先过马路,可以看到这个小系统实现了我们设计的要求。
最后,我们来做个小改动,在状态1和状态2之间增加一个状态:主干道绿灯闪烁,从干道红灯亮,用来表示主干道通行状态将要结束,姑且称之为状态11,来看增加状态11后的表4:
主干道红灯
主干道黄灯
主干道绿灯
从干道红灯
从干道绿灯
状态1:主干道通行,从干道停止,30秒。
灭
灭
亮
亮
灭
状态11:主干道通行,从干道停止,5秒。
灭
灭
闪烁
亮
灭
状态2:主干道将停,从干道将通行,5秒。
灭
亮
灭
亮
灭
状态3:主干道停止,从干道通行,10秒。
亮
灭
灭
灭
亮
状态4:主干道将通行,从干道将停,5秒。
亮
灭
灭
灭
闪烁
表
增加了状态11,我们在原有代码上需要做如下修改:
1.在CROSSSTATENUM枚举变量中增加一个新状态11。
2.在CROSSINITVALUE宏定义中增加表4中状态11的初始值。
3.在行人中断函数ISR_PassengerIsr里增加对状态11的处理。
可以看到在这个软件结构上只要做很少的代码改动就增加这个新功能。大家切记,编码只是软件中的一部分工作,软件编码前的设计也非常重要!
- 第3章第4节 使用Wanlix编写交通红…
- 第3章第5节 发布Wanlix操作系统
- 第3章 Wanlix操作系统
- 第2章第4节 Wanlix的文件组织结构
- 第2章第5节 Wanlix的开发环境
- 红帽 LINUX 6自学笔记第…
- 第4章第3节 实时事件触发的实时抢…
- 第4章第3节 实时事件触发的实时抢…
- 第4章第3节 实时事件触发的实时抢…
- 第4章第6节 任务自结束
- 第13周-交通类(3)
- Dive into python 第4章 自省的威…
- 第3章第3节 用户代码入口——根任务…
- 第4章第2节 定时器触发的实时抢占…
- 第4章第2节 定时器触发的实时抢占…
- 第4章第5节 任务创建和任务删除钩…
- 第2章第3节 ARM7芯片的函数调用标…
- 第3章第1节 两个固定任务之间的切…
- 第3章第1节 两个固定任务之间的切…
- spring mvc(注解)上传文件的简单例子
- 第3章第2节 任意任务间的切换
- 第3章第3节 用户代码入口——根任务…
- 我的学习之路_第二十二章_事务
- 第3章第4节 使用Wanlix编写交通红…
- Makefile编写及一个简单的Makefile架构实现
- 第3章第5节 发布Wanlix操作系统
- 第4章 Mindows操作系统
- 第4章第1节 Mindows的文件组织结构
- 第4章第2节 定时器触发的实时抢占…
- 第4章第2节 定时器触发的实时抢占…
- 第4章第3节 实时事件触发的实时抢…
- 第4章第3节 实时事件触发的实时抢…