AliOS Things基于USB通道外接4G模组的方案

1、概述

本文介绍AliOS Things关于USB外接广域网芯片连接入云的方案。物联网设备联网方案,可分为OpenCPU的方式与外接通信芯片的方式。OpenCPU的应用层与网络层运行在同一芯片上,该方式具有较高的集成度,但使得应用、协议在接口、配置、性能等方面产生了耦合,不利于方案的移植与推广。

而采用外接的方式,可以分离应用层与网络层,较好地降低耦合度,提高联网方案的灵活性。例如,MCU运行MQTT应用层协议,而由外接通信芯片(如Wi-Fi、LTE)完成网络层的TCP/IP连接与传输。当然,外接通信芯片的代价,是MCU与通信芯片之间增加了交互成本,需要开发者选择适合应用场景的外接方式。

AliOS Things支持MCU与通信芯片间的多种连接方式,如UART、SPI、SDIO、USB。这些连接方式不仅拓展了基于AliOS Things开发的可选联网方案,还满足了不同应用场景对传输速率需求,如表1所示。其中,HAAS100通过USB外接LTE,可以实现相同厂商不同模组间无缝替换,例如EC20、EC200S。

  接口 最高速率 (Mbps) 应用场景举例 MCU + 通信芯片
1 UART 1.5 Developerkit,WiFi STM32L496 + BK7231
2 SPI 20 HAAS100,Ethernet HAAS1000 + CH395
4 USB 12 HAAS100,LTE HAAS1000 + EC20

表1 AliOS Things所支持外接方式以及应用场景

2、USB外接通信芯片的优点

USB本身具有使用方便、数据传输可靠、成本低、省电等优点。而使用USB做为外接通信芯片的通道,将保留这些优点,具体表现为:

2.1、使用方便

  • 一个接口可以用于多种设备的连接,用户可以方便地替换所要连接的通信芯片,无需针对不同通信芯片采用不同的连接器和线缆。
  • 自动配置,通信芯片接入后,MCU侧可以自动对通信芯片进行识别,并加载对应的驱动程序。
  • 支持热插拔,用户可以随时接入或拔出通信芯片,而不会损害硬件设备,也无需重启设备。
  • 无需额外供电,USB接口提供了+5V电压,500mA以下电流,一般情况下通信芯片无需额外电源。

2.2、数据传输可靠

  • 接收端和线缆硬件规范,保证数据传输在一个平静的接口电器环境中,避免了导致数据错误的大部分噪声干扰。
  • 差分传输模式,USB 1.1/2.0采用四线模式,其中D+/D-为数据传输通道,采用差分信号的传输方式,D+/D-需要同时满足电平条件才能判定为0或1,降低了因干扰产生比特跳变的可能性。
  • CRC校验,USB硬件自带CRC校验,可检测传输过程中发生的错误。
  • 协议确认重传,USB在协议层面提供了确认(ACK/NACK)与重传机制,可从传输错误中恢复。

2.3、成本低、省电

  • USB部件成本较低,无论是使用独立的controller,还是使用集成IP的方案,成本都可以控制在合理范围内。并且从可扩展性来看,USB可以支持更多种类的设备连接,而无需硬件上的改动。
  • USB使用了省电电路与协议,配合通信芯片的休眠与唤醒功能,可实现整体上的低功耗。

3、实现基于USB通道外接通信芯片

为了实现基于USB通道外接通信芯片,除了要保证MCU具备USB连接硬件能力以外,MCU侧还需要实现USB host协议栈,以完成

扫描二维码关注公众号,回复: 12139427 查看本文章
  • 设备识别
  • 驱动加载
  • 数据传输

image

图 1 MCU侧USB Host协议栈结构,包括了Host controller层、Host Core层、Host Class层、USB Device Driver层

MCU侧的USB host协议栈大致分为四层:Host Controller层、Host Core层、Host Class层、USB Device Driver层。其中,Host Controlle是USB host协议栈最底层,负责直接与硬件交互,读写寄存器、中断处理;Host Core是协议栈的核心层,对下负责管理Host controller、设备、接口、端点,并负责设备枚举,对上负责host class的注册、设备的配置以及传输请求处理;Host Class层为各USB host类的实现层,例如HID、CDC、UVC等类。 最后,设备驱动层用于实现与USB设备应用交互逻辑,例如通过AT指令与EC20进行交互。各层的设计细节将在另一篇文章中详细介绍,此处将不再展开。本节将围绕设备识别、驱动加载、数据传输介绍USB外接通信芯片的实现方式。

3.1、设备识别

当通信芯片通过USB连接上MCU后,两者会发生以下对话。

Host:你是什么设备?
Device: 12 01 0100...  /* Device Descriptor */
Host:你有几种功能?
Device:09 02 09...    /* Configuration Descriptor */
Host:每个功能有几个接口?
Device: 09 04 00...    /* Interface Descriptor */
Host:每个接口使用哪几个端点?
Device: 06 05 82...    /* Endpoint Descriptor */
Host: 我知道你是谁了,开始传输
Device: OK 
....

这些问答的目的是为了帮助USB Host准确地对接入的设备进行识别。交互的信息主要包括设备描述符、配置描述符、接口描述符、端点描述符。

3.2、类加载

在枚举过程的最后会根据设备所属类加载驱动。这里有两种加载方式,一种是按设备加载,另一种是按接口加载。以EC20为例,其接口都为vendor类,无法根据接口类进行加载。因此,需要根据设备的Vendor ID(VID)、Product ID(PID)加载对应类。

