Nitrogen8M SBC

在Nitrogen8M SBC上运行VxWorks 7

在这篇简短的文章中,我们来看一下风河(Wind River)的实时操作系统(RTOS)VxWorks 7对当代片上系统(SOC)设备的支持是如何让开发者在非常短的时间里将VxWorks 7的内核跑在一个新板子上的。

为什么使用Nitrogen8M单板计算机

Boundary Devices公司推出的Nitrogen8M单板计算机是一个非常出色的开发板,我们已经在许多Linux驱动程序项目中使用它作为开发平台,它具有一个四核的NXP i.MX8M处理器,2 GB RAM,以太网,USB 3等。

我有一个同事最近正在参与一个VxWorks 7项目,项目是关于i.MX8M的客制化设计,这让我在想,在Nitrogen8M上运行VxWorks会有多容易呢?

NXP i.MX8M上跑VxWorks 7

自90年代初以来,我们一直在编写VxWorks板级支持包(BSP)和驱动程序,所以我知道我们是有可能让VxWorks 7跑在NXP i.MX8M上的。VxWorks 7的创新之一是为各种片上系统(SoC)设备引入了平台(处理器)支持层,从而使向新板子的移植工作变得更加容易。通过将板子具体的硬件配置从BSP中移出并移进设备树中,可以帮助简化移植工作。

由于大多数外围设备都集成到处理器中,因此除了配置一个设备树以运行基本内核外,几乎没有其他事情可做了。当然,最魔幻的在于细节部分。绝大多数的定制化板子都是为特定市场上的某一个工作而设计的,因此使内核运行通常只是任何项目的开始而已。

VxWorks 7支持NXP i.MX8M SoC以及许多NXP的评估板,这是我的起点。我为Nitrogen8M单板创建了一个简单的设备树,并在现有的i.MX8M板级文件中添加了一些基本的板子具体的定义。 然后,我编译了一个内核映像,生成了一个带有集成设备树的U-Boot兼容的ELF文件。

加载内核

现在,使用U-Boot tftpboot命令将VxWorks映像加载到板子上:


=> tftp 43000000 uVxWorks 
Using FEC device 
TFTP from server 192.168.10.20; our IP address is 192.168.10.10 
Filename 'uVxWorks'. 
Load address: 0x43000000 

Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         ########################################
         7 MiB/s
done 
Bytes transferred = 4395496 (4311e8 hex)

下面使用bootm命令来运行它,由于设备树已集成到VxWorks内核映像中,因此我只需要指定加载地址:


=> bootm 43000000
## Booting kernel from Legacy Image at 43000000 ...
   Image Name: vxworks
   Image Type: AArch64 VxWorks Kernel Image (uncompressed)
   Data Size: 4395432 Bytes = 4.2 MiB
   Load Address: 40100000
   Entry Point: 40100000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
## Starting vxWorks at 0x40100000, device tree at 0x00000000 ...
Target Name: vxTarget
 _________            _________ 
 \77777777\          /77777777/ 
  \77777777\        /77777777/ 
   \77777777\      /77777777/ 
    \77777777\    /77777777/ 
     \77777777\   \7777777/ 
      \77777777\   \77777/              VxWorks 7 SMP 64-bit 
       \77777777\   \777/ 
        \77777777\   \7/     Core Kernel version: 3.1.1.0 
         \77777777\   -      Build date: Apr 29 2020 10:55:31 
          \77777777\ 
           \7777777/         Copyright Wind River Systems, Inc. 
            \77777/   -                 1984-2020 
             \777/   /7\ 
              \7/   /777\ 
               -   ------- 

                   Board: Boundary Devices Nitrogen8M SBC - ARMv8 
               CPU Count: 4 
          OS Memory Size: 2048MB 
        ED&R Policy Mode: Deployed
 Adding 9129 symbols for standalone.

->

以上都很简单,只花了几个小时。但是,我们现在有的只是内核和以太网的支持,这只是一个开始,还不足以支持复杂的应用程序。

增加USB 3的支持

增加USB 3支持会如何呢?USB主机控制器已集成到处理器中,原则上也应该很容易,只需将正确的驱动程序添加到内核配置并更新设备树即可。

我插入了一个U盘,期望能检测到它并列出其中的内容,结果什么动静也没有!我检查了驱动程序和内核配置,看起来都没问题,那出问题的地方可能是哪儿呢?

我把USB的调试信息打开,并重新编译了VxWorks内核,重新启动运行带有调试功能的内核,当我插入U盘的时候,USB主机控制器没有识别到任何的设备插入事件,这是确定无疑的了。

看来是时候要更仔细研究一下硬件了!

Nitrogen8M上的USB 3主机控制器

