七、从这里去哪里

在前一章中,我们研究了安卓应用如何同时与 GPIO、I2C 和 SPI 接口,以提供完整的硬件接口解决方案。虽然你可能认为这涵盖了安卓系统下硬件接口的大部分问题,但仍有许多其他因素需要考虑。

在本章中,我们将涵盖以下主题:

  • 将您的解决方案集成到安卓系统中
  • 将您的硬件与其他硬件相结合
  • 探索 BBB 的其他接口

将您的解决方案与安卓系统集成

BBB 提供了各种各样的硬件功能,当您更改系统中使用的斗篷和覆盖时,您在项目中使用的特定功能会有所不同。虽然这在原型制作过程中为您提供了很大的灵活性,但您最终可能会将定制硬件设计最终确定为单一的静态配置,并决定将其作为基于安卓的永久解决方案。

本书中的示例做出了让应用直接访问 BBB 硬件的设计决策。虽然这种方法使创建硬件接口安卓应用变得简单,但它并不是一种理想的方法。一旦你有了你喜欢的硬件设计和与硬件正确接口的软件,是时候将你的解决方案与安卓完全集成了。根据您的硬件解决方案有多复杂,您最终可能会创建自定义内核设备驱动程序,甚至修改安卓操作系统框架内的管理器!

创建自定义内核和设备树

创建永久安卓解决方案的第一步是确保系统的 Linux 端一切正常。这意味着所有硬件支持(如您的项目所需的 Linux 内核驱动程序)都应该在内核中启用,并在内核的设备树中配置和分配(用于引脚复用和资源分配)。理想情况下,您需要的一切都将直接静态地构建到内核和设备树中。这消除了通过从init.{ro.hardware}.rc文件中执行的显式命令为您的解决方案加载覆盖和内核模块的需要。

我们对准备项目内核空间方面的建议是从 Linux 内部开发这些项目。Linux 环境为内核驱动程序开发和调试提供了更多的工具,您将能够快速轻松地构建独立的用户空间二进制文件,通过open()read()write()ioctl()函数调用与自定义和现有的内核驱动程序进行交互。Linux 用户空间二进制文件的代码编译测试调试周期可以非常快速地执行,因为在 Linux 下有完整的开发工具链,包括编译器和调试器。在安卓系统下,你必须在你的开发机器上使用安卓 NDK 构建这样的测试二进制文件,然后使用adb将它们推送到安卓系统进行测试。这使得开发周期更加缓慢和困难。

为您的解决方案开发静态设备树需要类似的过程。设备树及其覆盖是使用dtc工具编译的,该工具在 Linux 下可用,但在安卓下不可用。使用标准的 Linux 内核调试技术,您可以开发一个覆盖层并进行故障排除,该覆盖层为您的项目复用管脚,并为这些管脚分配必要的内核驱动程序。一旦您的覆盖正常工作,您可以将覆盖永久集成到设备树中。

类型

在哪里可以了解更多关于 BBB 的 Linux 开发?

网上有很多教程和资源可以帮助你学习如何为 BBB 开发 Linux 软件和设备树覆盖。我们可以向您推荐的最佳资源是德里克·莫洛伊创建的 BeagleBone 系列视频教程。这些教程涵盖了诸如 C/C++ 开发环境的设置和配置、调试、设备树覆盖创建和故障排除等主题。他们还有各种代码和电路示例来帮助您入门。你可以在德里克网站的“比格犬骨”部分观看这些教程,网址为http://derekmolloy.ie/beaglebone

在内核中加入硬件通信

虽然直接与 GPIOs 以及 I2C 和 SPI 总线接口很方便,但这并不是与硬件接口的最有效方式。第 4 章与 I2C 存储和检索数据中的 I2C·FRAM 示例使用 24c256 内核驱动程序来处理与 FRAM 芯片通信的低级细节。你能想象实现与 FRAM 芯片直接接口所需的每一个细节有多困难吗?除了必须知道 BBB 和 FRAM 芯片之间的通信协议的每一个细节之外,这样的协议还可能需要严格的时序保证,这在用户空间中是很难或不可能满足的。

