Linux 在嵌入式系统中的应用

作者:Dave Pfaltzgraff

我在一家公司工作,该公司从事定制电路的设计和制造。 从历史上看,我们设计印刷电路板和盒子,这些电路板和盒子由我们的客户进一步集成到他们的系统中。 直到最近,我们还很少参与通常称为系统设计和集成的工作。 然而,时代在变化,随着我们扩大客户群,我们已经适应了这些需求。 大多数时候,我们已经能够使用 DOS,在某些情况下使用 Windows 来满足眼前的需求。 今年,我们开始使用 Windows 98,以便能够使用一些较新的视频功能,并且在一种情况下,Linux 介入以快速解决网络连接问题。 本文简要描述了一个项目,该项目提供了更多参与 Linux 和这个新操作系统的功能的机会。

问题描述

最近,一位从事零售业务并且通常自己进行系统集成的客户,要求我们考虑设计一个门禁系统来替换他们现有的系统。 这主要有两个原因。 其中之一是成本。 他们认为,通过设计一个专门满足他们要求的系统,生产成本将低于要求定制市场上已有的产品。 第二个原因对他们来说更为重要。 他们希望能够扩展这个新系统,并添加与其他整体门店系统部分的接口。 门店系统包括他们的销售点 (POS) 控制器和到安全视频系统的链接。 系统设计的这些方面将在稍后更详细地讨论。

需要满足的基本要求是

  • 通过使用信用卡式钥匙来控制进入某个区域。

  • 如果用户没有钥匙,他们可以手动输入号码。

  • 可以通过 POS 系统自动添加或删除员工,也可以由商店经理手动添加或删除。

  • 根据钥匙和所涉及区域的类型来授予或拒绝访问某个区域的权限。

  • 可以在现场轻松更改系统配置。

  • 如果任何区域在没有有效钥匙的情况下被访问,则应发出警报。

  • 警报可以由经理重置,或者可选地,由任何有效的钥匙重置。

  • 警报条件将发送到安全视频系统。

  • 经理将能够覆盖系统并允许门在较长时间内保持打开状态。

  • 必须具备查询系统并根据区域、时间和/或员工检查活动的功能。

尽管这些要求相当基本,但有三件事很突出。 首先,他们希望访问数据库的更新来自 POS 系统。 然而,这仍然是“未来”的事情。 因此,第二点是更新需要在本地进行,这需要一个直观的界面。 最后,安全视频系统的设计也在同时进行,因此与该系统的链接也将是未来的事情。 除了有这么多点仍然是未来的事情之外,这在我们做过的许多项目中是很典型的。 另一个不同之处是我们将交付一个完整的系统,而不仅仅是零件。

实施

由于商店环境的分布式特性,决定使用 EIA RS-422 类型的接口将系统分布在整个商店中。 基本想法是从中央 PC 引出几条串行线,连接到每条串行线上的多个门禁模块。 每个门禁模块将控制最多四个读卡器(或门),见图 1。 选择四个读卡器是基于门的典型邻近性和读卡器、螺线管和警报所需的布线量。 由于我们过去设计过读卡器和其他数据输入类型的设备,因此决定将读卡器实现为壁挂式面板,并由 8051 型设备控制。 来自键盘或刷卡的任何输入都将被缓冲,并在轮询时发送到门禁模块。 门禁模块稍后会在轮询时将其转发到中央 PC。 系统的设计允许每个串行链路最多连接十个门禁模块,或者每个串行链路最多连接 40 扇门。

The Use of Linux in an Embedded System

图 1。

当项目开始时,感觉我们将使用 Windows 95/98 作为操作系统。 考虑到除了必要的通信之外,它还可以通过使用 Microsoft Access 和直观的用户界面来提供数据库服务,这很自然。 然而,随着硬件设计的进展,编程资源在可接受的时间范围内不可用变得显而易见。 当需要为这项工作分配资源时,我正在从另一项工作中收尾,并被问到我将如何处理用户界面的设计。 由于不太熟悉 Windows 编程,但对浏览器界面有一些接触,我询问是否适合切换到 Linux 并通过使用 Apache 和合适的浏览器来提供用户界面。 设计团队立即接受了这个想法,并将其提交给客户。 当指出这种实现不需要用户在设备旁操作时(设备通常挤在壁橱里),客户回应说:“真棒。” 当被问及他们是否反对在 Linux 上实现它时,他们的回答是:“酷。” 这样,我就开始了我的工作。

