EZ-Link是RDA物聯(lián)網(wǎng)應(yīng)用集成開(kāi)發(fā)平臺(tái),該平臺(tái)包括SDK開(kāi)發(fā)包,Eclipse集成開(kāi)發(fā)環(huán)境,調(diào)試工具和燒錄工具。SDK開(kāi)發(fā)包提供了在EZ-Link平臺(tái)進(jìn)行物聯(lián)網(wǎng)開(kāi)發(fā)必需的模塊和標(biāo)準(zhǔn)API接口,同時(shí)通過(guò)對(duì)硬件層抽象,提供對(duì)RDA物聯(lián)網(wǎng)系列芯片的全面支持。
RDA物聯(lián)網(wǎng)系列芯片即有獨(dú)立藍(lán)牙、WIFI芯片,也有在SoC上集成Wi-Fi、Bluetooth和GSM功能的組合芯片,并提供包括UART/ADC/I2S在內(nèi)的硬件接口。
RDA特有的共存技術(shù)使用戶(hù)可以獨(dú)立或并行使用Wi-Fi及藍(lán)牙功能。
本文闡述EZ-Link平臺(tái)SDK的主要功能和使用方法。本文所描述SDK為精簡(jiǎn)版,該版本針對(duì)物聯(lián)網(wǎng)設(shè)備開(kāi)發(fā)周期短、市場(chǎng)反應(yīng)敏感等特點(diǎn),對(duì)EZ-Link SDK進(jìn)行了一系列優(yōu)化升級(jí),以幫助客戶(hù)提高開(kāi)發(fā)效率。用戶(hù)僅需要了解必要的接口,然后通過(guò)SDK提供的豐富示例代碼,簡(jiǎn)單修改甚至零修改就可以實(shí)現(xiàn)一款完整的物聯(lián)網(wǎng)應(yīng)用。
1.1 PCB設(shè)計(jì)
硬件層 |
硬件抽象層 |
驅(qū)動(dòng)和操作系統(tǒng)層 |
服務(wù)層 |
應(yīng)用程序?qū)?/strong> |
芯片模塊化 | RDA 芯片為本SDK設(shè)計(jì)參照的核心,芯片類(lèi)型決定系統(tǒng)的CPU硬件架構(gòu)、IO接口、總線等特性,進(jìn)而影響服務(wù)層提供的服務(wù)、產(chǎn)品特性和源碼編譯等。芯片模塊化使用戶(hù)在無(wú)需修改上層軟件的情況下,根據(jù)需求選擇適當(dāng)?shù)男酒?/div> |
操作系統(tǒng)模塊化 | 目前市面上嵌入式實(shí)時(shí)操作系統(tǒng)種類(lèi)繁多,用戶(hù)可以根據(jù)自己的偏好和使用習(xí)慣選擇操作系統(tǒng)而不影響其他應(yīng)用 |
驅(qū)動(dòng)模塊化 | 用戶(hù)通常有更換外設(shè)的需求,驅(qū)動(dòng)模塊化正是滿(mǎn)足該項(xiàng)需求 |
服務(wù)模塊化 | 服務(wù)層模塊化,有效減少各個(gè)子模塊之間耦合,方便用戶(hù)刪減與特定產(chǎn)品無(wú)關(guān)服務(wù),添加新服務(wù) |
特性 |
SDK源碼目錄結(jié)構(gòu) |

