mqttclient
一個高性能、高穩定性的跨平臺MQTT客戶端
一個高性能、高穩定性的跨平臺MQTT客戶端,基於socket API之上開發,可以在嵌入式設備(FreeRTOS/LiteOS/RT-Thread/TencentOS tiny)、Linux、Windows、Mac上使用,擁有非常簡潔的API接口,以極少的資源實現QOS2的服務質量,並且無縫銜接了mbedtls加密庫。開源地址:https://github.com/jiejieTop/mqttclient
開發平臺說明
本次使用TencentOS tiny官方開發板——TencentOS_tiny_EVB_MX_Plus開發板作爲移植實驗,使用wifi模塊連接到雲平臺。
本次實驗需要使用到TencentOS tiny操作系統,大家對於TencentOS tiny操作系統的移植不會的話,
可以看我之前錄製的TencentOS tiny視頻教程——【全網首發】TencentOS tiny物聯網操作系統視頻教程,
或者博客文檔——TencentOS tiny 移植到STM32F103全教程(基於標準庫)。
獲取到TencentOS tiny的helloworld工程
我們可以將TencentOS tiny官方倉庫拉取到你的電腦上,地址是:https://github.com/Tencent/TencentOS-tiny
然後選擇一個TencentOS_tiny_EVB_MX_Plus開發板的hello world例程就好了,當然這裏面已經有移植完畢的mqttclient例程,我們現在是學習移植過程,就選個helloworld就好了。
可以將它提取出來,我已經把它拿出來了(當然目錄結構可能跟官方的有點不太一樣,不過不影響我們的移植),目錄結構如下:
只有一些比較簡單的驅動,我們可以嘗試將它編譯並且下載到開發板行,跑一遍這個例程,是非常簡單的現象:
開始移植
拷貝at驅動源碼
爲了保證網絡的底層,我們要移植TencentOS tiny的at框架:
-
在工程中創建一個文件夾,路徑如下:net\at\src,然後將TencentOS-tiny\net\at\src路徑下的tos_at.c拷貝到新建的文件夾目錄下:
-
在工程中創建一個文件夾,路徑如下:net\sal_module_wrapper,然後將TencentOS-tiny\net\sal_module_wrapper路徑下的sal_module_wrapper.c與sal_module_wrapper.h拷貝到新建的文件夾目錄下:
-
在工程中創建一個devices文件夾,然後將TencentOS-tiny\devices路徑下的bc35_28_95文件夾與esp8266文件夾以及m26文件夾拷貝到新建的文件夾目錄下:
-
在工程中創建一個文件夾,路徑如下:platform\hal\st\stm32l4xx\src,然後將TencentOS-tiny\platform\hal\st\stm32l4xx\src路徑下的tos_hal_usrt.c文件拷貝到新建的文件夾目錄下:
在工程中創建對應的分組並添加文件
-
打開工程,添加at、devices、hal三個分組,具體操作如下:
-
然後添加相關的文件到分組中,這些文件是我們剛剛拷貝的文件:
-
tos_at.c、sal_module_wrapper.c文件放在at分組中:
-
bc35_28_95.esp8266.c文件放在devices分組中:
-
tos_hal_usrt.c文件放在hal分組中:
-
添加完成後分組的文件如下:
然後嘗試編譯,可能會報錯,因爲相關頭文件還沒處理好。
拷貝相關頭文件
-
拷貝at框架的頭文件,在工程目錄下創建以下路徑的文件夾net\at\include,將TencentOS-tiny\net\at\include路徑下的tos_at.h文件拷貝到新建的文件夾目錄下:
添加頭文件路徑到工程
拷貝了頭文件還需要將頭文件添加進去到工程中,頭文件路徑如下:
將at框架的後端介紹融入工程中
只需要在stm32l4xx_it_module.c文件的HAL_UART_RxCpltCallback函數中添加以下代碼即可:
extern uint8_t data;
if (huart->Instance == LPUART1) {
HAL_UART_Receive_IT(&hlpuart1, &data, 1);
tos_at_uart_input_byte(data);
}
移植mqttclient
-
拷貝源碼到工程目錄下:首先在工程目錄下創建一個components\connectivity文件夾,將TencentOS-tiny倉庫中路徑TencentOS-tiny\components\connectivity下的mqttclient文件夾拷貝到工程中:
-
在工程中創建分組:mqttclient、mqttclient/mqtt、mqttclient/salof、mqttclient/common、mqttclient/network、mqttclient/platform、mqttclient/config。
-
添加對應的文件,根據工程分組的目錄進行添加即可,因爲這些目錄與工程分組的目錄是一樣的:
-
簡單介紹mqttclient倉庫文件夾
-
common文件夾:是一些通用的文件內容,比如鏈表的處理,錯誤代碼的處理、隨機數生成器、日誌庫等內容。
-
mqtt文件夾:著名的paho mqtt庫。
-
mqttclient文件夾:實現mqttclient的主要文件,並且包含了一個默認的配置文件。
-
network文件夾:網絡抽象層,封裝了mbedtls加密庫、網絡數據的通道類型,自動選擇tls加密傳輸或者是tcp直連。
-
platform文件夾:平臺抽象層,此處封裝了各種平臺的內存管理、互斥鎖、線程管理、時間管理等內容,如linux平臺,freertos平臺、rt-thread平臺、TencentOS tiny平臺等。
-
-
添加完成後的分組代碼如下:
-
爲工程添加mqttclient的頭文件路徑
-
編譯代碼,發現沒有錯誤,則可以添加對應的例程,在工程目錄的BSP\Src文件夾下創將一個mqttclient.c文件,然後添加以下代碼:
#include "stm32l4xx_hal.h" #include "mcu_init.h" #include "tos_k.h" #include "esp8266.h" #include "mqttclient.h" #define USE_ESP8266 //#define USE_NB_BC35 #ifdef USE_ESP8266 static hal_uart_port_t esp8266_port = HAL_UART_PORT_0; void mqtt_set_esp8266_port(hal_uart_port_t port) { esp8266_port = port; } #endif static void tos_topic_handler(void* client, message_data_t* msg) { (void) client; MQTT_LOG_I("-----------------------------------------------------------------------------------"); MQTT_LOG_I("%s:%d %s()...\ntopic: %s, qos: %d. \nmessage:\n\t%s\n", __FILE__, __LINE__, __FUNCTION__, msg->topic_name, msg->message->qos, (char*)msg->message->payload); MQTT_LOG_I("-----------------------------------------------------------------------------------\n"); } void mqttclient_task(void) { int error; char buf[100] = { 0 }; mqtt_client_t *client = NULL; mqtt_message_t msg; memset(&msg, 0, sizeof(msg)); #ifdef USE_ESP8266 esp8266_sal_init(esp8266_port); esp8266_join_ap("wifii", "woshijiejie"); #endif #ifdef USE_NB_BC35 int bc35_28_95_sal_init(hal_uart_port_t uart_port); bc35_28_95_sal_init(HAL_UART_PORT_0); #endif mqtt_log_init(); client = mqtt_lease(); mqtt_set_port(client, "1883"); mqtt_set_host(client, "www.jiejie01.top"); //111.230.189.156 mqtt_set_client_id(client, random_string(10)); mqtt_set_user_name(client, random_string(10)); mqtt_set_password(client, random_string(10)); mqtt_set_clean_session(client, 1); error = mqtt_connect(client); MQTT_LOG_D("mqtt connect error is %#x", error); mqtt_subscribe(client, "tos-topic", QOS0, tos_topic_handler); MQTT_LOG_D("mqtt subscribe error is %#x", error); memset(&msg, 0, sizeof(msg)); for (;;) { sprintf(buf, "welcome to mqttclient, this is a publish test, a rand number: %d ...", random_number()); msg.qos = QOS0; msg.payload = (void *) buf; error = mqtt_publish(client, "tos-topic", &msg); tos_task_delay(4000); } } void application_entry(void *arg) { mqttclient_task(); while (1) { printf("This is a mqtt demo!\r\n"); tos_task_delay(1000); } }
-
然後將其添加到工程中,最後,編譯並下載到開發板上運行,注意需要修改你的wifi賬號密碼,效果如下:
本次移植教程結束。
源代碼獲取
可以關注微信公衆號:
在後臺回覆“25”即可獲取源代碼