投身开源范式

在实际投入这个程序之前,需要考虑使用 Linux 的几个方面。 随着 Linux 努力进入主流,许多公司一直在与这些问题作斗争。 对我们来说最重要的是开发资源是否可供我们使用。 在之前的项目中使用过 GNU 实用程序,即 gccgdb,我觉得开发主程序不会有问题。 下一个问题是允许通过用户浏览器提供数据库接口所需的支持。 同样,一点研究表明,不仅支持到位,而且还有很多选择。 有人问我的一个问题是我们将如何处理内核开发的持续变化。 很快就意识到没有必要不断升级这些系统只是为了保持最新。 我们所需要的只是一个可行的版本,可以在整个产品中传播。 由于源代码是可用的,如果内核朝着与我们的系统不兼容的方向发展,我们也不会被遗弃,背上沉重的负担。

实现串行接口和控制程序

似乎在任何系统中为串行线编程都是一项挑战,没有什么容易的。 对于这个项目来说尤其如此,因为我对 UNIX 环境的经验很少,并且必须处理多达八个串行端口。 由于之前的经验,设计团队已经选择了 Digi International 八端口 422 卡。 我的首要任务是设置它以在 Linux 下运行。 我感觉自己像是在黑暗中摸索,并寻找任何形式的确认,证明我做的事情是正确的。 我尝试使用带有环回插头的 minicom 只是为了看看它是否有效。 如果它有效,这里就不会提到它了,但它没有,我花了很多时间审查我所做的事情。 最后,我打电话给 Digi International 支持人员。 当然,他们让我尝试所有常用的方法,我愿意听取他们的意见,以防我忽略了什么。 长话短说,经过几个周期的电子邮件往来,他们的一位二线支持人员接受了我的困境。 在与他合作的过程中,我确实学到了很多关于 Linux 内部运作的知识,仅仅为了这一点就值得花时间。 最后,我们发现问题出在我拥有的驱动程序版本中; 事实上,它没有编写来支持 422 卡。 简单地更改一下,它就开始工作了。 这一经历向我证明,Linux 确实是一个受支持的系统。

现在所有硬件都已到位,我的工作是让它工作起来。 我很困惑如何处理多达八个串行接口,所以我做了一些阅读。 这包括适当的 HOWTO 和我可以获得的任何书籍。 幸运的是,其中一本是 Neil Matthew 和 Richard Stones 于 1996 年 Wrox 出版的 Beginning Linux Programming。 在书中,他们开发了一个使用 FIFO 在任务之间进行通信的出色示例。 我采用了他们的示例并进行了扩展,以便每个串行接口都有自己的任务,并且所有任务都通过 FIFO 与中央控制任务进行通信。 要了解各个任务之间的关系,请参见图 2。 事实证明,这是一个极好的选择,原因有二。 首先是中央控制任务可以为每个串行链路生成一个任务。 如果应用程序只需要一个串行链路,则只生成一个任务,依此类推。 第二个原因是串行任务可以执行所有轮询、错误检查和重传,而无需控制任务以任何方式参与。 这使得控制任务变得简单得多,因为它只处理需要操作的有效消息。

The Use of Linux in an Embedded System

图 2。

我过去在编程串行链路时遇到的一个问题是,除非你能掌握中断机制,否则系统会花费大量时间空转,等待某些事情发生。 在 Linux 系统中,我能够使用 select 调用来允许每个任务进入空闲状态,直到需要做某些事情。 这发生在控制任务等待来自其中一个读卡器的消息到达时。 select 调用的超时功能也用于触发后台任务。 如果在十秒钟内没有收到来自任何读卡器的消息,则子任务将执行后台内务处理。 串行任务中也会发生这种情况。 在这种情况下,select 设置为在收到来自读卡器或控制任务的消息时唤醒。 同样,使用了超时功能,但这次它表明其中一个门禁模块未能响应,这表明存在硬件问题。