目錄 | 說(shuō)明 | |
apps | 客戶(hù)應(yīng)用程序和RDA示例代碼 | |
platform | RDA IOT平臺(tái)代碼,其下包括:chip、edrv、 rtos、 service等子目錄,子目錄會(huì)在下面依次說(shuō)明 | |
chip | 平臺(tái)芯片相關(guān)代碼,包括:boot loader,hal層,寄存器地址定義和rom代碼。通常用戶(hù)無(wú)需修改rom代碼 | |
edrv | 包括外設(shè)驅(qū)動(dòng)和芯片內(nèi)驅(qū)動(dòng),外設(shè)驅(qū)動(dòng)包括:LCD,F(xiàn)M等;芯片內(nèi)部驅(qū)動(dòng)為內(nèi)部總線驅(qū)動(dòng),如GPIO,UART等 | |
rtos | 實(shí)時(shí)操作系統(tǒng)層,該目錄包括原生操作系統(tǒng) | |
service | base | 基礎(chǔ)服務(wù),包括RTOS操作等 |
net | 網(wǎng)絡(luò)服務(wù),提供http,lwna,tcp/ip操作接口 | |
bt | 藍(lán)牙服務(wù) | |
camera | 提供相機(jī)操作接口 | |
gps | 提供GPS定位服務(wù) | |
gui | 用戶(hù)界面操作接口 | |
gsm | GSM/GPRS操作服務(wù)接口 | |
media | 音頻、視頻服務(wù)接口等 | |
iotapi | 簡(jiǎn)單iot應(yīng)用程序編程接口 | |
target | 用戶(hù)產(chǎn)品配置文件 | |
build | 影子目錄,該目錄在編譯時(shí)由編譯腳本生成,用來(lái)存放編譯過(guò)程中生成的臨時(shí)文件 | |
lib | 模塊靜態(tài)連接庫(kù) | |
hex | Lod文件、Ramrun文件和其他GDB相關(guān)asm及map文件 | |
配置文件 | 說(shuō)明 |
target.def | 產(chǎn)品配置,target表示產(chǎn)品、開(kāi)發(fā)板 |
target_common.def | 對(duì)target.def信息的集中處理,通常不需要用戶(hù)修改 |
memd.def | Flash屬性定義 |
tgt_app_cfg.h | 用戶(hù)功能宏頭文件,控制用戶(hù)APP特性 文件存在./target/include |
tgt_board_cfg.h | 硬件線路板配置 文件存在./target/include |
tgt_calib_cfg.h | 校準(zhǔn)配置 文件存在./target/include |
選項(xiàng) | 說(shuō)明 | |
芯片描述信息 | 定義芯片類(lèi)型和封裝 | |
觸屏驅(qū)動(dòng) | 定義觸屏設(shè)置 | |
FM驅(qū)動(dòng) | 定義FM總線和時(shí)鐘管腳 | |
FLASH驅(qū)動(dòng) | 定義FLASH類(lèi)型、時(shí)鐘及ADMUX | |
LCD驅(qū)動(dòng) | 定義LCD總線 | |
CAMERA驅(qū)動(dòng) | 是否支持CAMERA及各種特性 | |
藍(lán)牙驅(qū)動(dòng) | 定義藍(lán)牙模塊類(lèi)型,32K時(shí)鐘管腳,UART透?jìng)?/div> | |
T卡驅(qū)動(dòng) | 定義T卡接口類(lèi)型 | |
音頻驅(qū)動(dòng) | 定義音頻設(shè)置 | |
WIFI驅(qū)動(dòng) | 定義WIFI 32K時(shí)鐘管腳,TCP/IP支持,SDIO,GPIO,SDMMC接口支持,DLNA接口支持,WIFI音箱支持 | |
32K時(shí)鐘配置 | 配置時(shí)鐘 | |
用戶(hù)項(xiàng)目定義 | APP_BASEDIR | 客戶(hù)APP目錄 |
CT_PROJECT | 定義資源類(lèi)型 | |
AUD_MAX_LEVEL | 定義音量 | |
RESOURCE_SUPPORT | 是否包含資源 | |
AT_SUPPORT | 是否支持AT命令 | |
BT_SPP | 是否支持藍(lán)牙SPP | |
USB支持類(lèi)型 | 是否支持USB音箱;USB HOST | |
編譯優(yōu)化選項(xiàng) | CT_OPT:優(yōu)化編譯空間 WITHOUT_WERROR:告警是否停止編譯 | |
調(diào)試選項(xiàng) | TRACE控制選項(xiàng); | |
Eclipse和JRE(Jave Run Environment)選用32位版本,可以兼容64和32位操作系統(tǒng) |
安裝Eclipse |
創(chuàng)建工程 |


配置工程 |
Select Target | 選擇目標(biāo)Target |
Target Wizard | 項(xiàng)目向?qū)В渲庙?xiàng)目特性、模塊等 |
Remove | 刪除Target |
New Target | 新建Target |
Select Release | 選擇生成“release”還是“debug”版本 |
Base Build Command | - |
Custom Build Option | - |

編譯工程 |
Build Flash | 編譯Ramrun文件 |
Build Image | 編譯Flash文件 |

編譯模塊 |
Build this module | 編譯該模塊 |
Clean this module | 清除模塊已編譯中間文件 |