在用户空间与硬件接口不可行的情况下,使用内核驱动程序是必要的。内核驱动程序封装了与特定硬件通信的细节。通过将这些细节保留在应用实现之外,这简化了您的接口应用。内核驱动在与硬件通信时也提供了严格得多的时序保证。这是因为内核对调度内核驱动程序通信事件以满足必要的截止日期有更深的理解。在用户空间中,如果内核的任务调度器决定给另一个进程一个执行的机会,那么一个进程可以在任何时候被挂起。即使用户空间进程优先级大大增加,与基于内核的活动的优先级相比,它仍然总是具有较低的调度优先级。

创建内核驱动程序可能相当复杂,这是一项远远超出本书范围的活动。但是,如果您发现自己在与硬件通信时试图满足非常严格的时间限制,您可能最终需要探索内核设备驱动程序开发的细节。

类型

在哪里可以了解更多关于开发内核驱动的知识?

开始学习内核驱动程序开发的最佳地方是由 Corbet,Rubini 和 Kroah-Hartman 所著的书 Linux 设备驱动程序。这本书提供了全面的指导,指导您完成开发过程。更好的是,这本书的第三版可以在http://lwn.net/Kernel/LDD3免费下载。第三版最初出版于 2005 年,所以有点过时,但书中提出的中心概念仍然有效。

融入现有管理者

第 5 章使用 SPI 与高速传感器接口中,您与基于 SPI 的温度和压力传感器接口。当您使用单个应用中的spidev内核驱动程序与传感器通信时,让管理器与传感器通信要干净得多。这样,所有应用都可以通过与管理器通信来请求访问传感器数据,而不必了解 SPI 通信的许多细节并在它们之间协调访问。它还限制哪些应用有权与spidev驱动程序交互。

事实上,安卓已经有了一个管理器Android.SensorManager,旨在与手机和平板电脑中常见的硬件传感器资源进行对话。应用通过请求管理器实例,然后请求代表特定类型传感器的对象来与管理器通信:

Private final SensorManager mSensorManager;
Private final Sensor mPressure;
Private final Sensor mTemperature;

Public SensorActivity() {
  mSensorManager =
   (SensorManager)getSystemService(SENSOR_SERVICE);mPressure = 
    mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
  mTemperature =
    mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE);
}

如果将SensorManager扩展为与您在第 5 章中使用 SPI 与高速传感器接口,您的应用只需几行 Java 代码就可以通过SensorManager与传感器通信!更好的是,spidev设备的文件系统权限不必设置为如此不安全的状态,应用就可以与传感器通信。不幸的是,将新的硬件功能集成到现有的管理器中非常困难,原因如下:

  • 您必须重建适当的安卓部分,这通常需要您至少构建一次完整的安卓源代码库。对于没有经验的人来说,这是一个耗时的过程(而且常常相当混乱)。安卓开源项目在https://source.android.com/source提供了如何从源代码构建安卓的说明。
  • 新硬件的附加接口逻辑必须添加到您正在集成的管理器的 HAL 中。虽然这通常相当简单,但是管理器的 HAL 部分可能分散在整个安卓代码库中。
  • 新硬件必须符合管理器提供的框架的应用编程接口方法。除非您愿意打破 API 兼容性,为特定管理器的类添加额外的属性和方法,否则您必须确保您的硬件适合管理器提供的现有接口。

虽然这种集成可能很困难,但通常非常简单。由于安卓是为平板电脑和手机设计的,任何可能成为移动设备平台一部分的硬件都可能已经有了一个安卓管理器来与之接口。SensorManager就是一个很好的例子。它旨在从各种不同类型的传感器硬件中提供传感器信息。虽然您需要将一些本机代码集成到SensorManager HAL 中来与您的特定传感器进行通信,但是 HAL 和SensorManager API 方法之间的通信是一个相当简单的过程。

类型

在哪里可以找到将定制硬件集成到管理器中的示例

