rtthread-nano AT组件管理Air724

cAir724ug 网卡管理

air720_device_class_register

AT 设备类注册

-> Air724 socket 类注册,注册socket数量与socket 操作函数

-> 注册AT设备类到设备链表

air720_device_register

AT设备注册(air720_device_register )

-> 根据设备类型查找设备类(at_device_class_get)

-> 为设备SOCKET 对象分配空间

-> 模组初始化(device-> ops - >init-)

1. 初始化AT客户端,创建AT指令解析线程 at_client_init
2. 设置URC TABLE
3. 将网卡设备添加到netdev网卡链表
4. 网卡开机
at_device_register                                          /* AT设备注册 */
    |-> class = at_device_class_get(class_id)               /* 模组ID唯一 */
    |-> class->device_ops->init(device)                     /* AT设备操作函数初始化模组 */
        |-> air720_init                                     /* 注意操作函数在air720_device_class_register注册到设备链表*/
            |-> air720->power_status = RT_FALSE;            /* default power is off.  */
            |-> air720->sleep_status = RT_FALSE;            /* default sleep is disabled. */
            |-> at_client_init                              /* components/net/at/src/at_client.c */
                |-> at_client_para_init                     /* components/net/at/src/at_client.c */
                    |-> rt_thread_create(client_parser)     /* 线程名字为"at_clnt0",创建AT解析线程 components/net/at/src/at_client.c */
                        |-> client_parser                   /* AT解析线程的具体实现 components/net/at/src/at_client.c */
                |-> rt_device_find                          /* 寻找串口设备 rt-thread/src/device.c */
                |-> rt_device_open                          /* 打开串口设备 rt-thread/src/device.c */
                |-> rt_thread_startup(client->parser)       /* rt-thread/src/thread.c */
            |-> air720_socket_init                          /* 增加socket相关的URC*/
            |-> air720_netdev_add("air720")                 /* 设置AIR724网卡相关信息与操作函数,注册网卡到链表 */
                |-> netdev_get_by_name("air720")            /* rt-thread/components/net/netdev/src/netdev.c */
                |-> netdev->ops = &air720_netdev_ops;       /* 网络设备操作集 */
                |-> sal_at_netdev_set_pf_info               /*  设置AT网络接口设备协议簇信息 */
                |-> netdev_register                         /* rt-thread/components/net/netdev/src/netdev.c */
                    |-> netdev->status_callback = RT_NULL;  /* rt-thread/components/net/netdev/src/netdev.c */
                    |-> netdev->addr_callback = RT_NULL;    /* rt-thread/components/net/netdev/src/netdev.c */
            |-> air720->power_pin                           
            |-> air720->power_status_pin                   
            |-> air720->wakeup_pin                          
            |-> air720_netdev_set_up                        /* 网卡开机,注册网络 */
                |-> at_device_get_by_name                   /* packages/at_device-v2.0.4/src/at_device.c */
                |-> air720_net_init                         /* 网络初始化,附着网络  */
                    |-> rt_thread_create(air720_init_thread_entry)      /* 线程名字为"air720_net_init",执行各种AT指令初始化网络  */
                    |-> rt_thread_startup(air720_init_thread_entry)     /* 启动网络初始化线程 */
                		|-> air720_power_on
                		|-> ATE0 [disable echo] -> ATI [get module version] -> AT+CPIN? [check SIM card] -> AT+CREG? [check the GSM 							network is registered] -> AT+CGREG? [check the GPRS network is registered] -> AT+CSQ [check signal strength]
                	      -> AT+CGATT? -> AT+CIPSHUT -> AT+CIPMUX=1 [multiple connections] ->  AT+CIPQSEND=1 [fast send mode] -> AT+CSTT 
                	      -> AT+CIICR -> AT+CIFSR
               |-> netdev_low_level_set_status              /* rt-thread/components/net/netdev/src/netdev.c */

