??AT組件的核心處理邏輯是將收到的 AT 模組的應(yīng)答信息放到 recv_line_buf 緩沖區(qū)中,然后每次讀一行數(shù)據(jù)("\r\n")進(jìn)行處理,然后判斷屬于哪一類的消息,調(diào)用不同的函數(shù)。
??本文以 EC200x 模組為例,詳細(xì)分析了 AT 組件的實現(xiàn)過程和代碼的調(diào)用邏輯,幫助在使用 AT 組件過程中遇到問題的開發(fā)者快速定位問題出現(xiàn)的位置。
1 AT 組件
1.1 AT 組件調(diào)試信息級別設(shè)置
??可以通過修改 env 中的如下內(nèi)容來控制是否啟用 AT 組件的 debug log 功能,開啟后可以看到日志級別為 debug 的相關(guān)日志。使能該選項后將在 `rtconfig.h` 中生成 `#define AT_DEBUG`,AT 組件日志級別的控制是在 `rt-thread/components/net/at/include/at_log.h` 文件中實現(xiàn)的。
RT-Thread Components
-> Network
-> AT commands
-> [*] Enable debug log output /* 選中表示修改日志級別為 debug */
??特別注意:打開上述功能后,ec200x 線程(在 packages/at_device-2.0.4/class/ec200x/at_device_ec200x.c 文件中由 ec200x_netdev_check_link_status() 函數(shù)創(chuàng)建)會提示棧溢出,使用的棧空間約為 1598Bytes,建議將 ec200x_netdev_check_link_status() 函數(shù)中的 EC200X_LINK_THREAD_STACK_SIZE 宏更改為 1024 +1024 即 2048 個字節(jié),以解決棧溢出的問題。
1.2 AT 命令打印使能設(shè)置
??在調(diào)試時可以通過修改 env 中的如下內(nèi)容來控制是否使能 AT 組件的收發(fā) AT 指令的顯示,開啟后可以看到每次執(zhí)行的 AT 指令以及返回的執(zhí)行結(jié)果。
RT-Thread Components
-> Network
-> AT commands
-> [*] Enable print RAW format AT command communication data /* 選中表示打印執(zhí)行的AT指令 */
??上述選項選中后,在執(zhí)行測試時,打印的 AT 指令示例如下
[D/AT] recvline: 0000-0020: 41 54 0D 0D 0A AT...
[D/AT] recvline: 0000-0020: 4F 4B 0D 0A OK..
[D/AT] sendline: 0000-0020: 41 54 45 30 ATE0
[D/AT] recvline: 0000-0020: 41 54 45 30 0D 0D 0A ATE0...
[D/AT] recvline: 0000-0020: 4F 4B 0D 0A OK..
[D/AT] sendline: 0000-0020: 41 54 2B 49 50 52 3F AT+IPR?
01-01 00:40:19 D/at.clnt: execute command (AT+IPR?) timeout (300 ticks)!
[D/AT] recvline: 0000-0020: 0D 0A ..
[D/AT] recvline: 0000-0020: 2B 49 50 52 3A 20 31 31 35 32 30 30 0D 0A +IPR: 115200..
[D/AT] recvline: 0000-0020: 0D 0A ..
[D/AT] recvline: 0000-0020: 4F 4B 0D 0A OK..
[D/AT] recvline: 0000-0020: 0D 0A ..
[D/AT] recvline: 0000-0020: 52 44 59 0D 0A RDY..
01-01 00:40:22 I/at.dev.ec200x: ec200x device initialize retry...
[D/AT] sendline: 0000-0020: 41 54 45 30 ATE0
01-01 00:40:24 D/at.clnt: execute command (ATE0) timeout (300 ticks)!
[D/AT] recvline: 0000-0020: 0D 0A ..
[D/AT] recvline: 0000-0020: 4F 4B 0D 0A OK..
[D/AT] recvline: 0000-0020: 0D 0A ..
[D/AT] recvline: 0000-0020: 4F 4B 0D 0A OK..
1.3 GPRS 網(wǎng)絡(luò)注冊狀態(tài)檢查
??AT組件中會自動創(chuàng)建一個 GPRS 網(wǎng)絡(luò)注冊狀態(tài)檢查的線程,使用 "AT+CGREG?" 指令進(jìn)行 GPRS 網(wǎng)絡(luò)注冊狀態(tài)的檢查,并根據(jù)指令返回的結(jié)果修改網(wǎng)卡設(shè)備的標(biāo)志位,該指令返回結(jié)果中的 等于 1 或者 5,表示模塊已在 UMTS/LTE 網(wǎng)絡(luò)注冊上 PS 業(yè)務(wù)。
??GPRS 網(wǎng)絡(luò)注冊狀態(tài)檢查線程的名字是模擬網(wǎng)卡的名字,在本例中為 "ec200x",線程的入口函數(shù)是 ec200x_check_link_status_entry(packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c),該線程沒間隔 60s 發(fā)送一條 AT 指令進(jìn)行 GPRS 網(wǎng)絡(luò)注冊狀態(tài)的檢查,并根據(jù)返回的結(jié)果在函數(shù) netdev_low_level_set_link_status` 中修改 `netdev->flags。各種情況的執(zhí)行結(jié)果分析如下所示
上一次網(wǎng)絡(luò)注冊狀態(tài) | 這次網(wǎng)絡(luò)注冊狀態(tài) | 操作1 | 操作2 |
未注冊 | 未注冊 | 無 | 無 |
未注冊 | 注冊 | 標(biāo)記 netdev->flags 的 NETDEV_FLAG_LINK_UP 標(biāo)志 | 調(diào)用 sal_check_netdev_internet_up() 函數(shù)將任務(wù)放入 sys_work 隊列,然后通過和 "link.rt-thread.org" 的 8101 端口交互來修改 netdev->flags 中的 NETDEV_FLAG_INTERNET_UP 標(biāo)志 |
注冊 | 未注冊 | 清除 netdev->flags 的 NETDEV_FLAG_LINK_UP 和 NETDEV_FLAG_INTERNET_UP 標(biāo)志 | 調(diào)用 netdev_auto_change_default() 函數(shù)切換到第一個連接的網(wǎng)絡(luò)設(shè)備,本例中只用到了一個網(wǎng)絡(luò)設(shè) |
注冊 | 注冊 | 無 | 無 |
??特別注意:GPRS 網(wǎng)絡(luò)注冊狀態(tài)檢查線程會檢查模組的 power_status,power_status 在 ec200x_init() 函數(shù)中默認(rèn)初始化為 RT_FALSE,然后在名為 "ec200x_net" 的線程的 ec200x_init_thread_entry() 線程入口函數(shù)中調(diào)用 ec200x_power_on() 函數(shù)來修改 power_status 的值。ec200x_power_on() 函數(shù)中 power_status 的值修改為 RT_TRUE 依賴于 power_pin 引腳的定義,因此在 env 中必須定義 power_pin 的編號,默認(rèn)為 -1,定義規(guī)則在文件 drivers/drv_gpio.c 中。另外還需要注意的是在代碼中 power_pin 為低電平表示模組處于上電狀態(tài),power_pin 為高電平表示模組處于斷電狀態(tài)。
??power_pin 編號的定義在禁用網(wǎng)卡(netdev_set_down)與啟用網(wǎng)卡(netdev_set_up)的實現(xiàn)中也至關(guān)重要,網(wǎng)卡的禁用與啟用最終實際調(diào)用的函數(shù)為 ec200x_power_off() 和 ec200x_power_on(),因此必須定義power_pin 的編號,網(wǎng)卡禁用與啟用的示例代碼如下
/* "ec200x" 名字來源于設(shè)備注冊時使用的名字,在文件 packages/at_device-v2.0.4/samples/at_sample_ec200x.c 中定義 */
struct at_device * dev = at_device_get_by_name(AT_DEVICE_NAMETYPE_NETDEV, "ec200x");/* 根據(jù)名字查找 AT 設(shè)備 */
netdev_set_up(dev->netdev); /* 啟用相應(yīng)的網(wǎng)卡設(shè)備 */
netdev_set_down(dev->netdev); /* 禁用相應(yīng)的網(wǎng)卡設(shè)備 */
1.4 EC200x 是否能連接外網(wǎng)日志輸出
??rt-thread/components/net/sal_socket/src/sal_socket.c 中 check_netdev_internet_up_work() 函數(shù)會自動連接 "link.rt-thread.org"` 的 `8101 端口進(jìn)行數(shù)據(jù)收發(fā)測試,從而判斷是否可以連接外網(wǎng)。該文件中默認(rèn)的打印級別為 DBG_INFO,為了方便看出是否可以連接外網(wǎng),將 check_netdev_internet_up_work() 函數(shù)結(jié)尾的部分的測試結(jié)果打印由 LOG_D 修改為 LOG_I。
??該函數(shù)的執(zhí)行的過程大致為在 ec200x 初始化線程 ec200x_init_thread_entry() 中將將外網(wǎng)檢查任務(wù)提交到 sys_work 工作隊列中,系統(tǒng)工作隊列處理線程 _workqueue_thread_entry() 會不斷的檢測是否有需要運行的任務(wù),如果有則執(zhí)行相應(yīng)的任務(wù),即執(zhí)行外網(wǎng)連接檢查任務(wù)。外網(wǎng)連接檢查任務(wù)提交到工作隊列的執(zhí)行過程如下
ec200x_init_thread_entry /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_power_on /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> at_obj_exec_cmd() /* 發(fā)送各種AT指令初始化EC200x rt-thread/components/net/at/src/at_client.c */
|-> ec200x_netdev_set_info /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> 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; /* 網(wǎng)絡(luò)設(shè)備的狀態(tài)改為連接 */
|-> 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 /* 設(shè)置本地的IP地址 rt-thread/components/net/netdev/src/netdev.c */
|-> sal_check_netdev_internet_up /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> rt_delayed_work_init(net_work, check_netdev_internet_up_work) /* 初始化外網(wǎng)連接檢查任務(wù) rt-thread/components/drivers/src/workqueue.c */
|-> (&work->work)->work_func = check_netdev_internet_up_work
|-> rt_work_submit(&(net_work->work), RT_TICK_PER_SECOND); /* rt-thread/components/drivers/src/workqueue.c */
|-> rt_workqueue_submit_work(sys_workq, work, time) /* 將任務(wù)提交到系統(tǒng)工作隊列里面 rt-thread/components/drivers/src/workqueue.c */
|-> netdev_low_level_set_dns_server /* 設(shè)置DNS服務(wù)器 rt-thread/components/net/netdev/src/netdev.c */
|-> ec200x_netdev_check_link_status /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> rt_thread_create(ec200x_check_link_status_entry) /* 線程名字為"ec200x",創(chuàng)建 GPRS 網(wǎng)絡(luò)注冊狀態(tài)檢查線程 packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> rt_thread_startup(ec200x_check_link_status_entry) /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
/* GPRS 網(wǎng)絡(luò)注冊狀態(tài)檢查線程 */
ec200x_check_link_status_entry /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_check_link_status /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> at_obj_exec_cmd("AT+CGREG?") /* 發(fā)送AT指令檢查網(wǎng)絡(luò)狀態(tài) */
|-> netdev_low_level_set_link_status /* rt-thread/components/net/netdev/src/netdev.c */
??系統(tǒng)工作隊列初始化和任務(wù)執(zhí)行過程如下
rt_work_sys_workqueue_init /* rt-thread/components/drivers/src/workqueue.c */
|-> rt_workqueue_create("sys_work") /* 創(chuàng)建系統(tǒng)工作隊列 rt-thread/components/drivers/src/workqueue.c */
|-> rt_thread_create(_workqueue_thread_entry) /* 線程名字為"sys_work",創(chuàng)建隊列線程 rt-thread/components/drivers/src/workqueue.c */
_workqueue_thread_entry /* 系統(tǒng)工作隊列處理線程 rt-thread/components/drivers/src/workqueue.c */
|-> if(rt_list_isempty)
|-> rt_thread_suspend(rt_thread_self()); /* 掛起自身 */
|-> rt_schedule(); /* 任務(wù)列表為空,掛起自身,切換線程 */
|-> rt_hw_interrupt_disable /* 任務(wù)列表不為空,依次往下執(zhí)行,關(guān)閉中斷 */
|-> rt_list_entry /* 找到要處理的任務(wù)節(jié)點 */
|-> rt_list_remove /* 將找到的任務(wù)節(jié)點從任務(wù)列表中移除 */
|-> rt_hw_interrupt_enable /* 使能中斷 */
|-> work->work_func(work, work->work_data); /* 執(zhí)行任務(wù) */
??外網(wǎng)連接檢查任務(wù)的執(zhí)行過程如下
check_netdev_internet_up_work /* 外網(wǎng)連接檢查任務(wù) rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> 與 "link.rt-thread.org" 的 8101 端口建立連接,進(jìn)行收發(fā)數(shù)據(jù)測試
|-> 打印測試結(jié)果
|-> 收發(fā)測試成功 LOG_I("Set network interface device(%s) internet status up.", netdev->name);
|-> netdev->flags |= NETDEV_FLAG_INTERNET_UP;
|-> 收發(fā)測試失敗 LOG_I("Set network interface device(%s) internet status down.", netdev->name);
|-> netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
1.5 AT 設(shè)備注冊過程
at_device_register /* packages/at_device-v2.0.4/samples/at_sample_ec200x.c */
|-> class = at_device_class_get(class_id) /* packages/at_device-v2.0.4/src/at_device.c */
|-> class->device_ops->init(device) /* packages/at_device-v2.0.4/src/at_device.c */
|-> ec200x_init /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x->power_status = RT_FALSE; /* default power is off. packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x->sleep_status = RT_FALSE; /* default sleep is disabled. packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> 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",創(chuàng)建AT解析線程 components/net/at/src/at_client.c */
|-> client_parser /* AT解析線程的具體實現(xiàn) components/net/at/src/at_client.c */
|-> rt_device_find /* 尋找串口設(shè)備 rt-thread/src/device.c */
|-> rt_device_open /* 打開串口設(shè)備 rt-thread/src/device.c */
|-> rt_thread_startup(client->parser) /* rt-thread/src/thread.c */
|-> ec200x_socket_init /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> ec200x_netdev_add("ec200x") /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> netdev_get_by_name("ec200x") /* rt-thread/components/net/netdev/src/netdev.c */
|-> netdev->ops = &ec200x_netdev_ops; /* 網(wǎng)絡(luò)設(shè)備操作集 packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> sal_at_netdev_set_pf_info /* rt-thread/components/net/sal_socket/impl/af_inet_at.c */
|-> 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 */
|-> ec200x->power_pin /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x->power_status_pin /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x->wakeup_pin /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_netdev_set_up /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> at_device_get_by_name /* packages/at_device-v2.0.4/src/at_device.c */
|-> ec200x_net_init /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> rt_thread_create(ec200x_init_thread_entry) /* 線程名字為"ec200x_net",執(zhí)行各種AT指令初始化網(wǎng)絡(luò) packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> rt_thread_startup(ec200x_init_thread_entry) /* 啟動網(wǎng)絡(luò)初始化線程 packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> netdev_low_level_set_status /* rt-thread/components/net/netdev/src/netdev.c */
1.6 AT 設(shè)備類注冊過程
ec200x_device_class_register /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_socket_class_register /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> class->socket_num = AT_DEVICE_EC200X_SOCKETS_NUM; /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> class->socket_ops = &ec200x_socket_ops; /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> class->device_ops = &ec200x_device_ops; /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> at_device_class_register /* packages/at_device-v2.0.4/src/at_device.c */
1.7 網(wǎng)卡的啟用與禁用
1.7.1 啟用網(wǎng)卡的執(zhí)行過程
/* 啟用網(wǎng)卡 */
netdev_set_up(netdev) /* components/net/netdev/src/netdev.c */
|-> netdev->ops->set_up(netdev) /* netdev->ops = &ec200x_netdev_ops; packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_netdev_set_up ------------------------------| /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_net_init | /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_init_thread_entry | /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|
/* module init */ |
ec200x_init | /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> at_client_init | /* components/net/at/src/at_client.c */
|-> ec200x_socket_init | /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> ec200x_netdev_add | /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> netdev_register | /* rt-thread/components/net/netdev/src/netdev.c */
|-> ec200x_netdev_set_up ----------------------------------| /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_net_init /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_init_thread_entry /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
1.7.2 禁用網(wǎng)卡的執(zhí)行過程
/* 禁用網(wǎng)卡 */
netdev_set_down(netdev) /* components/net/netdev/src/netdev.c */
|-> netdev->ops->set_down(netdev); /* components/net/netdev/src/netdev.c */
|-> ec200x_netdev_set_down ----------------------------| /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_power_off | /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> netdev_low_level_set_status(netdev, RT_FALSE) | /* rt-thread/components/net/netdev/src/netdev.c */
|-> netdev->flags &= ~NETDEV_FLAG_UP | /* rt-thread/components/net/netdev/src/netdev.c */
|-> netdev_auto_change_default | /* rt-thread/components/net/netdev/src/netdev.c */
|
/* module deinit */ |
ec200x_deinit | /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_netdev_set_down --------------------------------| /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
|-> ec200x_power_off /* packages/at_device-v2.0.4/class/ec200x/at_device_ec200x.c */
1.8 socket 編程源碼分析
1.8.1 socket 執(zhí)行過程
#define socket(domain, type, protocol) sal_socket(domain, type, protocol) /* rt-thread/components/net/sal_socket/include/socket/sys_socket/sys/socket.h */
|-> sal_socket /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> socket_new /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> socket_alloc /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock = st->sockets[idx]; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock->socket = idx + SAL_SOCKET_OFFSET; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock->magic = SAL_SOCKET_MAGIC; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock->netdev = RT_NULL; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock->user_data = RT_NULL; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sal_get_socket /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> socket_init /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock->netdev = netdev; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_SOCKETOPS_VALID /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> pf->skt_ops->socket /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> at_socket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> alloc_socket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> sock->type = socket_type; /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> sock->state = AT_SOCKET_OPEN; /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> sock->ops->at_set_event_cb(AT_SOCKET_EVT_RECV, at_recv_notice_cb); /* 設(shè)置接收回調(diào)函數(shù) rt-thread/components/net/at/at_socket/at_socket.c */
|-> ec200x_socket_set_event_cb /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> at_evt_cb_set[event] = cb; /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> sock->ops->at_set_event_cb(AT_SOCKET_EVT_CLOSED, at_closed_notice_cb); /* 設(shè)置關(guān)閉套接字回調(diào)函數(shù) rt-thread/components/net/at/at_socket/at_socket.c */
|-> ec200x_socket_set_event_cb /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> at_evt_cb_set[event] = cb; /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
1.8.2 connect 函數(shù)執(zhí)行過程
#define connect(s, name, namelen) sal_connect(s, name, namelen) /* rt-thread/components/net/sal_socket/include/socket/sys_socket/sys/socket.h */
|-> sal_connect /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_SOCKET_OBJ_GET /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_IS_UP /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_SOCKETOPS_VALID /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> pf->skt_ops->connect /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> at_connect /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> at_get_socket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> sock->ops->at_connect /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> ec200x_socket_connect /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c *
1.8.3 send 函數(shù)執(zhí)行過程
#define send(s, dataptr, size, flags) sal_sendto(s, dataptr, size, flags, NULL, NULL) /* rt-thread/components/net/sal_socket/include/socket/sys_socket/sys/socket.h */
#define sendto(s, dataptr, size, flags, to, tolen) sal_sendto(s, dataptr, size, flags, to, tolen) /* rt-thread/components/net/sal_socket/include/socket/sys_socket/sys/socket.h */
|-> sal_sendto /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_SOCKET_OBJ_GET /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_IS_UP /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_SOCKETOPS_VALID /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> pf->skt_ops->sendto /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> at_sendto /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> at_get_socket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> sock->ops->at_send /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> ec200x_socket_send /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
1.8.4 recv 函數(shù)執(zhí)行過程
??recv() 函數(shù)執(zhí)行時,EC200x 接收的 URC 函數(shù)將數(shù)據(jù)放到 `recvpkt_list` 中,然后 recv() 函數(shù)從 `recvpkt_list` 中取出數(shù)據(jù)。
#define recv(s, mem, len, flags) sal_recvfrom(s, mem, len, flags, NULL, NULL) /* rt-thread/components/net/sal_socket/include/socket/sys_socket/sys/socket.h */
#define recvfrom(s, mem, len, flags, from, fromlen) sal_recvfrom(s, mem, len, flags, from, fromlen) /* rt-thread/components/net/sal_socket/include/socket/sys_socket/sys/socket.h */
|-> sal_recvfrom /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_SOCKET_OBJ_GET /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_IS_UP /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_SOCKETOPS_VALID /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> pf->skt_ops->recvfrom /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> at_recvfrom /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> at_get_socket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> at_recvpkt_get(&(sock->recvpkt_list)...) /* 從鏈表中獲取數(shù)據(jù) rt-thread/components/net/at/at_socket/at_socket.c */
/* EC200x 接收的 URC 函數(shù) */
urc_recv_func /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> recv_buf = (char *) rt_calloc(1, bfsz); /* 申請空間,供 at_recv_pkt 使用,掛載在 rlist 列表中 */
|-> at_client_obj_recv /* rt-thread/components/net/at/src/at_client.c */
|-> at_client_getchar /* rt-thread/components/net/at/src/at_client.c */
|-> at_evt_cb_set[AT_SOCKET_EVT_RECV](socket, AT_SOCKET_EVT_RECV, recv_buf, bfsz); /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> at_recv_notice_cb /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> at_recvpkt_put(&(sock->recvpkt_list), buff, bfsz); /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> pkt->buff = (char *) ptr; /* 將buff指向之前申請到的空間 rt-thread/components/net/at/at_socket/at_socket.c */
|-> rt_slist_append /* 掛載到鏈表中 */
1.8.5 closesocket 函數(shù)執(zhí)行過程
#define closesocket(s) sal_closesocket(s) /* rt-thread/components/net/sal_socket/include/socket/sys_socket/sys/socket.h */
|-> sal_closesocket /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_SOCKET_OBJ_GET /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> SAL_NETDEV_SOCKETOPS_VALID /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> pf->skt_ops->closesocket /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> at_closesocket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> sock->ops->at_closesocket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> ec200x_socket_close /* packages/at_device-v2.0.4/class/ec200x/at_socket_ec200x.c */
|-> free_socket /* rt-thread/components/net/at/at_socket/at_socket.c */
|-> socket_delete /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock = sal_get_socket(socket); /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock->magic = 0; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> sock->netdev = RT_NULL; /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> socket_free /* rt-thread/components/net/sal_socket/src/sal_socket.c */
|-> rt_free(sock); /* rt-thread/src/memheap.c */
|-> rt_memheap_free /* rt-thread/src/memheap.c */
審核編輯:湯梓紅
-
AT
+關(guān)注
關(guān)注
2文章
192瀏覽量
65202 -
組件
+關(guān)注
關(guān)注
1文章
512瀏覽量
17813 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1285瀏覽量
40079
發(fā)布評論請先 登錄
相關(guān)推薦
評論