Nitrogen8M有两个USB 3主机控制器,一个连接到了USB 3的Mini Type B的连接器,用于OTG连接。另一个连接到板载USB 3 hub(Renesas uPD720210),其提供了三个板载的USB端口。

幸运的是,Boundary Devices公司提供了板子的原理图,这很有趣:

Nitrogen 8M on-board USB3 hub
Nitrogen 8M on-board USB3 hub

Hub有一个复位引脚,器件的数据手册说这是一个低电平有效的复位信号,我的猜测是Hub被一直置于复位状态,因此我需要将该信号驱动为高电平才能使其退出复位状态。

复位信号是从哪儿来的呢?再看一下板子的原理图:

GPIO pin driving USB hub reset
GPIO pin driving USB hub reset

一点也不奇怪,该复位信号确实来自处理器的一个GPIO引脚。幸运的是,VxWorks 7对i.MX8M平台的支持包含了一个GPIO的驱动程序,我将此驱动程序添加到了内核的配置中,然后,我在Nitrogen8M设备树中添加了一个引脚配置,以在启动过程中将GPIO1的引脚14设置为高电平。

完整的设备树如下所示:


/* nitrogen8m.dts - Boundary Devices Nitrogen8M SBC device tree source */
/*
modification history
--------------------
29apr20,jge created
*/
/dts-v1/;
#include "prjParams.h"
#include "imx8mq.dtsi"
#include "imx8mq-clocks.dtsi"
#include "imx8mq-iomux.dtsi"
/ {
 model = "Boundary Devices Nitrogen8M SBC - ARMv8";
 aliases
 {
 ethernet0 = &enet0;
 serial0 = &uart1;
 };
 memory
 {
 device_type = "memory";
 reg = <0x0 0x40000000 0x0 0x80000000>;
 };
 /*
 * U-Boot only fixes up bootargs if  environment variable is set
 * when VxWorks kernel is configured in independent DTB mode.
 */
 chosen
 {
 bootargs = "enet(0,0)host:vxWorks h=192.168.10.20 e=192.168.10.10:ffffff00
g=192.168.10.1 u=target pw=vxTarget";
 stdout-path = "serial0";
 };
 };
&enet0
 {
 phy0: ethernet-phy@0
 {
 compatible = "atheros,ar8035";
 reg = <0>;
 };
 };
&iomux
 {
 iomux_usb2: iomux_usb2
 {
 pin-set = <
 0x060 0x2C8 0x000 0x0 0x0 0x16
 >;
 };
};
&gpio1
 {
 status = "okay";
 pinmux-0 = <&iomux_usb2>;
 usb_hub_resetb
 {
 gpio-hog;
 gpios = <14>;
 output-high;
 };
 };

重新编译内核并再次引导后,我们可以看到以下信息:


## Starting vxWorks at 0x40100000, device tree at 0x00000000 ...
Target Name: vxTarget
_________            _________
\77777777\          /77777777/
 \77777777\        /77777777/
  \77777777\      /77777777/
   \77777777\    /77777777/
    \77777777\   \7777777/
     \77777777\   \77777/              VxWorks 7 SMP 64-bit
      \77777777\   \777/
       \77777777\   \7/     Core Kernel version: 3.1.1.0
        \77777777\   -      Build date: May 1 2020 13:59:07
         \77777777\
          \7777777/         Copyright Wind River Systems, Inc.
           \77777/   -                 1984-2020
            \777/   /7\
             \7/   /777\
              -   -------

                  Board: Boundary Devices Nitrogen8M SBC - ARMv8
              CPU Count: 4
         OS Memory Size: 1984MB
       ED&R Policy Mode: Deployed

 Adding 10204 symbols for standalone.

->

板子启动后,我看到USB存储设备中的LED灯在闪烁,在shell下使用devs显示内核设备列表也确认了这一点,该列表显示了USB设备上存在两个已挂载的文件系统分区。


-> devs
drv refs name
  1 [ 3] /
  2 [ 3] /bd0:1 ==> /bd0a
  2 [ 3] /bd0:2 ==> /bd0b
  5 [ 3] /bd0a
  6 [ 3] /bd0b
 10 [ 3] /input/event
  0 [ 3] /null
  3 [ 3] /ttyS0
  2 [ 3] /tyCo/0 ==> /ttyS0
 12 [ 3] host:
value = -140737484449152 = 0xffff8000003b9a80
->

展望

到目前为止,总共花费了大约一天的时间。对板载外围设备的全面支持还需要做更多的工作。即使使用VxWorks 7内核中的SoC支持,我们发现还是需要大量的配置和驱动开发工作来支持客户设计的硬件。

有些事情还是没有变化。