當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]本文基于TOS的AT框架,實現(xiàn)了一個基于MX+開發(fā)板的demo,用于控制之前搭的智能小車。

本節(jié)基于TOS的AT框架,我實現(xiàn)了一個基于MX+開發(fā)板的demo,用于控制之前搭的智能小車,效果如下,詳細源碼及實驗例程請參考文末碼云倉庫鏈接:

動手智能小車記(5)-坦克底盤硬件模塊大雜燴

1、什么是AT指令?

在嵌入式開發(fā)過程中,我們有時候要使用一些通信模組,比如藍牙、WIFI、4G、NBIOT等等,這些模組內(nèi)部固件已經(jīng)將協(xié)議棧封裝好了,然后模組硬件向外部提供了標(biāo)準(zhǔn)的串口,這樣通過與模組的串口相連接,就可以與模組進行通信;一般情況下,廠商都會提供模組的使用手冊,只要照著流程去操作模組就可以正常通信了,如下圖所示,這是一個MCU、藍牙模組、手機之間的通信案例:

2、為什么要有AT框架?

一般情況下,在一些物聯(lián)網(wǎng)產(chǎn)品的項目上可能這樣的需求,比如:

常規(guī)的一些傳感器設(shè)備,需要監(jiān)測環(huán)境溫度、濕度等等這樣的情況:

  • 實現(xiàn)數(shù)據(jù)上傳

共享單車、智能門鎖

  • 實現(xiàn)開鎖的邏輯

等等。。。

這些需求看起來就非常簡單,比如我就用ESP8266+一個后臺服務(wù)器來實現(xiàn)這樣的需求吧,只要后臺提供好API接口,那么這類簡單的需求分分鐘搞定,完全沒有任何難度,在應(yīng)用程序上編寫好模組的驅(qū)動接口和通信邏輯就可以了。

但是,如果換一個呢??再換一個呢?有可能實現(xiàn)同樣的需求,我們還要去實現(xiàn)不一樣的驅(qū)動流程,這是不是顯得很麻煩?基于這樣的問題誕生,于是各個廠商分別提出了對應(yīng)的AT框架思維,那么這種AT框架思維具體是什么樣的呢?以驅(qū)動ESP8266為例,一般有以下幾種模式:

  • AP模式
  • STA模式
  • AP+STA模式

以STA模式為例,最后要和云端服務(wù)器進行對接,我們首先要完成初始化流程,一般要發(fā)以下幾個指令:

  • AT+RESTORE\r\n 模組復(fù)位

  • ATE0\r\n 關(guān)閉回顯

  • AT+CWMODE=1\r\n 設(shè)置多連接

  • AT+CIPMODE=0\r\n 關(guān)閉透傳模式

  • AT+CIPMUX=1\r\n 開始多連接模式

  • AT+CWJAP="TOS","12345678"\r\n 連接熱點

這樣就基本完成了模組的初始化流程,初始化完畢以后,就可以進入數(shù)據(jù)傳輸?shù)牧?,連接服務(wù)器,然后開啟透傳模式,進入透傳模式,然后就可以把數(shù)據(jù)直接傳送到后臺了,此時還可以讀取后臺的消息,當(dāng)我們不需要需要模組的時候,還可以將模組掉電;所以,我們可以在這個基礎(chǔ)上把這個驅(qū)動流程框架化,即是擁有初始化、連接服務(wù)器、發(fā)送、接收、關(guān)閉等等這些接口。

3、TencetOS tiny AT框架

在TencentOS tiny中,內(nèi)部就集成了一套簡單易用的AT框架,哪怕是不一樣的指令,我們也只需要填充對應(yīng)的方法,然后注冊到框架上,就可以順利與模組進行通信了,以下是TencentOS tiny AT框架的基本組成圖:

上圖來源于汪兄講解的PPT

