Ruff Board Description

Ruff Board Description describes hardware interfaces (such as GPIO), and on-board devices (such as LED) that application can control. The board is a prerequisite condition for any Ruff app to run on a real board.

Please refer to Ruff MBD V1 about how to write descriptions for a real board.

Prerequisites

  • Please click here if you are not sure how to use Ruff to write apps.
  • Please click here if you know nothing about boards.
  • Please upload device information to Rap Registry for accurate visualization on rap layout - visual . Visit here for how to add a device to Rap Registry.
  • Please read the datasheet to confirm the information of hardwares interface and on-board boards.

The Structure of Board Description

board.json is a main file in the board project to describe the board. The structure is written as follows:

{
"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"
}
}
  • There are some properties declared in board.json:
    • version - currently the schema version of board.json is 2.0.
    • id - ID for this board and also the ID what you input during initialization.
    • model - hardware model. You’d better upload your device information to Rap Registry.
    • devices - the on-board hardware resource(interface or device).
    • outputs - the export hardware resource, and can be used by other devices.

Configuring Resouce on The Board

It is important to configure resource on the board, including:

  • Hardware interface
  • VCC
  • GND
  • On-board device

If it is not a Ruff OS built-in driver, please install rap install --save and then refer it in the configuration.

Hardware Interface

Hardware interface is the most essential part of the board that provides a real interface for other devices to connnect.

There are two parts for the hardware interface:

  • devices - basic information, including driver and PIN etc.
  • outputs - export interface, which provides real interface for other devices to connnect.

The devices contain the following fields:

  • id - the device ID
  • driver - the device driver
  • inputs - the argument for driver
  • outputs - the export interface, which provides real interface for other devices to connnect.

Here is an example:

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

A GPIO interface is declared as follows:

  • ID is named as gpio-0
  • The driver is sys-gpio, a RuffOS builtin driver.
  • The driver specifies a PIN for GPIO. Its type is a number, and pin as the argument is 0.
  • It will export a GPIO interface for other devices. Its name is gpio and the type is gpio. The type usuually is used for matching during the hardware layout.

A name is defined in outputs for external use:

  • gpio-0 - the gpio interface exported from gpio-0

Please refere to Hardware Inteface Guide for more details.

VCC

VCC provides a power interface on the board for device to connect.

To configure VCC, a configuration with power as id should be declared in devices. VCC is a virtual configuration, so there is no need to configure the driver. You need to declare VCC according to the real board. The real VCC resource is configured in outputs.

  • voltage - the voltage of VCC.

Here is an example:

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

Two VCCs are declared as follows:

  • The VCC named as vdd-0 has 3.3v voltage.
  • The VCC named as vdd-1 has 5v voltage.

GND

GND provides a ground interface on the board for devices to connect.

To configure GND, a configuration with ground as id should be declared in devices. GND is a virtual configuration, so there is no need to configure driver. You need to declare GND according to the real board.The real GND resource is configured in outputs.

There are four GNDs declared in the following example:

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

On-Board Device

On-Board Device is an object installed on the board, like LED and button. Application can use on-board devices by declaruing them in board.json.

The on-board devices is declared in devices. The following are examples of fields that are configured.

  • id - device ID. Application can use $(‘#‘) to access the device.
  • model- optional field and the device model.
  • driver - the driver for device.
  • inputs - the arguments provided to driver but varies from drivers.

The on-board driver is a plain driver installed by rap install --save. Once installed, the driver can be refered in driver.json.

An example of on-board LED is listed as follow:

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

The above configuration tell us,

  • The ID of the on-board LED is led-r. The application can access the device with $(‘#led-r’).
  • The model is ruff-led-gpio
  • The driver is led-gpio
  • The inputs depends on led-gpio.

A gpio configuration is declared here:

  • The type is gpio.
  • Bind to gpio-22/gpio.
  • The arguments are direction is out and level is low.

Hardware Inteface Guideline

Here is a list of hardware interface that Ruff currently supports:

InterfaceRuffOS Builtin Driver
GPIOsys-gpio
I²Csys-i2c
UARTsys-uart
PWMN
ADCN

Ruff OS Built-in Driver

GPIO

The Ruff OS built-in driver is sys-gpio:

  • Takes a PIN as input argument
  • Exports a GPIO interface

An example is listed as follows:

"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

The Ruff OS built-in driver is sys-i2c:

  • Takes a bus as input argument
  • Exports a I²C interface

Here is an example:

"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

The Ruff OS built-in driver is sys-uart:

  • Takes a path as input argument
  • Exports a UART interface
"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",
...
}

Convertor

It’s common in hardware development to convert one interface to the other.

Please see Ruff MBD V1 as an example.

I²C to PWM

In Ruff MBD V1, it takes pca9685 to convert I²C to PWM that has 8 channels. Here is an example:

"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 to ADC

In Ruff MBD V1, it takes ltc2309 to convert I²C to ADC that has 8 channels. An example is listed as follow:

"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 to GPIO

In Ruff MBD V1, it takes mcp23017 to convert I²C to GPIO that has 16 channels. Here is an example:

"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"
...
}