Ruff 板卡描述文件

板卡描述,描述了具体的硬件板卡上存在哪些硬件接口(比如,GPIO接口),以及应用可以操作的内置设备(比如,LED)。板卡描述是 Ruff APP 运行在具体板卡上的基石。

请参考 Ruff MBD V1 ,了解一个具体的板卡描述文件如何编写。

前提条件

  • 如果还没有了解如何使用 Ruff 编写应用,可以阅读这里
  • 如果还没有了解如何创建板卡项目,可以阅读这里
  • 如果你希望在rap layout --visual 能够正确进行图形化展示,请在软件仓库上传并配置设备信息。参考这里了解如何在软件仓库添加设备。
  • 请查看板卡对应的技术手册,确定板卡上的接口类型和内置设备,以及相应的参数。

板卡描述文件的基本结构

board.json 是板卡工程的主要文件,用以描述板卡信息。其基本结构如下:

{
"version": "2.0",
"id": "foo",
"model": "foo",
"devices": [
{
"id": "gpio-0",
"driver": "sys-gpio",
"inputs": {
"pin": {
"type": "number",
"args": {
"pin": 0
}
}
},
"outputs": {
"gpio": {
"type": "gpio"
}
}
}
],
"outputs": {
"gpio-0": "gpio-0/gpio"
}
}

板卡声明包括如下内容:

  • version,这个版本号是 board.json 的模式(schema)版本号,当前版本为2.0。
  • id,该板卡描述的 ID,它是你在创建工程的时候输入的工程名。
  • model,该板卡的所支持硬件的型号,建议在软件仓库上传设备信息后,将设备型号配置在这里。
  • devices,描述了板卡上所支持的硬件资源(接口或设备)。
  • outputs,描述了板卡对外导出的硬件资源,也就是其它外设可以使用的接口。

板卡资源配置

在板卡的配置过程中,最重要的是配置板卡上的各种资源,包括:

  • 硬件接口
  • 电源管脚(VCC)
  • 接地管脚(GND)
  • 板载设备

在配置过程中,如果需要的驱动不是 RuffOS 中内置的驱动,需要通过 rap install --save 安装后,才可以配置中引用。

硬件接口

硬件接口,是板卡上最重要的组成部分,只有对外提供了硬件接口,其它外设才能接入。

配置硬件接口,要配置两个部分:

  • devices,配置接口的基本信息,包括驱动、PIN 等。
  • outputs,配置对外导出的接口,也就是其它外设用以接入的接口。

devices 部分包含如下字段:

  • id,该设备对象的 ID。
  • driver,该设备对象使用的驱动
  • inputs,为该驱动配置的输入参数
  • outputs,该设备对象导出的接口,这是在程序中真实用到的接口对象。

下面是一个例子:

"devices": [
...
{
"id": "gpio-0",
"driver": "sys-gpio",
"inputs": {
"pin": {
"type": "number",
"args": {
"pin": 0
}
}
},
"outputs": {
"gpio": {
"type": "gpio"
}
}
}
...
],
"outputs": {
...
"gpio-0": "gpio-0/gpio"
...
}

这里,我们声明了一个 GPIO 接口:

  • 其 ID 命名为 gpio-0
  • 驱动是 sys-gpio,这是由 RuffOS 提供的一个内置驱动。
  • 这个驱动要求指定 GPIO 对应的 PIN,其类型是一个数字,参数是 pin 为 0。
  • 它会导出一个 GPIO 接口供其它外设使用,其名字为 gpio,类型为 gpio,在硬件布局的过程中,会根据这个类型进行匹配。

我们在 outputs 里可以定义一个供外部使用的名字:

  • gpio-0,它对应的就是 gpio-0 导出的名为 gpio 的接口。

更多配置细节,请参考硬件接口指南

电源管脚(VCC)

电源管脚,是板卡上为外设提供的电源接口。

配置电源管脚,需要在 devices 部分声明一个 id 为 power 的配置。在板卡描述文件中,电源管脚是一个虚拟的配置,无需配置驱动,只要根据板卡的实际情况,声明对应的信息即可。具体的配置需要在 outputs 字段声明,每个电源管脚都要有一个参数:

  • voltage,描述该电源管脚对应的电压。

下面是一个例子:

"devices": [
...
{
"id": "power",
"outputs": {
"vdd-0": {
"type": "power",
"args": {
"voltage": "3.3v"
}
},
"vdd-1": {
"type": "power",
"args": {
"voltage": "5v"
}
}
}
},
...
]

