利用JSON来定义HCI接口

LoRa硬件与主机之间接口(HCI:Host Command Interface)采用UART/USB接口。在设计LoRa/LoRaWAN的主机接口时,发现需要对应多种语言的实现方式:

  1. C/C++,Keil IDE/GCC/mbed
  2. Lua,MCU/OpenWRT
  3. Python,CPython on Ubuntu/Raspbian/OpenWRT
  4. MicroPython,on STM32F4/ESP8266/ESP32
  5. JavaScript,on Node.js

而HCI的版本目前还是一种不太稳定的状态,不断地升级。所以考虑使用某种语言定义HCI结构,然后设计一个代码生成器来产生所需要的源码、头文件和文档。这样协议升级时,重新生成一次,可以减少许多工作量。这个思路和AIDL/protobuf等方式类似。

暂时,我使用JSON来定义HCI接口。

实现

假设我们的二进制bytes采用如下JSON定义:

{
  "name":"{%struct_name%}",
  "param":[
    {
      "fname":"{%field%}",
      "ftype":"{%type%}",
      "size":{%len(type)%},
      "description":"{%comment%}"
    }
  ]
}

上面其实是一个JSON模板,可以采用Python Jinja2来实现,这是以后我要实现的更高的抽象,眼下都是手工填入JSON文件。在JSON中,会定义名称,字段名称,字段类型,字段长度,描述...

如果需要导出C/C++语言,包括Arduino/mbed C++,都可以使用的C语言结构体。则应该是:

// struct typedef for C/C++
typedef struct{
  {type} {field}; // {comment}
  {type} {field}[{size}]; // {comment}
}{struct_name};

代码生成器应该读取JSON定义后,导出如上所示结构体定义,以及对应的C语言模板。

如果需要导出Python语言,包括CPython/MicroPython,则直接使用struct模块。

struct.pack('fmt_str',*args)
args = struct.unpack("fmt_str", data)

其中fmt_str可以从JSON的字段类型和尺寸上推算出来。

同理,如果导出Lua代码,也直接使用struct包。

-- Lua struct --
struct.pack()
struct.unpack()

至于JavaScript和Node.js,从JSON导出就更加简单了。

可能路径

可能会把它升级为一个通用工具,称之为JDI,JSON Defined Interface。针对通讯和芯片寄存器定义。

你可能感兴趣的:(利用JSON来定义HCI接口)