用戶(hù)模塊組織結(jié)構(gòu) |

Makefile格式 |
## ----------------------------------------------------------- ## ## Don't touch the next line unless you know what you're doing.## ## ----------------------------------------------------------- ## include ${SOFT_WORKDIR}/env/compilation/compilevars.mk # Name of the module LOCAL_NAME := apps/ap_customer # list all modules APIs that are neccessary to compile this module LOCAL_API_DEPENDS := \ platform \ platform/service \ ## ----------------------------------------------------------- ## ## List all your sources here ## ## ----------------------------------------------------------- ## include src/make.srcs ## ----------------------------------------------------------- ## ## Do Not touch below this line ## ## ----------------------------------------------------------- ## include ${SOFT_WORKDIR}/env/compilation/compilerules.mk |
安裝串口驅(qū)動(dòng) |

配置串口 |

Eclipse燒錄工具條目 |
Reset Target | 重置目標(biāo)板,目標(biāo)板將重啟 |
Connect Target | 連接目標(biāo)板,成功失敗都會(huì)有彈出對(duì)話框提示 |
Open Coolwatcher | 打開(kāi)CoolWatcher工具 |
Open Memory View | 打開(kāi)內(nèi)存讀寫(xiě)窗口,該部分將在2.6 調(diào)度中介紹 |
Down Flash | 下載Ramrun 和Flash 文件 |
燒錄BIN文件 |

Flash Programmer File文件由build flash產(chǎn)生 System Lod File文件由build image產(chǎn)生,參考2.3 IDE配置 |