有了这些基本知识,其余程序的开发进展非常迅速。 我想指出的是,Linux 的多任务处理能力和 gdb 的功能在这个阶段发挥了作用。 由于串行任务是由控制任务生成的,因此没有连接屏幕,因此在开发阶段无法打印通常的诊断消息。 我做的第一件事是学习如何使用 syslogd 来报告这些任务中的错误情况。 其次,我使用了 gdb 的功能来连接到已经运行的任务并对其进行调试。

控制程序与数据库之间的接口

这是我们有足够的经验以至于变得危险的领域之一。 我们知道它可以完成,这是一个潜在的热点。 在评估各种数据库软件包时,我们查看了许可条款以及对嵌入式和 Web 应用程序的支持的可用性。 似乎许多可用于 Linux 的数据库都满足了最后两个要求。 许可方面变化更大,因为几个更知名的软件包提供了免费的单用户或非商业用途。 由于我们将在许多系统上安装它并用于商业目的,因此许可是一个我们不想忽视的问题。 当我们深入研究时,我们发现一些许可费高于 MS Access 的通行费率。 仅此一项就排除了一些选择。 我们最终决定使用 PostgreSQL。 除了非常宽松的版权之外,高质量文档的可用性也强烈影响了我们。 有机会在甚至承诺下载代码之前查看手册就足以让我们确信这是一条正确的道路。

一旦选择了数据库,我们就必须深入研究实现的细节。 第一部分是定义模式。 之前有过一些 SQL 经验,我发现 psql 很容易适应。 知道模式可能会随着项目的演进而改变,我编写了一些脚本来定义所有表并填充默认值。 这解决了设置数据库的问题。 下一步是定义到控制程序的接口。 基于数据库模式会改变的相同前提,我将接口设置为一个单独的模块,其中包含将选定数据读入工作缓冲区的子例程。 除了日志表之外,所有表对于此功能都是只读的。 因此,有一个子例程可以从每个表中读取选定的记录。 这种方法的唯一例外是,当系统首次启动时,需要一种方法来确定实际实现了多少扇门。 这仅仅需要一组子例程,这些子例程将打开表,在每次调用时返回表中的下一个条目,然后关闭表。 这允许程序扫描所有可能的条目以设置通信链路和其他结构。 我需要的所有功能都由发行版中包含的 lilbpq 库提供。 事实证明它比我最初预期的要容易。

数据库与用户界面之间的接口

由于涉及的软件包数量众多,因此该项目这一方面有点复杂。 如果您还记得一开始,想法是使用 Web 浏览器作为用户界面。 这意味着我们需要在链接的末端提供一个 Web 服务器。 对于 Linux 中的任何人来说,Apache 的选择都是不费吹灰之力的。 然而,我们需要以某种方式将其链接到我们的数据库。 由于 Perl 专业知识的可用性,我们选择走这条路。 为了提供完整的软件包,我们还需要包含其他模块。 对于到数据库的接口,我们添加了 ApacheDBI、Postgres 的 DBD 和 Perl DBI 软件包。 为了支持我们在 Apache 中需要的所有内容,我们添加了 Digest、HTML-Parser、MIME-Base64、URI、Apache-SSI、libnet、libwww-perl 和 mod-perl。 软件包的组合非常复杂,但当正确安装后,一切都运行良好。

用户界面的设计分为两个主要部分。 第一部分是一组例程,用于格式化数据以在用户的屏幕上显示。 第二部分是接受用户输入并处理它的主例程。 通常,该处理包括更新数据库并将控制权传递给适当的例程,以便为用户显示一组新数据。 最重要的是,在浏览器级别使用了 Javascript,以便在将参数传递回主例程之前执行有效性检查。 由于浏览器和系统之间来回传递大量数据,我们使事情保持相当简单。 我们使用的唯一图形是标识徽标。