德州仪器为其生产和销售的各种处理器提供了多个评估模块 ( 电动汽车)。由于许多商业产品都基于这些处理器,TI 免费提供文档和指导,说明如何创建定制的 HAL 代码,将通用硬件集成到 Android 管理器中。开始寻找这些细节的最好地方是 TI 的 Sitara Android SDK 的文档。软件开发工具包的网页位于http://www.ti.com/tool/androidsdk-sitara

为定制硬件创建新的管理器

如果您正在将一个独特的硬件集成到安卓系统中,例如您在第 6 章创建一个完整的接口解决方案中创建的环境采样器,可能不会有任何标准的安卓管理器为应用提供必要的 API 方法来与硬件正确通信。在这种情况下,您可以考虑创建一种专门处理独特硬件的新型管理器。

新的管理器可以根据与之交互的硬件进行定制。例如,BBB 提供专门的硬件,允许软件与大多数现代车辆内的计算机通信。这种功能在标准的安卓移动设备中是不可用的,因此不存在处理这种通信的功能。

创建一个新的管理器来处理使用这个接口的具体细节,并提供一个自定义的应用编程接口来使用这个管理器,使应用不必知道这种通信的细节。但是,出于以下原因,这应被视为最后手段:

  • 没有现有的经理代码可以构建。充其量,您可能会找到一个简单的管理器来复制代码作为起点。
  • 安卓构建过程必须修改,以包括构建新的管理器代码。这需要将新管理器的源文件添加到安卓 makefiles 中,然后验证安卓框架没有被破坏。构建安卓是一项庞大而复杂的任务,因此对流程进行任何更改都不应轻易进行。
  • 你必须设计一个合适的应用编程接口来与新经理接口。由于这种新的接口添加不是标准安卓应用编程接口的一部分,除非您专门将它们添加到您的 Eclipse ADT 安装中,否则应用将无法包含这些应用编程接口调用。
  • 您还必须增加android.Manifest.permission以包括一个或多个允许应用访问新管理器功能的新权限设置。或者,您可以利用现有的权限,或者选择完全放弃使用权限。

总的来说,建立一个定制经理是一项艰巨的工作,不适合胆小的人。这个过程涉及安卓框架的许多不同部分,并且需要所有这些部分的功能方面的专业知识。如果你发现自己处于一个位置,你认为你绝对需要创建一个新的管理器来通过安卓框架正确处理你的硬件,你应该考虑跳过管理器,使用一种类似于本书中例子的方法:让你的应用使用 JNI 直接与你的硬件通信。

将您的项目与其他硬件相结合

现在您已经考虑了如何最好地修改您的安卓系统的软件方面,以完全集成您的定制硬件项目,让我们看看事情的硬件方面。试验板在允许您快速创建和更改硬件项目设计方面做得很好。硬件和软件的协同设计是一个迭代的过程,所以当你开发接口软件时,你可能会发现自己在改变硬件设计。然而,随身携带一块试验板来展示你的硬件项目远非理想。

构建自己的原型斗篷

为什么不创建自己的定制披风板项目呢?如果你已经为你的安卓系统开发了完美的硬件项目,你应该考虑让它成为一个独立的 cape board。将您的项目放入斗篷形状因子中,可以轻松地将其与其他斗篷板集成。它还允许您将项目从一个地方移动到另一个地方,而不用担心干扰电路或意外断开任何线路板。

对于没有经验的人来说,为定制斗篷创建一个专业布局的印刷电路板是一项非常困难的任务。但是,你仍然可以通过一点焊接和规划来构建你自己的角板。ada 水果的 Proto Cape 套件(产品 ID 572)是一个很好的开始。Proto Cape 只不过是一个普通的印刷电路板,用来容纳焊接到半永久性电路中的元件。如果您购买了我们在第 1 章安卓系统介绍中提到的 BeagleBone Black 入门包(产品 ID 703)和 BeagleBone Black ,那么您已经拥有了 Proto Cape,因为它包含在该套件中。

Constructing your own prototype capes

