MS-RTOS 网络子系统

更新时间:
2023-08-09
下载文档

MS-RTOS 网络子系统

本章将介绍 MS-RTOS 网络子系统开发。

网络实现

网络实现是 MS-RTOS 网络子系统对不同实现方法的 TCP/IP 协议网络通信技术的抽象。

不同的网络实现(如 TCP/IP 协议栈和 ESP8266 等有线、无线通信模块)提供了不同的 API 和数据类型,MS-RTOS 为了保证上层应用能使用统一标准的 BSD/socket 套接字 API 进行网络编程,MS-RTOS 网络子系统对网络实现进行了抽象。

多套网络实现能够在 MS-RTOS 中共存,目前 MS-RTOS 已经支持了三种网络实现:

  • lwIP 轻量级 TCP/IP 协议栈,加入了多 IP 支持
  • ESP8266/ESP32
  • SIM800/SIM900(2G)和 SIM7000/SIM7020(NB-Iot LTE)

网络实现示例

以 lwIP 协议栈为例,需要定义一个 ms_net_impl_t 对象及实现相关的网络实现操作 ms_net_impl_ops_t

// socket 设备驱动程序操作
static ms_io_driver_ops_t ms_lwip_socket_drv_ops = {
        .type     = MS_IO_DRV_TYPE_SOCK,
        .open     = __ms_lwip_socket_open,
        .close    = __ms_lwip_socket_close,
        .write    = __ms_lwip_socket_write,
        .read     = __ms_lwip_socket_read,
        .ioctl    = __ms_lwip_socket_ioctl,
        .fcntl    = __ms_lwip_socket_fcntl,
        .poll     = __ms_lwip_socket_poll,
};

// socket 设备驱动程序
static ms_io_driver_t ms_lwip_socket_drv = {
        .nnode = {
            .name = MS_LWIP_SOCKET_DRV_NAME,
        },
        .ops = &ms_lwip_socket_drv_ops,
};

// 网络实现操作
static ms_net_impl_ops_t ms_lwip_net_impl_ops = {
        .sock_drv_name          = MS_LWIP_SOCKET_DRV_NAME,
        .socket                 = (ms_net_socket_func_t)__ms_lwip_socket,
        .accept                 = (ms_net_accept_func_t)__ms_lwip_accept,
        .bind                   = (ms_net_bind_func_t)lwip_bind,
        .getpeername            = (ms_net_getpeername_func_t)lwip_getpeername,
        .getsockname            = (ms_net_getsockname_func_t)lwip_getsockname,
        .getsockopt             = (ms_net_getsockopt_func_t)lwip_getsockopt,
        .setsockopt             = (ms_net_setsockopt_func_t)lwip_setsockopt,
        .connect                = (ms_net_connect_func_t)lwip_connect,
        .listen                 = (ms_net_listen_func_t)lwip_listen,
        .shutdown               = (ms_net_shutdown_func_t)lwip_shutdown,
        .recv                   = (ms_net_recv_func_t)lwip_recv,
        .recvfrom               = (ms_net_recvfrom_func_t)lwip_recvfrom,
        .recvmsg                = (ms_net_recvmsg_func_t)lwip_recvmsg,
        .send                   = (ms_net_send_func_t)lwip_send,
        .sendmsg                = (ms_net_sendmsg_func_t)lwip_sendmsg,
        .sendto                 = (ms_net_sendto_func_t)lwip_sendto,
        .if_indextoname         = (ms_net_if_indextoname_func_t)lwip_if_indextoname,
        .if_nametoindex         = (ms_net_if_nametoindex_func_t)lwip_if_nametoindex,
        .gethostbyname_addrtype = (ms_net_gethostbyname_addrtype_func_t)netconn_gethostbyname_addrtype,
        .gethostname            = (ms_net_gethostname_func_t)__ms_lwip_gethostname,
        .sethostname            = (ms_net_sethostname_func_t)__ms_lwip_sethostname,
        .getdnsserver           = (ms_net_getdnsserver_func_t)__ms_lwip_getdnsserver,
        .setdnsserver           = (ms_net_setdnsserver_func_t)__ms_lwip_setdnsserver,
};

// 网络实现对象
static ms_net_impl_t ms_lwip_net_impl = {
        .nnode = {
            .name = MS_LWIP_NET_IMPL_NAME,
        },
        .ops = &ms_lwip_net_impl_ops,
};

// 初始化 lwIP 网络实现
ms_err_t ms_lwip_net_init(void (*init_done_callback)(ms_ptr_t arg), ms_ptr_t arg)
{
    ms_err_t err;

    // 初始化 lwIP 协议栈
    tcpip_init(init_done_callback, arg);

    // 注册 lwIP 网络实现
    err = ms_net_impl_register(&ms_lwip_net_impl);
    if (err == MS_ERR_NONE) {
        // 注册 lwIP socket 设备驱动
        err = ms_io_driver_register(&ms_lwip_socket_drv);
        if (err == MS_ERR_NONE) {
            ms_lwip_inited = MS_TRUE;
        }
    }

    return err;
}

相关 API

// 获得默认的网络实现
ms_net_impl_t *ms_net_impl_default(void);

// 通过名字查找网络实现
ms_net_impl_t *ms_net_impl_find(const char *name);

// 注册一个网络实现
ms_err_t ms_net_impl_register(ms_net_impl_t *net_impl);

// 注册一个指定网络实现的 socket 设备,并与传入的 dev_ctx 关联
int ms_net_socket_attach(const char *net_impl_name, ms_ptr_t dev_ctx);

// sockaddr 转 ipaddr 与 port
void ms_net_sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, ms_uint16_t *port);

// ipaddr 与 port 转 sockaddr
void ms_net_ipaddr_port_to_sockaddr(union sockaddr_aligned *saddr, ip_addr_t *ipaddr, ms_uint16_t port);

// 构建 IPv4 地址
void ms_net_ip_addr4(ip_addr_t *ipaddr, ms_uint8_t ip0, ms_uint8_t ip1, ms_uint8_t ip2, ms_uint8_t ip3);

// 设置为任意的 IP 地址
void ms_net_ip_addr_set_any(ms_bool_t is_ipv6, ip_addr_t *ipaddr);

相关命令

命令介绍参数
nets查看注册的网络实现
lwipstat查看 lwIP 协议栈的统计信息
netifs查看 lwIP 网络接口的信息
文档内容是否对您有所帮助?
有帮助
没帮助