對于應(yīng)用開發(fā)者來說,我們最關(guān)注的是SAL interface、也就是網(wǎng)絡(luò)適配框架,只要模組注網(wǎng)成功,那么在這一層,我們不需要具體去關(guān)注模組到底是怎么用AT指令去通信的,我們只需要調(diào)用SAL interface的socket、connect、send、recv、close等等接口完成我們與后臺的通信或者與別的通信方式的邏輯即可,但是調(diào)用SAL接口口還需要去與各個模組進行適配。

typedef?struct?sal_module_st?{
????int?(*init)(void);

????int?(*get_local_mac)(char?*mac);

????int?(*get_local_ip)(char?*ip,?char?*gw,?char?*mask);

????int?(*parse_domain)(const?char?*host_name,?char?*host_ip,?size_t?host_ip_len);

????int?(*connect)(const?char?*ip,?const?char?*port,?sal_proto_t?proto);

????int?(*send)(int?sock,?const?void?*buf,?size_t?len);

????int?(*recv_timeout)(int?sock,?void?*buf,?size_t?len,?uint32_t?timeout);

????int?(*recv)(int?sock,?void?*buf,?size_t?len);

????int?(*sendto)(int?sock,?char?*ip,?char?*port,?const?void?*buf,?size_t?len);

????int?(*recvfrom)(int?sock,?void?*buf,?size_t?len);

????int?(*recvfrom_timeout)(int?sock,?void?*buf,?size_t?len,?uint32_t?timeout);

????int?(*close)(int?sock);
}?sal_module_t;

對于怎么去綁定(適配)模組和SAL interface,在此之前那我們還需要完成AT framework與HAL(uart)的適配,然后提供SAL interface需要的接口,注冊上去,這樣我們就可以在SAL上愉快的進行操作了,接下來AT框架具體是怎么解析每個AT指令我們就不需要特別去關(guān)心了,感興趣的可以去研究一下tos_at.c、tos_at.h這兩個文件。

在TencentOS tiny SDK中,騰訊官方已經(jīng)提供了一些熱門模組的操作例程,比如esp8266,它是怎么與SAL interface完成適配的呢?如下:

上圖來源于戴兄講解的PPT


這樣的話,我們就可以調(diào)用TOS提供的SAL接口進行通信了,如下,在sal_module_wrapper.h中查看,詳細實現(xiàn)在sal_module_wrapper.c:

/**
?*?@brief?Convert?domain?to?ip?address.
?*
?*?@attention?None
?*
?*?@param[in]???host_name???domain?name?of?the?host
?*?@param[out]??host_ip?????ip?address?of?the?host
?*?@param[out]??host_ip_len?ip?address?buffer?length
?*
?*?@return??errcode
?*/
int?tos_sal_module_parse_domain(const?char?*host_name,?char?*host_ip,?size_t?host_ip_len);

/**
?*?@brief?Connect?to?remote?host.
?*
?*?@attention?None
?*
?*?@param[in]???ip??????ip?address?of?the?remote?host
?*?@param[in]???port????port?number?of?the?remote?host
?*?@param[in]???proto???protocol?of?the?connection(TCP/UDP)
?*
?*?@return??socket?id?if?succuss,?-1?if?failed.
?*/
int?tos_sal_module_connect(const?char?*ip,?const?char?*port,?sal_proto_t?proto);

/**
?*?@brief?Send?data?to?the?remote?host(TCP).
?*
?*?@attention?None
?*
?*?@param[in]???sock????socket?id
?*?@param[in]???buf?????data?to?send
?*?@param[in]???len?????data?length
?*
?*?@return??data?length?sent
?*/
int?tos_sal_module_send(int?sock,?const?void?*buf,?size_t?len);

/**
?*?@brief?Receive?data?from?the?remote?host(TCP).
?*
?*?@attention?None
?*
?*?@param[in]???sock????socket?id
?*?@param[in]???buf?????data?buffer?to?hold?the?data?received
?*?@param[in]???len?????data?buffer?length
?*
?*?@return??data?length?received
?*/
int?tos_sal_module_recv(int?sock,?void?*buf,?size_t?len);