用于构建半永久性斗篷电路的原型斗篷套件(来源:www.adafruit.com

Proto Cape 还提供了一个重要的优势,即去除了堵塞 P8/P9 连接器开口的试验板电线。通过堆叠斗篷,最多可以同时连接四个斗篷(通过每个斗篷上的直通 P8/P9 连接器将一个斗篷插入另一个斗篷)。这提供了一个机会来组合不同的斗篷组合,以创建一个定制的安卓系统,最大限度地利用您设计的定制硬件。如果试验板电线阻碍了 P8/P9 的连接,则其他的角板不能再插入连接器并堆叠在 BBB 的顶部。如果堆叠中最上面的角没有直通 P8/P9 连接器(像大多数液晶角一样),就不可能使用试验板设计。

与安卓接口的商用斗篷

有许多预制 BBB 斗篷可供购买,并将在安卓系统上运行良好。4D 系统公司(http://www.4dsystems.com.au/)提供了几种不同的价格合理的各种尺寸和分辨率的液晶显示器,有触摸屏和非触摸屏两种型号。BeagleBoard Toys(http://www.beagleboardtoys.com/)也提供了各种各样的披风,比如液晶、音响和电池披风。通过将各种不同的斗篷与您的 BBB 相结合,您可以将您的安卓系统转变为便携式安卓设备!

Commercial capes that interface with Android

4DCAPE-70T (800 x 480 像素,左)和 4DCAPE-43T (480 x 272 像素,右)4D 系统触摸屏液晶斗篷(来源:www.4dsystems.com.au

类型

那 USB 设备呢?

其他需要考虑的硬件组件是 USB 设备,如音频设备、鼠标、键盘、Wi-Fi 适配器、蓝牙适配器、游戏手柄和网络摄像头。由于 Linux 内核包含所有这些设备的驱动程序,您可以轻松地使用它们来扩展您的安卓平台并开发各种创造性的应用。BBB 只有一个通用串行总线端口,尽管您可以将一个通用串行总线集线器连接到该端口,以支持同时使用多个通用串行总线设备。

也许你可以创建一个基于安卓系统的手持游戏控制台,带有 GPIO 控制器输入和一个基于 SPI 或 I2C 的加速度计。或者,您可以设计一个带有触摸屏液晶显示器的定制汽车控制台,从您的车辆收集实时数据。你可以控制整个平台的硬件和软件,安卓应用开发工具非常适合快速轻松地创建用户界面。可能性是无穷无尽的!

Commercial capes that interface with Android

5VDC 电池(左)和音频编解码器(右)电路(来源:www.beagleboardtoys.com)

探索 BBB 的其他接口

到目前为止,我们已经使用了 BBB 的 GPIO、SPI 和 I2C 功能作为接口。不过,这些并不是 BBB 提供的唯一接口选项。以下是您在 BBB 上考虑安卓项目时应该记住的几个其他界面。

可编程实时单元

BBB 的 AM335X 处理器中嵌入了一对可编程实时单元(PrU)。这些单元的时钟频率为 200 兆赫,因此它们以每 5 纳秒一条指令的速度执行程序。内核将程序加载到一个 PRU 中,然后指示 PRU 开始执行。PRU 和内核之间的通信通过共享内存进行。PRU 的执行与主处理器的执行完全分离,因此将 PRU 推到极限不会对主处理器产生性能影响,除非处理器和 PRU 之间需要一些协调。

有许多 GPIO 引脚可以被多路复用,以便它们处于 PRU 的直接控制之下。PRU 可以在每条指令上检查或设置这些 gpio 的值,这意味着 PRU 控制的 gpio 可以足够快地切换到复杂数字接口(如 SPI 和 I2C)的“位开关”实现。如果您有一个定制的硬件,并且需要实现一个高速接口,使用一个或两个 pru 是一个选择。

串行通信

BBB 提供五个串行通信 UART,可以多路复用到 P8 和 P9 连接器的引脚。还有第六个 UART (UART0),通过 FTDI 电缆提供串行调试输出。如果你用 BBB 来控制大量的串行控制设备,这些 UARTs 是非常有用的资源。

不幸的是,这些 UART 中的几个(UARTs 3、4 和 5)与液晶接口总线使用的引脚冲突,液晶接口总线向液晶显示角和内部 HDMI 角提供视频数据。由于安卓的优势很大程度上来自于它的用户界面,禁用液晶界面来接收更多的通用异步收发器通常是一个非常糟糕的权衡。如果你发现你在安卓系统下绝对需要这些通用异步收发器,所有的通用异步收发器都可以使用标准的 Linux 内核串行驱动程序和现有的 NDK 库来访问,这些库可以访问文件系统中的/dev/TTYS*文件。

控制器局域网

BBB 上有 2 辆 控制器局域网 ( CAN ) 公交车。CAN 是一种串行协议,是用于车辆接口的车载诊断 ( OBD ) 标准的五种协议之一。车辆诊断硬件和软件使用 CAN 与大多数现代汽车的主控制器通信。Linux 内核中的 CAN 驱动程序将每条 CAN 总线公开为一个网络接口,可以通过网络套接字编程与之通信。如果您有兴趣创建一个能够与您的车辆通信的安卓设备,例如您的汽车中的状态显示器或手持诊断单元,CAN 总线正是您所需要的。

CAN0 总线被多路复用到 P9.19 和 P9.20 引脚,这是 capesmgr 用来发现任何连接的 cape 的身份的 I2C2 总线所使用的相同引脚。将 CAN1 总线多路复用到 P9.24 和 P9.26 引脚可能会与 I2C1 冲突,具体取决于您如何多路复用 I2C 通道。一般来说,您不能同时使用 SPI、I2C 和 CAN。

模数转换器

BBB 不仅限于数字通信。它还提供 8 通道、12 位模数转换器 ( 模数转换器 ) ,允许 BBB 接收 0 至 1.8 V 之间的模拟电压电平。这在与现实世界的传感器以及许多触摸屏显示器交互时非常有用。但是,您必须非常小心,以确保施加到这些引脚的电压永远不会超过 1.8 伏,否则您将损坏 BBB。

引脚 P9.32 至 P9.40 与 ADC 永久复用,因此您可以在自己的项目中自由使用。支持触摸屏的 CircuitCo 和 4D 系统液晶显示器目前使用 4-7 通道作为触摸屏,剩下 0-3 通道供您使用。

脉宽调制

BBB 上的 AM3359 处理器有一个 脉宽调制 ( 脉宽调制)子系统用于电机的精确控制。脉宽调制设置向电机提供电压以控制其转速的周期和占空比。脉宽调制子系统包含三个 增强型高分辨率脉宽调制器 ( eHRPWM )模块和一个 增强型正交编码器脉冲 ( eQEP )模块。这四个模块总共为驱动电机提供了八个脉宽调制通道。

虽然脉宽调制经常出现在工业制造设备、机器人伺服电机和各种其他机械系统的控制中,但它也可以用于控制照明亮度和其他任务,这些任务可以利用脉宽调制的可变占空比来模拟全强度下关闭和打开之间的功率/亮度/速度水平。如果你对用安卓操作系统控制机械系统感兴趣,脉宽调制绝对是 BBB 的一个特性,你应该进一步探索。

总结

在这一章中,我们研究了如何在 BBB 上将您的定制硬件项目完全集成到安卓系统中。我们讨论了如何将自定义设备驱动程序直接构建到 Linux 内核中,以及如何将自定义设备树覆盖直接编译到主设备树中。这避免了在你的init.{ro.hardware}.rc文件中包含一个特殊的模块和一个加载命令的覆盖。

我们还探讨了如何定制标准的安卓软件框架,以支持您的定制硬件项目。现有的安卓管理器可以扩展到支持定制硬件。

我们考虑使用 Proto Cape 使您的定制硬件设计半永久性。这允许您在移动项目时避免意外断开试验板电线。它还可以避免用试验板电线堵塞 P8/P9 连接器的问题,从而更容易与商用 BBB 斗篷集成。我们还提到,有很多类型的 USB 设备也是安卓支持的,在考虑新项目时值得探索。

最后,我们探讨了本书前面几章中的例子没有涉及的一些其他 BBB 接口。BBB 的 pru、串行 UARTs、CAN 总线、ADC 和 PWM 子系统都提供了与外部世界接口的附加功能。