diff --git a/docs/doc/apparch/imagesrc/lian.png b/docs/doc/apparch/imagesrc/lian.png new file mode 100644 index 0000000..c6ffb7b Binary files /dev/null and b/docs/doc/apparch/imagesrc/lian.png differ diff --git a/docs/doc/apparch/lian.md b/docs/doc/apparch/lian.md index 61bb10e..484a6c9 100644 --- a/docs/doc/apparch/lian.md +++ b/docs/doc/apparch/lian.md @@ -1 +1,182 @@ -# 联 +# 联 - 网络框架 + +多数嵌入式操作系统,应具备传输多种网络协议数据的能力,但是网络协议种类繁多,为每种协议都开放单独的接口,势必会增加操作系统使用者的开发负担,亦不利于嵌入式操作系统的普及与推广。 + +XiUOS网络框架采用以网络适配器为中心的抽象方式,发送与接收数据时,只需要像Linux socket网络通信一样,仅关注发送与接收的数据,而不用把重点放在所使用的具体协议上。这种抽象方式有效屏蔽了种类繁多的网络协议细节,对外提供统一的网络接口,简化了基于嵌入式操作系统的网络开发。网络框架对各类协议的网络设备进行了抽象: +* 一个网络协议设备,被抽象为一个xs_Adapter + +xs_Adapter可以被设计为采用类似面向对象的方法,针对不同的网络协议,扩展其数据成员与接口,从而为种类繁多的网络协议实现统一的管理架构。在网络应用开发的过程中,只需要使用对应网络协议的xs_Adapter实例,而无需关心网络协议的硬件细节,从而实现了网络数据收发功能与底层硬件的解耦。 + +
+ +![LIAN IMAGE](./imagesrc/lian.png) + +
+ +## 1. XiUOS网络框架关键数据结构定义和解析 + +* struct xs_Adapter结构 +```c +struct xs_Adapter +{ +    const char name[XS_NAME_MAX]; /* name of the adapter instance */ +    enum xs_AdpterType type;      /* type of adapter, such as lora adapter */ +    xs_AdapterInfo info;   /* adapter model info, such as vendor name and model name */ +    struct xs_AdpterOps ops; /* socket-like APIs for data transferring */ +    struct xs_AdpterInterface interface; /* physical interface for transferring data */ +    struct XS_DOUBLE_LINKLIST_NODE link; /* link list node */ +}; +``` +name成员是一个可读的名字,用于唯一标识一个xs_Adapter结构。type成员表示该xs_Adapter所使用的网络协议,用一个枚举变量表示: + +```c +enum xs_AdapterType { +    XS_ADAPTER_LORA = 0, /* Lora */ +    XS_ADAPTER_4G ,      /* 4G */ +    /* ...... */ +    XS_ADAPTER_WIFI ,    /* Wifi */ +}; +``` + +info成员包含此网络设备的基础信息,如厂家名vendor与型号product_model。 + +```c +struct xs_AdapterInfo{ +    const char *vendor; +    const char *product_model; +}; +``` + +ops成员包含统一的、类似文件系统的API,用于对网络适配器进行实际的数据读写。在使用一个网络适配器前后需要打开(open)/关闭(close)该网络适配器,send、receive分别用与从网络适配器接收数据与向网络适配器发送数据,ioctl用于配置Adapter属性: + +```c +struct xs_AdapterOps { +    int (*open)(struct xs_Adapter *sadapter); +    void (*close)(struct xs_Adapter *sadapter); +    int (*join)(struct xs_Adapter *sadapter,int net_type, int dev_type, int net_number); +    int (*send)(struct xs_Adapter *sadapter, const char* data, int len,int des_dev, int time_out, bool block, int delay); +    int (*receive)(struct xs_Adapter *sadapter, char* rev_buffer, int buffer_len,int time_out, bool block); +    int (*ioctl)(struct xs_Adapter *sadapter, int cmd, void *arg); +}; +``` + +其中需要注意的是,join接口的所使用的net_type和dev_type参数,分别来自枚举: + +```c +enum xs_net_type{ +    XS_CENTRALIZATION = 0, +    XS_ADHOC, +}; + +enum xs_dev_type{ +    XS_Client = 0, +    XS_GATEWAY, +}; +``` +net_type代表的含义是,使用传统的中心化网络或者自组网络。dev_type代表的含义是,此设备是普通设备或者网关设备。 + +最后,在系统中每种网络协议的xs_Adapter被分别组织成不同双链表,如Lora的xs_Adapter链表、4G的xs_Adapter链表等,使用的链表节点即为link成员。 + +## 2. XiUOS网络框架驱动开发 + +以Lora网络适配器为例。网络框架针对每个具体的网络适配器将xs_Adapter进行扩充,采用类似面向对象的手段添加其他必要成员,如: + +```c +struct xs_AdapterLora { +    struct xs_Adapter parent; /* inherit from xs_Adapter */ + +    const char *deve_ui; /* Lora specific value */ +    const char *app_key; /* Lora specific value */ +}; +``` + +实现xs_AdapterOps中的数据通信API,具体实现细节取决于所使用网络协议,无法实现的API可以置为NULL: + +```c +struct xs_AdapterOps lora_example_ops = { +    .open = lora_example_open; +    .close = lora_example_close; +    .send = lora_example_send; +    .receive = NULL; +    .ioctl = lora_example_ioctl; +}; +``` + +填充xs_AdapterLora,并将其注册。 + +```c +int xs_AdapterRegister(struct xs_Adapter *sadapter); + +extern struct xs_AdapterOps lora_example_ops; +/* declare xs_AdapterLora */ +struct xs_AdapterLora lora_example_adapter; + +void register_lora_adapter() +{ +    /* initialize and register the xs_Adapter object */ +    memset(&lora_example_adapter, 0, sizeof(lora_example_adapter)); +    lora_example_adapter.parent.name = "adapter1"; +    lora_example_adapter.parent.type = XS_ADAPTER_LORA; +    lora_example_adapter.parent.info.vendor = "xxx"; +    lora_example_adapter.parent.info.product_model = "yyy"; +    lora_example_adapter.parent.ops = &lora_example_ops; +    lora_example_adapter.parent.interface.bus_device = xs_DeviceFind("uart1"); +    lora_example_adapter.deve_ui = "mmm"; +    lora_example_adapter.app_key = "nnn"; +    xs_AdapterRegister(&lora_example_adapter); +} +``` + +## 3. XiUOS网络框架的使用实例 + +网络应用开发者使用网络框架提供的API操作网络适配器,网络适配器API可以分为通用API与协议特有API。通用API用于网络适配器的获取、打开与关闭,协议特有API用于特定协议的数据采样。以Lora网络适配器为例: + +```c +/* generic API: find a adapter instance by its name */ +struct xs_Adapter *xs_AdapterFind(const char *name); + +/* generic API: open/close a adapter instance */ +int xs_AdapterOpen(struct xs_Adapter *adapter); +void xs_AdapterClose(struct xs_Adapter *adapter); +/* Lora API: get current Lora adapter reading */ +uint32_t xs_AdapterReceive(struct xs_Adapter *adapter, char* rev_buffer, int buffer_len,int time_out, bool block); +``` + +在获取数据前,需要先获取并打开要使用的网络适配器;网络适配器打开后可以随时对网络适配器数据进行读取;使用完毕后,须关闭网络适配器。完整的使用过程示例如下: + +```c +#define BUFFER_MAX 512 +int main(int argc, char *argv[]) +{ +int ret; +    char rev_buffer[BUFFER_MAX]; + +    struct xs_Adapter *adapter; +    struct xs_AdapterLora *lora_adapter; + +    /* get the Lora adapter instance */ +    adapter = xs_AdapterFind("lora_1"); +    XS_ASSERT(adapter->type == XS_ADAPTER_LORA); +    /* open the Lora adapter instance */ +    lora_adapter = (struct xs_AdapterLora *)adapter; +    ret = xs_AdapterOpen(adapter); +    XS_ASSERT(ret == XS_EOK); +   +    xs_AdapterReceive(adapter, rev_buffer, BUFFER_MAX, 0, true); +    xs_kprintf("Data read from lora_adapter is %s \n", rev_buffer); +    xs_AdapterClose(adapter); +    return 0; +} +``` + +## 4. XiUOS自组网功能简介 + +传统的数据收集与上报系统架构,一般采用星型拓扑的组织形式,以网关为中心,将数据收集设备(传感器)连接组织起来,传感器之间一般没有大规模的数据流动。而这种中心化的网络架构,有其自身的缺点,如中心节点的数据压力经常逼近极限,成为整个系统的性能瓶颈,或者一旦程序崩溃,即造成其承载的所有传感器发生掉线事故。 +所以我们在提供中心化网络服务的同时,也提供了去中心化的自组网络服务,自组网结构一般具有以下优点: + +1、动态接入 +传统的中心节点型网络,需要网关手动配置想要连接的传感器,然后对区域进行轮询扫描,传感器则在被轮询到时,被动地上报自己的数据。而自组网新节点需接入时,可实现主动接入,无需对网关进行手动配置,节省运维成本。 +2、去中心化 +自组网内无中心节点,节点之间可进行自主路由协商,以此来实现跳转通信,相比传统中心化网络,有效分摊网络流量,进而分散节点运算压力。自组网具有良好的健壮性,任何一个节点发生崩溃,其所承载的传感器会自动寻找其他上传节点,不会造成大面积的掉线事故。 +3、不依赖现有网络 +节点之间通信,不依赖现有的网络基础设施,自组网内部实现网络自治,以此应对通信地点和时间的不确定性。 \ No newline at end of file