/**
?*?@brief?Receive?data?from?the?remote?host(TCP).
?*
?*?@attention?None
?*
?*?@param[in]???sock????socket?id
?*?@param[in]???buf?????data?buffer?to?hold?the?data?received
?*?@param[in]???len?????data?buffer?length
?*?@param[in]???timeout?timeout
?*
?*?@return??data?length?received
?*/
int?tos_sal_module_recv_timeout(int?sock,?void?*buf,?size_t?len,?uint32_t?timeout);

/**
?*?@brief?Send?data?to?the?remote?host(UDP).
?*
?*?@attention?None
?*
?*?@param[in]???sock????socket?id
?*?@param[in]???ip??????ip?address?of?the?remote?host
?*?@param[in]???port????port?number?of?the?remote?host
?*?@param[in]???buf?????data?to?send
?*?@param[in]???len?????data?length
?*
?*?@return??data?length?sent
?*/
int?tos_sal_module_sendto(int?sock,?char?*ip,?char?*port,?const?void?*buf,?size_t?len);

/**
?*?@brief?Receive?data?from?the?remote?host(UDP).
?*
?*?@attention?None
?*
?*?@param[in]???sock????socket?id
?*?@param[in]???buf?????data?buffer?to?hold?the?data?received
?*?@param[in]???len?????data?buffer?length
?*
?*?@return??data?length?received
?*/
int?tos_sal_module_recvfrom(int?sock,?void?*buf,?size_t?len);

/**
?*?@brief?Receive?data?from?the?remote?host(UDP).
?*
?*?@attention?None
?*
?*?@param[in]???sock????socket?id
?*?@param[in]???buf?????data?buffer?to?hold?the?data?received
?*?@param[in]???len?????data?buffer?length
?*?@param[in]???timeout?timeout
?*
?*?@return??data?length?received
?*/
int?tos_sal_module_recvfrom_timeout(int?sock,?void?*buf,?size_t?len,?uint32_t?timeout);

/**
?*?@brief?Close?the?connection.
?*
?*?@attention?None
?*
?*?@param[in]???sock????socket?id
?*
?*?@return??errcode
?*/
int?tos_sal_module_close(int?sock);

但是你以為這就完了嗎?為了和Posix API無差異化調(diào)用,TencentOS tiny官方開發(fā)人員開發(fā)了一套近似于通用網(wǎng)絡(luò)操作接口,就類似操作一個文件一樣open、read、write、close,這不就更簡單了嘛?我們來一睹為快:

tos_at_socket.h

#ifndef??_TOS_AT_SOCKET_H_
#define??_TOS_AT_SOCKET_H_

#include?"tos_at_socket_lib.h"
#include?"tos_at_socket_types.h"

#define?AF_INET?????????????0

#define?AF_INET6????????????1

#define?AF_UNIX?????????????2

/*?Provides?sequenced,?reliable,?bidirectional,?connection-mode?byte?streams,?and?may?provide?a?transmission?mechanism?for?out-of-band?data.?*/
#define?SOCK_STREAM?????????0

/*?Provides?datagrams,?which?are?connectionless-mode,?unreliable?messages?of?fixed?maximum?length.?*/
#define?SOCK_DGRAM??????????1

/*?Peeks?at?an?incoming?message.?The?data?is?treated?as?unread?and?the?next?recv()?or?similar?function?shall?still?return?this?data.?*/
#define?MSG_PEEK????????????0x01

/*?Requests?out-of-band?data.?The?significance?and?semantics?of?out-of-band?data?are?protocol-specific.?*/
#define?MSG_OOB?????????????0x02

