MQTT移植到stm32開發板——使用FreeRTOS操作系統

mqttclient

一個高性能、高穩定性的跨平臺MQTT客戶端

一個高性能、高穩定性的跨平臺MQTT客戶端,基於socket API之上開發,可以在嵌入式設備(FreeRTOS/LiteOS/RT-Thread/TencentOS tiny)、Linux、Windows、Mac上使用,擁有非常簡潔的API接口,以極少的資源實現QOS2的服務質量,並且無縫銜接了mbedtls加密庫。開源地址:https://github.com/jiejieTop/mqttclient

開發平臺說明

本次使用野火官方開發板——STM32F429挑戰者開發板作爲移植實驗,使用lwip+以太網連接到雲平臺。

本次實驗需要使用到freertos操作系統,大家對於freertos操作系統的移植不會的話,
可以看我之前的操作系統博客專欄——https://blog.csdn.net/jiejiemcu/category_7707185.html

而對於lwip不理解的同學,可以看我的博客專欄,專門寫lwip網絡協議棧的——https://blog.csdn.net/jiejiemcu/category_8634585.html

獲取到野火的lwip例程

大家可以通過野火官方資料去獲取到野火的lwip例程,比如我獲取的一個例程目錄如下,用這個例程作爲移植mqttclient的工程。

mqtt-freertos001