一般来说,允许用户从顶级菜单中选择特定的表。 选择表后,允许用户列出现有表、查找现有条目、修改条目,当然,还可以添加或删除条目。 由于各个表中的数据可能有些敏感,并且定义门的人员的需求与定义职位代码的人员的需求不同,因此我们在系统中添加了另一个表。 安全表与系统的正常运行无关,而是确定谁可以查看哪些表。 它运行良好,并且还为我们提供了一种仅允许某些用户访问系统的方法。

结论

在项目结束时要问自己的主要问题之一是:我们是否应该以不同的方式来做? 尽管由于人们熟悉 Microsoft 环境,因此存在很大的遵循 Microsoft 流程的压力,但我不得不回答“不”。 我们安装的系统已经达到或超过了客户的所有期望。 linux 操作系统提供的设施使我们能够交付一个可靠且易于维护和升级的系统。 例如,cron 与 logrotate 实用程序结合使用,以确保日志文件不会填满所有磁盘空间。 然而,与此同时,我们可以轻松查看最近四周的数据。 类似地,PostgreSQL 提供了所有需要的数据库服务,并且通过一个快速脚本,可以删除陈旧的数据。 这些共同作用防止系统因文件臃肿而变得迟缓。 其他实用程序也发挥了作用,apcupsd 守护程序监视 ups 并确保在必要时有序关机。 作为附带好处,我们还获得了建筑物电力的日志。 将 mgetty 与 pppd 结合使用允许拨号登录以进行任何可能需要的维护。 到目前为止,对系统的所有更新都通过此路径处理,因为我们与站点之间的当前网络连接非常慢。

选择使用 apache 来提供 GUI 再好不过了。 当我们开始时,想法是允许网络上的任何浏览器获得访问权限,并允许从远程位置进行更新。 如上所述,网络连接速度很慢,因此这种情况在很大程度上没有发生。 此外,巧合的是,初始站点没有任何其他本地机器。 为了解决这种情况,X windows 系统投入使用,Netscape 浏览器在机器上使用。 定义了一个特殊的登录名,将用户置于 Netscape 中,并且在退出 X windows 时,用户将被注销。 安全性得到了保留,用户对此一无所知。

另一个要问的问题是:我们未来的方向可能在哪里? 第一步是提供一个串行链路,将活动报告给外部安全系统。 第二步是让系统数据库的更新从另一台机器完成。 最初的讨论集中在使用备用串行端口进行这些功能。 没问题! 在达到这一步的过程中,我们已经积累了所有串行编程的经验,可以准确地知道这两项任务都需要什么。 后来的讨论转向使用 TCP/IP 链路进行更新功能。 同样,linux 提供的网络环境也没有问题!

客户还询问我们是否可以建立一个中央监控设施,目的是能够报告硬件故障。 凭借网络功能(直接和拨号),提出一个中央单元可以轮询现场所有单元的系统相当简单。 或者,现场系统可以呼叫并报告其健康状况。 该系统甚至可以是这两种方法的混合体! 客户尚未对该提案做出回应,但看到不仅可以监控所有系统,而且所有程序更新也可以通过这种机制处理,这并不是一个很大的飞跃。

正如您可能从我的热情中看到的那样,我完全支持 linux! 我们遇到的最大障碍是人们已经习惯的熟悉环境。 我期望,随着时间的推移,linux 世界将会发生转变,并且将会对大众进行“教育”,并且对于此类项目,使用 linux 将变得更加自然。 为了预料到这种转变,该系统最近被移植到 Red Hat 6.0 版本。 通过对 Apache 进行一些小的调整,并重新编译我们的代码以使用新的库,过渡相当顺利。

The Use of Linux in an Embedded System
Dave Pfaltzgraff 是一名 Staff Engineer,从事嵌入式系统设计已有 20 多年。 他发现 Linux 的开放性是一种极大的乐趣,并喜欢分享“战争”故事。 可以通过 dpfaltzg@patapsco.com 与他联系。
加载 Disqus 评论