/*?On?SOCK_STREAM?sockets?this?requests?that?the?function?block?until?the?full?amount?of?data?can?be?returned.?The?function?may?return?the?smaller?amount?of?data?if?the?socket?is?a?message-based?socket,?if?a?signal?is?caught,?if?the?connection?is?terminated,?if?MSG_PEEK?was?specified,?or?if?an?error?is?pending?for?the?socket.?*/
#define?MSG_WAITALL?????????0x04

int?socket(int?domain,?int?type,?int?protocol);

int?connect(int?socket,?const?struct?sockaddr?*address,?socklen_t?address_len);

int?recv(int?socket,?void?*buffer,?size_t?length,?int?flags);

int?recvfrom(int?socket,?void?*?buffer,?size_t?length,?int?flags,?struct?sockaddr?*address,?socklen_t?*address_len);

int?send(int?socket,?const?void?*buffer,?size_t?length,?int?flags);

int?sendto(int?socket,?const?void?*message,?size_t?length,?int?flags,?const?struct?sockaddr?*dest_addr,?socklen_t?dest_len);

int?shutdown(int?socket,?int?how);

int?read(int?socket,?void?*buffer,?size_t?length);

int?close(int?socket);

int?write(int?socket,?const?void?*buffer,?size_t?length);

#endif?/*?_TOS_AT_SOCKET_H_?*/

只要注冊框架等流程完成以后,模組注網(wǎng)成功,后面就可以直接這樣常規(guī)操作了:

void?network_demo(void)
{
????int?recv_len?=?-1;
????int?fd,?rc,?cnt?=?0;

????struct?sockaddr_in?addr;

????bzero(&addr,?sizeof(addr));
????addr.sin_family?=?AF_INET;
????addr.sin_addr.s_addr?=?inet_addr(SERVER_IP);
????addr.sin_port?=?htons(SERVER_PORT);

????fd?=?socket(AF_INET,?SOCK_STREAM,?0);

????if?(fd?????{
????????printf("socket?failed\n");
????????return;
????}

????rc?=?connect(fd,?(struct?sockaddr?*)&addr,?sizeof(addr));

????if?(rc?????{
????????printf("connect?failed\n");
????????close(fd);
????????return;
????}
?
? while(1)
? {
?? //調(diào)用send發(fā)送數(shù)據(jù)
?? //調(diào)用recv接收并處理數(shù)據(jù)
? }
?
? close(fd);
}

基于TencentOS tiny AT框架的基礎(chǔ)上,我編寫了一個基于MX+開發(fā)板的控制小車?yán)?,源碼已更新到碼云個人倉庫。

個人碼云倉庫地址:

https://gitee.com/morixinguan

我還將之前做的一些項目以及練習(xí)例程在近期內(nèi)全部上傳完畢,與大家一起分享交流:

全文參考資料

騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)SDK文檔.pdf

騰訊物聯(lián)網(wǎng)終端操作系統(tǒng)開發(fā)指南.pdf

TencentOS tiny技術(shù)講解與開發(fā)實踐PPT.pdf

云加社區(qū)沙龍(騰訊物聯(lián)網(wǎng)操作系統(tǒng)TencentOS tiny架構(gòu)解析與實踐).pdf

公眾號粉絲福利時刻

這里我給大家申請到了福利,本公眾號讀者購買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購買小熊派以及騰訊物聯(lián)網(wǎng)開發(fā)板的朋友,淘寶搜索即可,跟客服說你是公眾號:嵌入式云IOT技術(shù)圈 的粉絲,立享9折優(yōu)惠!

往期精彩

TencentOS tiny RTOS快速入門

網(wǎng)紅騰訊物聯(lián)網(wǎng)開發(fā)板終極開箱評測,讓我們一睹為快!

Linux進程間通信(中)之信號、信號量實踐

Linux進程間通信(下)之共享內(nèi)存實踐

STM32硬核DIY機械鍵盤|藍牙USB雙模|燈控

覺得本次分享的文章對您有幫助,隨手點[在看]并轉(zhuǎn)發(fā)分享,也是對我的支持。

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