/* Air724网络初始化线程 */
air720_init_thread_entry                                        /* packages/at_device-v2.0.4/class/air/at_device_ec200x.c */
    |-> air720_power_on                                
    |-> at_obj_exec_cmd()                                       /* 发送各种AT指令初始化EC200x rt-thread/components/net/at/src/at_client.c */
    |-> ec200x_netdev_set_info                                  
        |-> at_device_get_by_name                               /* packages/at_device-v2.0.4/src/at_device.c */
        |-> netdev_low_level_set_status                         /* rt-thread/components/net/netdev/src/netdev.c */
            |-> netdev->flags |= NETDEV_FLAG_LINK_UP;           /* 网络设备的状态改为连接 */
        |-> netdev_low_level_set_link_status                    /* rt-thread/components/net/netdev/src/netdev.c */
        |-> netdev_low_level_set_dhcp_status                    /* rt-thread/components/net/netdev/src/netdev.c */
        |-> netdev_low_level_set_ipaddr                         /* 设置本地的IP地址 rt-thread/components/net/netdev/src/netdev.c */
        |-> netdev_low_level_set_dns_server                     /* 设置DNS服务器 rt-thread/components/net/netdev/src/netdev.c */
    |-> air720_netdev_check_link_status                         /* 创建链路检测线程*/
        |-> rt_thread_create(check_link_status_entry)           /* 线程名字为"air724_link",创建网络连接状态检查线程 */          
        |-> rt_thread_startup(check_link_status_entry)      

check_link_status_entry           
        |-> at_obj_exec_cmd("AT+CGREG?")    /* 发送AT指令检查网络状态 */
        |-> at_obj_exec_cmd("AT+CSQ?")      /* 发送AT指令检查信号状态 */
    |-> netdev_low_level_set_link_status    /* rt-thread/components/net/netdev/src/netdev.c */

整个网卡注册流程共建立如下三个线程

线程1: client_parser 解析AT指令,处理URC 数据

线程2: air720_init_thread_entry 模组开机,搜寻网络并初始化

线程3: check_link_status_entry 一直轮询设备状态

AT client 对象信息


struct at_client
{
    rt_device_t device;

    at_status_t status;
    char end_sign;

    /* the current received one line data buffer */
    char *recv_line_buf;
    /* The length of the currently received one line data */
    rt_size_t recv_line_len;
    /* The maximum supported receive data length */
    rt_size_t recv_bufsz;
    rt_sem_t rx_notice;
    rt_mutex_t lock;

    at_response_t resp;
    rt_sem_t resp_notice;
    at_resp_status_t resp_status;

    struct at_urc_table *urc_table;
    rt_size_t urc_table_size;

    rt_thread_t parser;
};

AT Socket


struct at_socket
{
    /* AT socket magic word */
    uint32_t magic;

    int socket;
    /* device releated information for the socket */
    void *device;
    /* type of the AT socket (TCP, UDP or RAW) */
    enum at_socket_type type;
    /* current state of the AT socket */
    enum at_socket_state state;
    /* sockets operations */
    const struct at_socket_ops *ops;
    /* receive semaphore, received data release semaphore */
    rt_sem_t recv_notice;
    rt_mutex_t recv_lock;
    rt_slist_t recvpkt_list;

    /* timeout to wait for send or received data in milliseconds */
    int32_t recv_timeout;
    int32_t send_timeout;
    /* A callback function that is informed about events for this AT socket */
    at_socket_callback callback;

    /* number of times data was received, set by event_callback() */
    uint16_t rcvevent;
    /* number of times data was ACKed (free send buffer), set by event_callback() */
    uint16_t sendevent;
    /* error happened for this socket, set by event_callback() */
    uint16_t errevent;

#ifdef SAL_USING_POSIX
    rt_wqueue_t wait_head;
#endif
    rt_slist_t list;

    /* user-specific data */
    void *user_data;
};

