BoardConfig — 硬件端口配置文件(board.json)详解

1、背景

IoT 产品碎片化严重,引入轻应用配置文件规则(一种描述硬件资源的数据结构) 可以实现同一个SoC不同项目只需要更换 board.json 就可以工作,

主要是存储了GPIO, UART, I2C, SPI, ADC, DAC, PWM, DebugLevel 等配置信息, 下面会详细介绍每种功能都包含哪些配置项。


开发者可以修改board.json文件的内容并重新推送到 HaaS 设备上,具体推送方式请参考 Python 轻应用开发工具 HaaS-Studio 第4节。


Python轻应用按照下面的顺序检测系统上的 board.json 文件, 如果找到文件则直接读取并解释使用,否则继续下一步。

1 - 是否存在 /sdcard/board.json 文件:如果存在则执行第4步,否则执行第2步;

2 - 是否存在 /data/pyamp/board.json 文件:如果存在则执行第4步,否则执行第3步;

3 - 是否存在 /data/python-apps/driver/board.json 文件:如果存在则执行第4步,否则持续打印文件缺失提示信息;

4 - 解析并使用 board.json 文件


快速上手 2、HaaS物联网终端 发布的固件包会把 board.json 文件默认放在 /data/python-apps/driver/ 路径下。

board.json 文件

HaaS 设备

board.json 文件链接

HaaS 100

HaaS 100 board.json 文件

HaaS 200

HaaS 200 board.json 文件

HaaS EDU K1

HaaS EDU K1 board.json 文件

HaaS 506

HaaS 506 board.json 文件


HaaS 700注意事项

HaaS700不适用以上说明,请参考以下说明: 1. 开发者修改的board.json文件,暂不支持推送到HaaS700设备,只支持拷贝到SD卡的方式。 2. Python轻应用按照下面的顺序检测系统上的board.json文件,如果找到文件则直接读取并解释使用,否则继续下一步:

  • 是否存在/mnt/sdcard/board.json:如果存在则执行第第4步,否则执行第2步;

  • 是否存在/python/board.json:如果存在则执行第4步,否则执行第3步;

  • 是否存在/data/python-apps/driver/board.json 文件:如果存在则执行第4步,否则持续打印文件缺失提示信息;

  • 解析并使用/board.json文件。

  1. HaaS700发布的固件包会把board.json文件默认放在/python/board.json路径下。

2、语法规则

以 HaaS EDU K1 为例,以下是一个基本配置示例:

{
  "name": "haasedu",
  "version": "0.0.1",
  "io": {
    "D1": {
      "type": "GPIO",
      "port": 31,
      "dir": "output",
      "pull": "pullup"
    },
    "D2": {
      "type": "GPIO",
      "port": 32,
      "dir": "output",
      "pull": "pullup"
    },
    "D3": {
      "type": "GPIO",
      "port": 33,
      "dir": "output",
      "pull": "pullup"
    }
  },
  "debugLevel": "DEBUG",
}

完整配置如下:

board.json配置格式

配置项

类型

是否必填

描述

version

String

IoT轻应用版本号

io

Object

硬件接口配置

debugLevel

String

设置日志等级,默认为ERROR

3、io 配置项

不同的模组/芯片,各个端口和管脚的功能映射可能是不一样的。

IoT轻应用的board配置文件 board.json 中,可将硬件(芯片)的物理端口映射成为统一的应用层逻辑端口。

这样映射的好处是在替换不同的硬件或者芯片时,只需要替换 board.json 而不用修改应用程序或设备程序,从而便于应用的跨平台运行。

IO配置项中有 typeport 等硬件描述概念,对于每一款硬件(通常是芯片/模组/开发板)该配置文件均可能不同。

语法描述格式定义如下:

{
  "io": {
  "D1":{
      "type":"GPIO",
      "port":12,
      "dir":"output",
      "pull":"pullup"
    },
    "I2C0":{
      "type":"I2C",
      "port":0,
      "mode":"master",
      "addrWidth":7,
      "devAddr":270,
      "freq":100000
    }
  },
  "debugLevel": "DEBUG"
}

其中:

  • D1 / I2C0:定义对象,后面大括号里面则描述了该对象的类型。 定义后可以在 JS 中直接使用。

  • type: 描述了该对象的类型,可以是IoT轻应用支持的硬件扩展类型,如 GPIO,I2C,ADC 等。

  • port:描述了该对象的端口,这里需要根据实际硬件连接及芯片的PIN 脚映射关系来填写。

  • dir / pull: 是 GPIO 类型特有的,用于描述 GPIO 输出输出及上拉下拉,其他如 ADC 类型则有 sampling 采样频率这种类型描述。

4、外设 type 说明

io配置项的 type 用于描述该对象是什么硬件端口类型,而每一种type也拥有不同的属性字段,如 GPIO 与 ADC 的属性字段是不一样的。

4.1 GPIO

GPIO 配置

属性字段

数据类型

属性值

是否必须

字段说明

port

Number

1

配置端口值,端口值跟硬件接口有一一对应关系

dir

String

output

配置引脚方向,设置为输出模式(默认)

input

配置引脚方向,设置为输入模式

irq

配置引脚方向,设置为为中断模式

analog

配置引脚方向,设置为模拟 IO 模式

pull

