rtthread-nano AT元件管理Air724
阿新 • • 發佈:2022-03-27
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);
};