/* AT socket operations function */
struct at_socket_ops
{
    int (*at_connect)(struct at_socket *socket, char *ip, int32_t port, enum at_socket_type type, rt_bool_t is_client);
    int (*at_closesocket)(struct at_socket *socket);
    int (*at_send)(struct at_socket *socket, const char *buff, size_t bfsz, enum at_socket_type type);
    int (*at_domain_resolve)(const char *name, char ip[16]);
    void (*at_set_event_cb)(at_socket_evt_t event, at_evt_cb_t cb);
};

AT device class

struct at_device_class
{
    uint16_t class_id;                           /* AT device class ID */
    const struct at_device_ops *device_ops;      /* AT device operaiotns */
#ifdef AT_USING_SOCKET
    uint32_t socket_num;                         /* The maximum number of sockets support */
    const struct at_socket_ops *socket_ops;      /* AT device socket operations */
#endif
    rt_slist_t list;                             /* AT device class list */
};

Netdev


/* network interface device object */
struct netdev
{
    rt_slist_t list;

    char name[RT_NAME_MAX];                            /* network interface device name */
    ip_addr_t ip_addr;                                 /* IP address */
    ip_addr_t netmask;                                 /* subnet mask */
    ip_addr_t gw;                                      /* gateway */
#if NETDEV_IPV6
    ip_addr_t ip6_addr[NETDEV_IPV6_NUM_ADDRESSES];     /* array of IPv6 addresses */
#endif /* NETDEV_IPV6 */
    ip_addr_t dns_servers[NETDEV_DNS_SERVERS_NUM];     /* DNS server */
    uint8_t hwaddr_len;                                /* hardware address length */
    uint8_t hwaddr[NETDEV_HWADDR_MAX_LEN];             /* hardware address */

    uint16_t flags;                                    /* network interface device status flag */
    uint16_t mtu;                                      /* maximum transfer unit (in bytes) */
    const struct netdev_ops *ops;                      /* network interface device operations */

    netdev_callback_fn status_callback;                /* network interface device flags change callback */
    netdev_callback_fn addr_callback;                  /* network interface device address information change callback */

#ifdef RT_USING_SAL
    void *sal_user_data;                               /* user-specific data for SAL */
#endif /* RT_USING_SAL */
    void *user_data;                                   /* user-specific data */
};


/* The network interface device operations */
struct netdev_ops
{
    /* set network interface device hardware status operations */
    int (*set_up)(struct netdev *netdev);
    int (*set_down)(struct netdev *netdev);

    /* set network interface device address information operations */
    int (*set_addr_info)(struct netdev *netdev, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw);
    int (*set_dns_server)(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server);
    int (*set_dhcp)(struct netdev *netdev, rt_bool_t is_enabled);

#ifdef RT_USING_FINSH
    /* set network interface device common network interface device operations */
    int (*ping)(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp);
    void (*netstat)(struct netdev *netdev);
#endif

    /* set default network interface device in current network stack*/
    int (*set_default)(struct netdev *netdev);
};

**AT device **


struct at_device
{
    char name[RT_NAME_MAX];                      /* AT device name */
    rt_bool_t is_init;                           /* AT device initialization completed */
    struct at_device_class *class;               /* AT device class object */
    struct at_client *client;                    /* AT Client object for AT device */
    struct netdev *netdev;                       /* Network interface device for AT device */
#ifdef AT_USING_SOCKET
    rt_event_t socket_event;                     /* AT device socket event */
    struct at_socket *sockets;                   /* AT device sockets list */
#endif
    rt_slist_t list;                             /* AT device list */

    void *user_data;                             /* User-specific data */
};

/* AT device operations */
struct at_device_ops
{
    int (*init)(struct at_device *device);
    int (*deinit)(struct at_device *device);
    int (*control)(struct at_device *device, int cmd, void *arg);
};

posted @ 2022-03-27 21:54  纯洁de小学生  阅读(802)  评论(0编辑  收藏  举报