功能描述: | 分配內(nèi)存, glibc兼容 | |||
函數(shù): | PVOID iot_Malloc(UINT32 size) | |||
參數(shù): | ||||
【輸入】 | size | 申請(qǐng)內(nèi)存大小 | ||
返回值: | 指向分配內(nèi)存的指針 | |||
功能描述: | 釋放內(nèi)存, glibc兼容 | |||
函數(shù): | VOID iot_Free(PVOID ptr) | |||
參數(shù): | ||||
【輸入】 | ptr | 內(nèi)存指針 | ||
返回值: | 無(wú) | |||
功能描述: | 打印trace,示例打印LED燈狀態(tài): | |||
iotPrintf("led status = %d ", ledOn); | ||||
函數(shù): | VOID iot_Printf(INT8* fmt,...) | |||
參數(shù): | ||||
【輸入】 | fmt | 打印格式 | ||
返回值: | 無(wú) | |||
功能描述: | 程序延時(shí) | |||
函數(shù): | VOID iot_delayMs(UIN32 ms) | |||
參數(shù): | ||||
【輸入】 | ms | 延時(shí)ms毫秒 | ||
返回值: | 無(wú) | |||
功能描述: | 程序延時(shí) | |||
函數(shù): | VOID iot_DelaySeconds( UINT32 seconds) | |||
參數(shù): | ||||
【輸入】 | secondes | 定時(shí)器時(shí)長(zhǎng),以秒為單位 | ||
返回值: | 無(wú) | |||
功能描述: | 打開(kāi)UART接口 | |||
函數(shù): | VOID uart_Open(UINT8 id, UINT32 baudrate) | |||
參數(shù): | ||||
【輸入】 | id | Uart ID | ||
【輸入】 | baudrate | Uart 波特率 | ||
返回值: | 無(wú) | |||
功能描述: | 關(guān)閉UART接口 | |||
函數(shù): | VOID uart_Close(UINT8 id); | |||
參數(shù): | ||||
【輸入】 | id | |||
返回值: | 無(wú) | |||
功能描述: | 通過(guò)UART接口發(fā)送數(shù)據(jù),每次只發(fā)送一個(gè)字節(jié)數(shù)據(jù) | |||
函數(shù): | UINT32 uart_Write(UINT8 id, CHAR ch); | |||
參數(shù): | ||||
【輸入】 | uartId | UART ID | ||
【輸入】 | ch | 數(shù)據(jù)地址指針 | ||
返回值: | > 0 | - | 通過(guò)UART發(fā)送字節(jié)數(shù) | |
0 | - | 發(fā)送數(shù)據(jù)失敗 | ||
功能描述: | 通過(guò)UART接口讀數(shù)據(jù) | |||
函數(shù): | UINT32 uart_Read(UINT8 id, CHAR* buff) | |||
參數(shù): | ||||
【輸入】 | id | UART ID | ||
【輸入】 | buff | 數(shù)據(jù)地址指針 | ||
返回值: | > 0 | - | 通過(guò)UART接收字節(jié)數(shù) | |
0 | - | 接收數(shù)據(jù)失敗 | ||
功能描述: | 打開(kāi)GPIO接口 | |||
函數(shù): | VOID gpio_Open(UINT8 port, UINT8 direction) | |||
參數(shù): | ||||
【輸入】 | port | 端口號(hào) | ||
【輸入】 | direction | 0 – 輸入 ;1 – 輸出 | ||
返回值: | 無(wú) | |||
功能描述: | 關(guān)閉GPIO接口 | |||
函數(shù): | VOID gpio_Close(UINT8 port) | |||
參數(shù): | ||||
【輸入】 | port | 端口號(hào) | ||
返回值: | 無(wú) | |||
功能描述: | 向GPIO寫(xiě)“0”或者“1” | |||
函數(shù): | VOID gpio_Write(UINT8 port, UINT8 data) | |||
參數(shù): | ||||
【輸入】 | port | 端口號(hào) | ||
【輸入】 | data | 數(shù)據(jù) | ||
返回值: | 無(wú) | |||
功能描述: | 從GPIO讀數(shù)據(jù) | |||
函數(shù): | UINT32 gpio_Read(UINT8 port) | |||
參數(shù): | ||||
【輸入】 | port | 端口號(hào) | ||
返回值: | GPIO接口當(dāng)前數(shù)據(jù) | |||
// app_led.c #include “hal_gpio.h” #include “tcpip_sockets.h” static struct sockaddr_in ledSckAddr; static INT8 ledSckServer; static INT8 ledSckClient = 0; ///Only accept 1 byte data(0 or 1), ok for turn on/off the LED #define MAX_RECV_BUFF 1 #define LED_SCK_PORT 5050 #define MAX_LED_CONNECTION 1 VOID init(VOID) { struct sockaddr_in clientAddr; HAL_GPIO_GPIO_ID_T ledGpioId; HAL_GPIO_DIRECTION_T direction; ///Use the tenth GPIO port ledGpioId = HAL_GPIO_10; direction = HAL_GPIO_DIRECTION_OUTPUT; ///Must open the GPIO before use it gpio_Open(ledGpioId, direction); ledSckServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); memset(&ledSckAddr,0, sizeof(struct sockaddr_in)); ledSckAddr.sin_family=AF_INET; ledSckAddr.sin_addr.s_addr=htonl(INADDR_ANY); ledSckAddr.sin_port=htons(LED_SCK_PORT); if(-1 == bind(ledSckServer, (struct sockaddr *)(& ledSckAddr),sizeof(sockaddr_in))) { return ; } } VOID loop(VOID) { INT8 readLen = 0; UINT8 ledOn; /// If no connection, waiting for connect if (ledSckClient <= 0) { if(-1 == listen(ledSckServer, MAX_LED_CONNECTION)) { return ; } addrSize = sizeof(struct sockaddr_in); ledSckClient = accept(ledSckServer, (struct sockaddr *)(&clientAddr), &addrSize); if(-1 == ledSckClient) { return ; } } readLen = read(ledSckClient, &ledOn, MAX_REV_BUF_SIZE); if (readLen > 0) { if (0 == ledOn || 1 == ledOn) gpio_Write(ledGpioId, ledOn); } } |
功能描述: | 連接網(wǎng)絡(luò) | |||
函數(shù): | INT32 iot_Connect(const char *addr, INT16 portno) | |||
參數(shù): | ||||
【輸入】 | addr | 網(wǎng)絡(luò)地址,URL或者 IP | ||
【輸入】 | portno | 端口號(hào) | ||
返回值: | < 0 | 失敗 | ||
其他 | 成功 | |||
功能描述: | 發(fā)送數(shù)據(jù) | |||
函數(shù): | INT32 iot_Send(INT32 sockfd, const INT8* buffer, UINT32 len) | |||
參數(shù): | ||||
【輸入】 | sockfd | 套接字句柄 | ||
【輸入】 | buffer | 發(fā)送數(shù)據(jù)緩存 | ||
【輸入】 | len | 發(fā)送數(shù)據(jù)長(zhǎng)度 | ||
返回值: | 指定索引的BSSID字串 | |||
功能描述: | 接收數(shù)據(jù) | |||
函數(shù): | INT32 iot_Recv(INT32 sockfd, INT8 *buffer, UINT32 len) | |||
參數(shù): | ||||
【輸入】 | sockfd | 套接字句柄 | ||
【輸入】 | buffer | 接收數(shù)據(jù)緩存 | ||
【輸入】 | len | 接收數(shù)據(jù)長(zhǎng)度 | ||
返回值: | 實(shí)際接收字節(jié)數(shù) | |||
功能描述: | 關(guān)閉網(wǎng)絡(luò) | |||
函數(shù): | INT32 iot_Close(INT32 sockfd) | |||
參數(shù): | ||||
【輸入】 | sockefd | 套接字句柄 | ||
返回值: | ||||
#include "iot_wifi.h" // Source device id allocated by oneNet #define SRC_DEV "777" // Destination device id allocated by oneNet #define DST_DEV "778" // API key allocated by oneNet #define API_KEY "your api key" // Data stream name, created on oneNet #define DATA_STREAM "your data stream" #define MAX_RESP_BUF 32 // ============================================================================ // Loop forever // Send temperature value to cloud application whenever changed // @return void // ============================================================================ VOID loop() { // Server information for connection INT8 *server_ip = "183.230.40.39"; INT8 *port = "876"; INT8 *src_dev = SRC_DEV; INT8 *dst_dev = DST_DEV; INT8 *src_api_key = API_KEY; INT8 *data_stream = DATA_STREAM; DOUBLE temperature = 0.0; INT sock, ret; EdpPacket *pkg = NULL; INT8 buffer[MAX_RESP_BUF] = { 0 }; SaveDataType data_type = kTypeSimpleJsonWithoutTime; recv_buf = NewBuffer(); // Connect to server sock = iot_Connect(server_ip, atoi(port)); if (sock < 0) { iot_Printf("Error connect cloud server. \n"); return; } // Build connect package follow oneNet EDP protocol pkg = PacketConnect1(src_dev, src_api_key); if (pkg == NULL) { iot_Printf("Build connect pkg failed.\n"); return; } // Send connection request pkg to cloud server ret = iot_Send(sock, (const char*)pkg->_data, pkg->_write_pos); DeleteBuffer(&pkg); while (1) { Temperature = user_poll_current_temperature(); // Build save data pkg follow oneNet EDP protocol pkg =PacketSavedataDouble(data_type,dst_dev,data_stream,temperature,0, NULL); if (pkg == NULL) { iot_Printf("Build data failed.\n"); return; } // Send temperature value pkg to clould server iot_Send(sock, (const char*)pkg->_data, pkg->_write_pos); DeleteBuffer(&pkg); iot_DelayMs(2000); } // Close socket iot_Close(sock); return; } |
功能描述: | 啟動(dòng)藍(lán)牙模塊 | |||
函數(shù): | VOID bt_Open(VOID) | |||
參數(shù): | ||||
【輸入】 | 無(wú) | |||
返回值: | 無(wú) | |||
功能描述: | 關(guān)閉藍(lán)牙模塊 | |||
函數(shù): | VOID bt_Close(VOID) | |||
參數(shù): | ||||
【輸入】 | 無(wú) | |||
返回值: | 無(wú) | |||
功能描述: | 設(shè)置本地藍(lán)牙設(shè)備名 | |||
函數(shù): | VOID bt_SetLocalName(UINT8* name) | |||
參數(shù): | ||||
【輸入】 | name | 本地藍(lán)牙設(shè)備名 | ||
返回值: | 無(wú) | - | ||
功能描述: | 設(shè)置本地藍(lán)牙可見(jiàn)性 | |||
函數(shù): | VOID bt_SetVisable(UINT8 visable); | |||
參數(shù): | ||||
【輸入】 | visible | TRUE – 可見(jiàn);FALSE – 不可見(jiàn) | ||
返回值: | 無(wú) | - | ||
功能描述: | 掃描周邊藍(lán)牙設(shè)備 | |||
函數(shù): | UINT32 bt_ScanDevice(UINT32 timeout) | |||
參數(shù): | ||||
【輸入】 | timeout | 掃描超時(shí)時(shí)間,單位秒 | ||
返回值: | 獲取藍(lán)牙設(shè)備總數(shù) | |||
功能描述: | 配對(duì)藍(lán)牙設(shè)備 | ||
函數(shù): | UINT32 bt_BondDevice( t_bdaddr device_addr, UINT32 timeout ) | ||
參數(shù): | |||
【輸入】 | Timeout | 配對(duì)超時(shí)時(shí)間,單位秒 | |
返回值: | TRUE 配對(duì)成功 FALSE 配對(duì)失敗 | ||
功能描述: | 藍(lán)牙配對(duì) | |||
函數(shù): | BOOL bt_GetBonedDevice(UINT32 index, rdabt_device_t_app *device); | |||
參數(shù): | ||||
【輸入】 | Index | 藍(lán)牙設(shè)備索引,取值范圍0~9 | ||
【輸出】 | device | 藍(lán)牙設(shè)備信息數(shù)據(jù)指針 | ||
返回值: | TRUE | - | 獲取成功 | |
FALSE | - | 獲取失敗 | ||
功能描述: | 連接藍(lán)牙SPP服務(wù)端 | |||
函數(shù): | BOOL bt_SppConnect(t_bdaddr device_addr, UINT8 timeout); | |||
參數(shù): | ||||
【輸入】 | device_addr | 藍(lán)牙地址 | ||
【輸入】 | timeout | 藍(lán)牙連接超時(shí) | ||
返回值: | TRUE | - | 連接成功 | |
FALSE | - | 連接失敗 | ||
功能描述: | 斷開(kāi)藍(lán)牙SPP連接 | |||
函數(shù): | VOID bt_SppDisconnect(VOID) | |||
參數(shù): | ||||
【輸入】 | 無(wú) | |||
返回值: | 無(wú) | |||
功能描述: | 通過(guò)SPP發(fā)送數(shù)據(jù) | |||
函數(shù): | INT32 bt_SppSend(UINT8* buf, UINT32 size) | |||
參數(shù): | ||||
【輸入】 | buf | 發(fā)送數(shù)據(jù)緩沖區(qū) | ||
【輸入】 | size | 發(fā)送數(shù)據(jù)長(zhǎng)度 | ||
返回值: | > 0 | - | 實(shí)際發(fā)送字節(jié)數(shù) | |
<= 0 | - | 發(fā)送失敗 | ||
功能描述: | 通過(guò)藍(lán)牙SPP接收數(shù)據(jù) | |||
函數(shù): | INT32 bt_SppRecv(UINT32 timeout, UINT8 *buf) | |||
參數(shù): | ||||
【輸入】 | timeout | 超時(shí)時(shí)間,單位秒 | ||
【輸出】 | buf | 接收數(shù)據(jù)緩沖區(qū) | ||
返回值: | > 0 | - | 成功接收數(shù)據(jù)字節(jié)數(shù) | |
<= 0 | - | 接收數(shù)據(jù)失敗 | ||
功能描述: | 藍(lán)牙SPP服務(wù)端接受客戶(hù)端連接 | |||
函數(shù): | BOOL bt_SppAccept(UINT32 timeout) | |||
參數(shù): | ||||
【輸入】 | timeout | 超時(shí)時(shí)間,單位秒 | ||
返回值: | TRUE | - | 連接成功 | |
FALSE | - | 連接失敗 | ||
// app_smart_plug.c #include “bt_types.h” #include “hal_gpio.h” static HAL_GPIO_GPIO_ID_T plugGpioId; VOID init(VOID) { HAL_GPIO_DIRECTION_T direction; // Use the fifth GPIO port plugGpioId = HAL_GPIO_15; direction = HAL_GPIO_DIRECTION_OUTPUT; // Must open the GPIO before use it gpio_Open(plugGpioId, direction ); bt_Open(VOID); } VOID loop(VOID) { t_DataBuf btData; memcpy(&btData, 0, sizeof(t_DataBuf)); // Return only when data available or error bt_SppRecv(&btData); if (btData.len > 0) { if (0 == (*btData.buff) || 1 == (*btData.buff) ) { gpio_Write(plugGpioId, *btData.buff); } } } |
| 歡迎光臨 (http://www.raoushi.com/bbs/) | Powered by Discuz! X3.1 |