其中声明了两个电源管脚:

  • 名为 vdd-0 的电源管脚,电压为3.3v。
  • 名为 vdd-1 的电源管脚,电压为5v。

接地管脚(GND)

接地管脚,是板卡上为外设提供的地线接口。

配置电源管脚,需要在 devices 部分声明一个 id 为 ground 的配置。在板卡描述文件中,接地管脚是一个虚拟的配置,无需配置驱动,只要根据板卡的实际情况,声明对应的信息即可。具体的配置需要在 outputs 字段声明。

下面是一个例子,声明了四个接地管脚。

"devices": [
...
{
"id": "ground",
"outputs": {
"gnd-0": {
"type": "ground"
},
"gnd-1": {
"type": "ground"
},
"gnd-2": {
"type": "ground"
},
"gnd-3": {
"type": "ground"
}
}
}
...
]

板载设备

板载设备,是板卡上预置的设备,比如,LED、按钮等。应用程序可以通过板卡描述文件中声明的信息操控板载设备。

板载设备需要配置在 devices 中,通常要配置如下字段:

  • id,设备 ID,应用程序可以通过$(‘#‘)访问该设备。
  • model,可选字段,设备的型号
  • driver,该设备对应的驱动
  • inputs,输入信息,用于给驱动提供输入参数,根据驱动的不同,配置内容不同。

通常来说,板载设备的驱动是一个普通的驱动,需要通过 rap install --save 安装后,才可以在配置中引用。

下面是一个板载 LED 的描述:

"devices": [
...
{
"id": "led-r",
"model": "ruff-led-gpio",
"driver": "led-gpio",
"inputs": {
"gpio": {
"type": "gpio",
"bind": "gpio-22/gpio",
"args": {
"direction": "out",
"level": "low"
}
}
}
}
...
]

上面的配置说明

  • 该板载 LED 的 ID 为 led-r,应用程序可以通过$(‘#led-r’)访问。
  • 其型号为 ruff-led-gpio
  • 其驱动为 led-gpio
  • inputs 字段中,具体的配置信息依赖于 led-gpio。这里声明了一个名为 gpio 的配置,
    • 其接口类型为 gpio
    • 绑定到 gpio-22/gpio
    • 该配置有两个参数,分别是 directionoutlevellow

硬件接口指南

目前,Ruff 支持的硬件接口类型包括:

接口类型RuffOS 内置驱动
GPIOsys-gpio
I²Csys-i2c
UARTsys-uart
PWMN
ADCN

RuffOS 内置驱动

GPIO

RuffOS 内置的驱动为 sys-gpio:

  • 以 PIN 作为输入参数
  • 导出一个 GPIO 接口供使用

下面是一个例子:

"devices": [
...
{
"id": "gpio-0",
"driver": "sys-gpio",
"inputs": {
"pin": {
"type": "number",
"args": {
"pin": 0
}
}
},
"outputs": {
"gpio": {
"type": "gpio"
}
}
}
...
],
"outputs": {
...
"gpio-0": "gpio-0/gpio"
...
}

I²C

RuffOS 内置的驱动为 sys-i2c

  • 以 bus 作为输入参数
  • 导出一个 I²C 接口供使用

下面是一个例子:

"devices": [
...
{
"id": "i2c-0",
"model": "ruff-i2c",
"driver": "sys-i2c",
"inputs": {
"bus": {
"type": "number",
"args": {
"bus": 0
}
}
},
"outputs": {
"i2c": {
"type": "i2c"
}
}
}
...
],
"outputs": {
...
"i2c-0": "i2c-0/i2c"
...
}

UART

RuffOS 内置的驱动为 sys-uart

  • 以路径作为输入参数
  • 导出一个 UART 接口供使用
"devices": [
...
{
"id": "uart-0",
"model": "ruff-sys-uart",
"driver": "sys-uart",
"inputs": {
"device": {
"type": "string",
"args": {
"path": "/dev/ttyS0"
}
}
},
"outputs": {
"uart" : {
"type":"uart"
}
}
}
...
],
"outputs": {
...
"uart-0": "uart-0/uart",
...
}

转换接口

在硬件接口开发中,将一个接口专为另外一种接口是一种常见的做法。

下面以 Ruff MBD V1 为例,介绍一些转换驱动。

I²C 转 PWM

Ruff MBD V1 中,采用 pca9685 将 I²C 转成了8路的 PWM,下面是一个例子:

"devices": [
...
{
"id": "ruff-pwm",
"model": "ruff-pwm",
"driver": "pca9685",
"inputs": {
"i2c": {
"type": "i2c",
"args": {
"address": 85
}
}
},
"outputs": {
"pwm-0": {
"type": "pwm"
},
"pwm-1": {
"type": "pwm"
},
"pwm-2": {
"type": "pwm"
},
"pwm-3": {
"type": "pwm"
},
"pwm-4": {
"type": "pwm"
},
"pwm-5": {
"type": "pwm"
},
"pwm-6": {
"type": "pwm"
},
"pwm-7": {
"type": "pwm"
}
}
}
...
],
"outputs": {
...
"pwm-0": "ruff-pwm/pwm-0",
"pwm-1": "ruff-pwm/pwm-1",
"pwm-2": "ruff-pwm/pwm-2",
"pwm-3": "ruff-pwm/pwm-3",
"pwm-4": "ruff-pwm/pwm-4",
"pwm-5": "ruff-pwm/pwm-5",
"pwm-6": "ruff-pwm/pwm-6",
"pwm-7": "ruff-pwm/pwm-7",
...
}

I²C 转 ADC

Ruff MBD V1 中,采用 ltc2309 将 I²C 转成了8路的 ADC,下面是一个例子:

"devices": [
...
{
"id": "ruff-adc",
"model": "ruff-adc",
"driver": "ltc2309",
"inputs": {
"i2c": {
"type": "i2c",
"args": {
"address": 8
}
}
},
"outputs": {
"an-0": {
"type": "adc"
},
"an-1": {
"type": "adc"
},
"an-2": {
"type": "adc"
},
"an-3": {
"type": "adc"
},
"an-4": {
"type": "adc"
},
"an-5": {
"type": "adc"
},
"an-6": {
"type": "adc"
},
"an-7": {
"type": "adc"
}
}
}
...
],
"outputs": {
...
"an-0": "ruff-adc/an-0",
"an-1": "ruff-adc/an-1",
"an-2": "ruff-adc/an-2",
"an-3": "ruff-adc/an-3",
"an-4": "ruff-adc/an-4",
"an-5": "ruff-adc/an-5",
"an-6": "ruff-adc/an-6",
"an-7": "ruff-adc/an-7",
...
}

I²C 转 GPIO

Ruff MBD V1 中,采用 mcp23017 将 I²C 转成了16路的 GPIO,下面是一个例子:

"devices": [
...
{
"id": "gpio-plus",
"model": "ruff-gpio",
"driver": "mcp23017",
"inputs": {
"i2c": {
"type": "i2c",
"args": {
"address": 36
}
},
"gpio": {
"type": "gpio",
"bind": "gpio-0/gpio",
"args": {
"direction": "in",
"edge": "both"
}
}
},
"outputs": {
"io-0": {
"type": "gpio"
},
"io-1": {
"type": "gpio"
},
"io-2": {
"type": "gpio"
},
"io-3": {
"type": "gpio"
},
"io-4": {
"type": "gpio"
},
"io-5": {
"type": "gpio"
},
"io-6": {
"type": "gpio"
},
"io-7": {
"type": "gpio"
},
"io-8": {
"type": "gpio"
},
"io-9": {
"type": "gpio"
},
"io-10": {
"type": "gpio"
},
"io-11": {
"type": "gpio"
},
"io-12": {
"type": "gpio"
},
"io-13": {
"type": "gpio"
},
"io-14": {
"type": "gpio"
},
"io-15": {
"type": "gpio"
}
}
}
...
],
"outputs": {
...
"io-0": "gpio-plus/io-0",
"io-1": "gpio-plus/io-1",
"io-2": "gpio-plus/io-2",
"io-3": "gpio-plus/io-3",
"io-4": "gpio-plus/io-4",
"io-5": "gpio-plus/io-5",
"io-6": "gpio-plus/io-6",
"io-7": "gpio-plus/io-7",
"io-8": "gpio-plus/io-8",
"io-9": "gpio-plus/io-9",
"io-10": "gpio-plus/io-10",
"io-11": "gpio-plus/io-11",
"io-12": "gpio-plus/io-12",
"io-13": "gpio-plus/io-13",
"io-14": "gpio-plus/io-14",
"io-15": "gpio-plus/io-15"
...
}