開始移植mqttclient

  1. 添加mqttclient源碼相關的文件,大家可以將下載的mqttclient直接拷貝到工程的根目錄下:在工程根目錄下創建一個mqttclient文件夾,然後將整個mqttclient的倉庫拷貝到這個新建的文件夾下,將mqttclient/test/mqtt_config.h拷貝到User目錄下。

    mqtt-freertos002

    mqtt-freertos002-1

  2. 刪除掉其他平臺層的文件:在mqttclient\platformmqttclient\common\log\arch目錄下刪除其他無關的平臺層,當然刪不刪無所謂,只是刪除了工程沒有那麼大一點而已。

    mqtt-freertos003

    mqtt-freertos004

  3. 打開工程,在工程中創建分組:mqttclient、mqttclient/mqtt、mqttclient/salof、mqttclient/common、mqttclient/network、mqttclient/platform、mqttclient/config。

    mqtt-freertos005

    mqtt-freertos006

  4. 簡單介紹mqttclient倉庫文件夾

    • common文件夾:是一些通用的文件內容,比如鏈表的處理,錯誤代碼的處理、隨機數生成器、日誌庫等內容。

    • mqtt文件夾:著名的paho mqtt庫。

    • mqttclient文件夾:實現mqttclient的主要文件,並且包含了一個默認的配置文件。

    • network文件夾:網絡抽象層,封裝了mbedtls加密庫、網絡數據的通道類型,自動選擇tls加密傳輸或者是tcp直連。

    • platform文件夾:平臺抽象層,此處封裝了各種平臺的內存管理、互斥鎖、線程管理、時間管理等內容,如linux平臺,freertos平臺、rt-thread平臺、TencentOS tiny平臺等。

    • test文件夾:主要是一些測試例程與相應的配置頭文件,如mqtt_config.h。

  5. 添加對應的文件,根據工程分組的目錄進行添加即可,因爲這些目錄與工程分組的目錄是一樣的,爲工程分組添加完畢的源文件如下(此處不使用mbedtls加密):

    mqtt-freertos007

  6. 修改mqtt_cofig.h配置文件,由於不使用mbedtls加密,所以需要打開指定MQTT_NETWORK_TYPE_NO_TLS宏定義,同時註釋MQTT_LOG_IS_SALOF宏定義不使用同步異步日誌庫,或者將宏SALOF_OS定義爲SALOF_USING_FREERTOS,表示使用freertos平臺。

    mqtt-freertos008

  7. 在工程中添加mqttclient的頭文件路徑:

    mqtt-freertos0010

  8. 編寫main.c文件的代碼,測試代碼如下:

    #include "main.h"
    /* FreeRTOS頭文件 */
    #include "FreeRTOS.h"
    #include "task.h"
    
    #include "mqttclient.h"
    
    //#define TEST_USEING_TLS  
    
    extern const char *test_ca_get(void);
    
    static TaskHandle_t app_task_create_handle = NULL;/* 創建任務句柄 */
    static TaskHandle_t mqtt_task_handle = NULL;/* LED任務句柄 */
    
    static void app_task_create(void);/* 用於創建任務 */
    
    static void mqtt_task(void* pvParameters);/* mqtt_task任務實現 */
    
    extern void TCPIP_Init(void);
    
    /*****************************************************************
    * @brief  主函數
    * @param  無
    * @retval 無
    * @note   第一步:開發板硬件初始化 
                第二步:創建APP應用任務
                第三步:啓動FreeRTOS,開始多任務調度
    ****************************************************************/
    int main(void)
    {	
    BaseType_t xReturn = pdPASS;/* 定義一個創建信息返回值,默認爲pdPASS */
    
    /* 開發板硬件初始化 */
    BSP_Init();
    
    /* 創建app_task_create任務 */
    xReturn = xTaskCreate((TaskFunction_t )app_task_create,  /* 任務入口函數 */
                            (const char*    )"app_task_create",/* 任務名字 */
                            (uint16_t       )2048,  /* 任務棧大小 */
                            (void*          )NULL,/* 任務入口函數參數 */
                            (UBaseType_t    )10, /* 任務的優先級 */
                            (TaskHandle_t*  )&app_task_create_handle);/* 任務控制塊指針 */ 
    /* 啓動任務調度 */           
    if(pdPASS == xReturn)
        vTaskStartScheduler();   /* 啓動任務,開啓調度 */
    else
        return -1;  
    
    while(1);   /* 正常不會執行到這裏 */    
    }
    
    
    /***********************************************************************
    * @ 函數名  : app_task_create
    * @ 功能說明: 爲了方便管理,所有的任務創建函數都放在這個函數裏面
    * @ 參數    : 無  
    * @ 返回值  : 無
    **********************************************************************/
    static void app_task_create(void)
    {
        int err;
        
        mqtt_client_t *client = NULL;
        
        BaseType_t xReturn = pdPASS;/* 定義一個創建信息返回值,默認爲pdPASS */
    
        TCPIP_Init();
        
        printf("\nwelcome to mqttclient test...\n");
    
        mqtt_log_init();
    
        client = mqtt_lease();
    
    #ifdef TEST_USEING_TLS
        mqtt_set_port(client, "8883");
        mqtt_set_ca(client, (char*)test_ca_get());
    #else
        mqtt_set_port(client, "1883");
    #endif
    
        mqtt_set_host(client, "www.jiejie01.top");
        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);
    
        err = mqtt_connect(client);
        
        MQTT_LOG_I("mqtt_connect err = %d", err);
        
        err = mqtt_subscribe(client, "freertos-topic", QOS0, NULL);
        
        MQTT_LOG_I("mqtt_subscribe err = %d", err);    
    
    
        taskENTER_CRITICAL();           //進入臨界區
    
        /* 創建mqtt_task任務 */
        xReturn = xTaskCreate((TaskFunction_t )mqtt_task, /* 任務入口函數 */
                            (const char*    )"mqtt_task",/* 任務名字 */
                            (uint16_t       )2048,   /* 任務棧大小 */
                            (void*          )client,	/* 任務入口函數參數 */
                            (UBaseType_t    )10,	    /* 任務的優先級 */
                            (TaskHandle_t*  )&mqtt_task_handle);/* 任務控制塊指針 */
        if(pdPASS == xReturn)
            printf("Create mqtt_task sucess...\r\n");
    
        vTaskDelete(app_task_create_handle); //刪除app_task_create任務
    
        taskEXIT_CRITICAL();            //退出臨界區
    }
    
    
    
    /**********************************************************************
    * @ 函數名  : mqtt_task
    * @ 功能說明: mqtt_task任務主體
    * @ 參數    :   
    * @ 返回值  : 無
    ********************************************************************/
    static void mqtt_task(void* arg)
    {	
        mqtt_client_t *client = (mqtt_client_t *)arg;
        
        char buf[100] = { 0 };
        mqtt_message_t msg;
        memset(&msg, 0, sizeof(msg));
        sprintf(buf, "welcome to mqttclient, this is a publish test...");
    
        vTaskDelay(4000);
        
        mqtt_list_subscribe_topic(client);
    
        msg.payload = (void *) buf;
        msg.qos = QOS0;
        
        while(1) {
            sprintf(buf, "welcome to mqttclient, this is a publish test, a rand number: %d ...", random_number());
    
            mqtt_publish(client, "freertos-topic", &msg);
            
            vTaskDelay(4000);
        }
    }
    
  9. 然後編譯代碼,燒錄到開發板上,實驗現象如下:

    mqtt-freertos009

本次移植完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章