事实上,针对这一类由vendor定制广域网USB设备,Linux USB驱动的解决方案,是使用专门有文件(usb/serial/option.c)用于存储厂商的VID和PID列表;在枚举时,如果USB设备的VID与PID相匹配,则加载相应驱动(usb/serial/wwan.c)进行处理。如上文所述,EC20有5个接口,其中接口0为DM口、接口1为GPS接口、接口2为AT口、接口3为PPP口、接口4为NDIS口,如图5所示。由于PC端资源是充足的,Linux USB Host在枚举EC20时可以为每个接口创建相应的端点,并允许用户同时操作这些接口(open/read/write)。

image

图 4  EC20各USB接口功能

然而,在运行RTOS的MCU芯片上USB控制器的资源是有限的,无法同时创建这么多个接口所需要的端点。以HAAS1000为例,除了控制端点0,其USB控制器只有4个端点可供使用。因此,在MCU上枚举过程中需要考虑底层硬件资源限制,否则会导致驱动加载失败。这里采用的策略是复用端点的方式。在加载驱动时,有针对性地选择接口:首先为接口2分配端点资源,用于AT指令交互,保证4G模块联网并获取IP;然后,在其它接口需要使用时,释放端点2的端点资源。

3.3、数据交互

完成类加载后,上层可通过USB通道收发送数据。以EC20的AT接口为例,AliOS Things的AT驱动框架(SAL + AT Utility)可以无缝运行在USB协议栈上。

image

图 5  基于USB协议栈的AT通道

需要做的工作是使用USB Class API实现AT Utility所需HAL(at_dev_ops_t)即可,如下所示。

/*
* AT dev operation type
*/
typedef struct {
   at_dev_type_t type;
   /**
    * AT device init
    *
    * @return  0 - success, -1 - failure
   */
   int (*init)(void *dev);
   /**
   * Receive data from AT device
   *
   * @return  0 - success, -1 - failure
   */  
   int (*recv)(void *dev, 
               void *data, 
               uint32_t expect_size,
               uint32_t *recv_size,
               uint32_t timeout);
   /**
   * Send data to AT device.
   *
   * @return  0 - success, -1 - failure
   */
   int (*send)(void *dev,
               void *data,
               uint32_t size,
               uint32_t timeout);
   
   /**
    * AT deviec deinit
    *
    * @return  0 - success, -1 - failure
   */
   int (*deinit)(void *dev);
} at_dev_ops_t;

在此基础上,使用AT Utility API实现SAL所需HAL(sal_op_t)即可,如下所示。

typedef struct sal_op_s {
    struct sal_op_s * next;  //<! Next sal_op_t structure
    char *version; //<! Reserved for furture use.
    char *name; //<! Drvier name
    /* Add sal device */
    int (*add_dev)(void*);
    /**
     * Module low level init so that it's ready to setup socket connection.
     *
     * @return  0 - success, -1 - failure
     */
    int (*init)(void);
    /**
     * Start a socket connection via module.
     *
     * @param[in]  c - connect parameters which are used to setup
     *                 the socket connection.
     *
     * @return  0 - success, -1 - failure
     */
    int (*start)(sal_conn_t *c);
    /**
     * Send data via module.
     * This function does not return until all data sent.
     *
     */
    int (*send_data)(int fd, uint8_t *data, uint32_t len,
                char remote_ip[16], int32_t remote_port, int32_t timeout);
    /**
     * Get IP information of the corresponding domain.
     * Currently only one IP string is returned (even when the domain
     * coresponses to mutliple IPs). Note: only IPv4 is supported.
     *
     *
     * @return  0 - success, -1 - failure
     */
    int (*domain_to_ip)(char *domain, char ip[16]);
    /**
     * Close the socket connection.
     *
     * @return  0 - success, -1 - failure
     */
    int (*finish)(int fd, int32_t remote_port);
    /**
     * Destroy SAL or exit low level state if necessary.
     *
     * @return  0 - success, -1 - failure
     */
    int (*deinit)(void);
    /**
     * Register network connection data input function
     * Input data from module.
     * This callback should be called when the data is received from the module
     * It should tell the sal where the data comes from.
     *
     * @return  0 - success, -1 - failure
     */
    int (*register_netconn_data_input_cb)(netconn_data_input_cb_t cb);
} sal_op_t;

完成以上对接后,上层应用即可以基于标准的套接字API编程,降低了应用层移植成本。相关AT驱动组件介绍请参考AliOS Things帮助文档 SAL组件AT组件

4、HaaS100外接4G模组示例

IMG_20201218_143254.jpg

图6 HaaS100通过USB外接EC20

E5B7D2D3-5CFC-41BD-B092-4FA90E5AB4DC.png

图 7 USB所用排针接线

HaaS100板上排针提供了USB引脚,可以用接USB母口扩展线,与通信模组连接,如图6、7所示。

步骤一:配置

 aos make linkkit_demo@haas100 -c config

步骤二:配置选择

aos make menuconfig

配置

image.png

image.png

image.png

步骤三:编译

aos make

步骤四:烧录

请参考HaaS快速开始

步骤五:启动

该应用运行Linkkit demo,USB枚举成功后,通过AT通道,可以连接入阿里云IoT平台。

5、总结

广域网通信模组通常都提供USB通道,支持AT、PPP、RNDIS、ECM等通信方式。因此,在MCU侧支持USB协议栈,可自动识别枚举各类通信设备,并加载所需的驱动,方便用户上层的开发。本文简要介绍了AliOS Things的USB Host协议栈,并以EC20为例描述了枚举识别过程,同时给出了在USB通道上对接AliOS Things传统AT通道的方式。在后续相关系列文章中,我们将介绍基于USB通道的PPP、RNDIS、ECM方式,并给出相应对比数据。敬请期待。

如需更多技术支持,可加入钉钉开发者群

更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/

猜你喜欢

转载自blog.csdn.net/HaaSTech/article/details/112046835