String

pulldown

配置引脚电阻,设置为上拉模式(默认)

pullup

配置引脚电阻,设置为下拉模式

opendrain

配置引脚电阻,设置为开漏模式

intMode

String

rising

配置引脚中断模式,设置为上升沿触发

falling

配置引脚中断模式,设置为下降沿触发

both

配置引脚中断模式,设置为边沿触发(默认)

示例

{
  "io": {
    "D3": {
        "type": "GPIO",
        "port": 22,
        "dir": "output",
        "pull": "pullup"
    },
    "D4": {
        "type": "GPIO",
        "port": 23,
        "dir": "irq",
        "pull": "pullup",
        "intMode": "rising"
    }
  },
  "debugLevel": "DEBUG"
}

4.2 UART

UART 配置

属性字段

数据类型

属性值

是否必须

字段说明

port

Number

1

配置端口值,这里跟芯片 datasheet上 的端口对应

dataWidth

Number

5、6、7、8

串口数据宽度值,默认为 8(bits)

baudRate

Number

9600、115200 等

串口波特率,默认为 115200

stopBits

Number

1、2

串口停止位,默认为 1

flowControl

String

disable、cts、rts、rtscts

流控设置,默认 disable

parity

String

none、odd、even

奇偶校验设置,默认 none

示例

{
  "io": {
    "UART1":{
      "type":"UART",
      "port":1,
      "dataWidth":3,
      "baudRate":9600,
      "stopBits":1,
      "flowControl":"disable",
      "parity":"none"
    },
    "UART2":{
      "type":"UART",
      "port":2,
      "dataWidth":3,
      "baudRate":115200,
      "stopBits":1,
      "flowControl":"disable",
      "parity":"none"
    }
  },
  "debugLevel": "DEBUG"
}

4.3 I2C

I2C 配置

属性字段

数据类型

属性值

是否必须

字段说明

port

Number

1

配置端口值,需要跟芯片 datasheet 上的端口对应,具体数值参考硬件电路手册

addrWidth

Number

7、10

配置 I2C 总线地址宽度,默认 7

freq

Number

100000、 300000等

配置 I2C 总线频率,默认 300000

mode

String

master 或 slave

配置 I2C 总线主从模式,默认 master

devAddr

Number

224

配置 I2C 从设备地址,默认 224。必须为10进制

示例

 {
  "io": {
    "I2C0":{
      "type":"I2C",
      "port":0,
      "mode":"master",
      "addrWidth":7,
      "devAddr":27,
      "freq":100000
    }
  },
  "debugLevel": "DEBUG"
}

4.4 SPI

SPI 配置

属性字段

数据类型

属性值

是否必须

字段说明

port

Number

1

配置端口值,需要跟芯片 datasheet 上的端口对应,具体数值参考硬件电路手册

mode

String

master 或 slave

配置 SPI 总线模式,默认 master

freq

Number

3250000、 6500000等

配置 SPI 总线频率,默认 3250000

示例

 {
  "io": {
    "SPI1":{
      "type":"SPI",
      "port":1,
      "mode":"master",
      "freq":3250000
    }
  },
  "debugLevel": "DEBUG"
}

4.5 ADC

ADC 配置

属性字段

数据类型

属性值

是否必须

字段说明

port

Number

1

配置端口值,需要跟芯片 datasheet 上的端口对应,具体数值参考硬件电路手册

sampling

Number

12000000

配置 ADC 采样率

示例

{
  "io": {
    "voltage": {
        "type": "ADC",
      "port": 1,
      "sampling": 12000000
    }
  },
  "debugLevel": "DEBUG"
}

4.6 DAC

DAC 配置

属性字段

数据类型

属性值

是否必须

字段说明

port

Number

1

配置端口值,需要跟芯片 datasheet 上的端口对应,具体数值参考硬件电路手册

示例

{
  "io": {
    "DAC1": {
      "type": "DAC",
      "port": 1
    }
  },
  "debugLevel": "DEBUG"
}

4.7 PWM

PWM 配置

属性字段

数据类型

属性值

是否必须

字段说明

port

Number

1

配置端口值,需要跟芯片 datasheet 上的端口对应,具体数值参考硬件电路手册

示例

{
  "io": {
    "PWM1": {
      "type": "PWM",
      "port": 1
    }
  },
  "debugLevel": "DEBUG"
}

4.8 debugLevel

配置调试日志等级,分为如下几个等级,默认为ERROR。

debugLevel 配置

等级

说明

DEBUG

显示debug级别的日志

INFO

显示info级别的日志

WARN

显示warning级别的日志

ERROR

显示error级别的日志

FATAL

显示fatal级别的日志

提示信息:

如何在C代码中使用 debugLevel

debugLevel 会设置 Python 轻应用底层C代码的打印等级。如果开发者想使用该功能调试自己的 C 代码,请参考下面的调用方式。

#include "ulog/ulog.h"
#define LOG_TAG "TEST" // define your own LOG_TAG
LOGD(LOG_TAG, "test debug loglevel\n");
LOGI(LOG_TAG, "test info loglevel\n");
LOGW(LOG_TAG, "test warning loglevel\n");
LOGE(LOG_TAG, "test error loglevel\n");
LOGF(LOG_TAG, "test fatal loglevel\n");