RT-Thread 之 RT-Thread + WIZnet + W5500 + MQTT + ali-iotkit-v3.0.1 完成乙太網Socket通訊MQTT協定主題訂閱發佈

2020-08-13 15:56:16

目錄

1、介紹

1.1 WIZnet

1.2 W5500

2、RT-Thread Studio 設定及相關程式碼

 2.1 新增WIZnet軟體包

2.2 設定 WIZnet 軟體包

2.3 設定 spi20 

3、驗證效果

4、與ali-iotkit-v3.0.1 阿裡雲IOT軟體包 MQTT主題訂閱發佈

4.1 新增 ali-iotkit-v3.0.1 軟體包

4.2  設定Ali-iotkit 連線阿裡雲IOT平臺的三元組參數,開啓Samples範例程式碼,其他參數預設即可

4.3 MQTT範例程式碼 mqtt-example.c

4.4  物模型範例程式碼 linkkit_example_solo.c

4.5 實驗驗證OK

 


開發環境:使用 RT-Thread 實時操作系統 。

開發軟體:使用 RT-Thread Studio (目前最新版本1.1.3)。

開發硬體:使用正點原子的 STM32L475 潘多拉開發板 。

 

1、介紹

1.1 WIZnet

WIZnet 軟體包是 RT-Thread 基於 WIZnet 官網 ioLibrary_Driver 程式碼庫的移植實現,目前只支援 W5500 裝置。該軟體包在原始碼庫功能的基礎上,對接 RT-Thread SAL 通訊端抽象層,實現對標準 BSD Socket APIs 的支援,完美的相容多種軟體包和網路功能實現,提高 WIZnet 裝置相容性。

1.2 W5500

W5500是WIZnet推出的高效能乙太網介面晶片系列之一,內部整合全硬體TCP/IP協定棧+MAC+PHY。全硬體協定棧技術採用硬體邏輯閘電路實現複雜的TCP/IP協定簇,其應用具有簡單快速、可靠性高、安全性好等顯著優勢;內部整合MAC和PHY工藝,使得微控制器接入乙太網方案的硬體設計更爲簡捷和高效。

W5500 晶片是一款整合全硬體 TCP/IP 協定棧的嵌入式乙太網控制器,同時也是一顆工業級乙太網控制晶片。是韓國WIZnet(微知納特)發佈全硬體TCP/IP協定棧乙太網介面晶片。

W5500 支援高速標準4線SPI介面與主機進行通訊,該 SPI 速率理論上可以達到 80MHz。其內部還整合了乙太網數據鏈路層(MAC)和10BaseT/100BaseTX 乙太網物理層(PHY),支援自動協商(10/100-Based全雙工/半雙工)、掉電模式和網路喚醒功能。與傳統軟體協定棧不同,W5500內嵌的8個獨立硬體 Socket 可以進行8路獨立通訊,該8路Socket的通訊效率互不影響,可以通過 W5500 片上32K 位元組的收/發快取靈活定義各個Socket的大小。

(注:參考資料 WIZnet W5500-參考設計大全

特點

    • 全硬體TCP/IP協定棧:TCP,UDP,ICMP,IPv4,ARP,IGMP,PPPoE
    • 8個獨立的硬體Socket,各路通訊互不影響
    • 32K位元組收發快取
    • 整合802.3乙太網MAC
    • 整合10Base-T / 100Base-T乙太網PHY
    • 主機介面:SPI高速序列外設介面(最高80Mhz )
    • 支援嵌入式操作系統:Linux & RTOS
    • 支援掉電模式 & UDP網路喚醒
    • 工作電壓3.3V,I/O 5V耐壓
    • 支援自動協商(全/半雙工,10M/100M)
    • 工作溫度40℃左右
    • 48Pin LQFP無鉛封裝(7x7mm, 0.5mm針間距)

 

 

 

2、RT-Thread Studio 設定及相關程式碼

 2.1 新增WIZnet軟體包

在RT-Thread 軟體包中搜尋W5500軟體包後新增到專案中

新增後的結果如下圖所示

2.2 設定 WIZnet 軟體包

spi20 裝置引腳說明如下所示 

PB12 SPI2_CS
PB13 SPI2_SCK
PB14 SPI2_MISO
PB15 SPI2_MOSI

Reset復位引腳是26(對應PB10),IRQ中斷引腳 27 (對應PB11),引腳號參考見下圖

硬體連線圖如下所示:

 

2.3 設定 spi20 

在drv_spi.c原始檔中新增 HAL_SPI_MspInit 函數(SPI2引腳設定)

void HAL_SPI_MspInit(SPI_HandleTypeDef *spiHandle)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RT_ASSERT(spiHandle != RT_NULL);

#ifdef BSP_USING_SPI1
    if (spiHandle->Instance == SPI1)
    {
        /* SPI1 clock enable */
        __HAL_RCC_SPI1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();

        /**SPI1 GPIO Configuration
        PA5     ------> SPI1_SCK
        PA6     ------> SPI1_MISO
        PA7     ------> SPI1_MOSI
        */
        GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
    else
#endif
#ifdef BSP_USING_SPI2
    if (spiHandle->Instance == SPI2)
    {
        /* SPI2 clock enable */
        __HAL_RCC_SPI2_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();

        /**SPI2 GPIO Configuration
        PB13     ------> SPI2_SCK
        PB14     ------> SPI2_MISO
        PB15     ------> SPI2_MOSI
        */
        GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
    else
#endif
#ifdef BSP_USING_SPI3
    if (spiHandle->Instance == SPI3)
    {
        /* SPI3 clock enable */
        __HAL_RCC_SPI3_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();

        /**SPI3 GPIO Configuration
        PB3 (JTDO-TRACESWO)     ------> SPI3_SCK
        PB4 (NJTRST)            ------> SPI3_MISO
        PB5                     ------> SPI3_MOSI
        */
        GPIO_InitStruct.Pin = GPIO_PIN_3 /* | GPIO_PIN_4 */ | GPIO_PIN_5;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
    else
#endif
    {
        RT_ASSERT(0);
    }
}

 自動初始化 rt_hw_spi_flash_init 函數,將spi20 掛載到spi2總線上

static int rt_hw_spi_flash_init(void)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();
    rt_hw_spi_device_attach("spi2", "spi20", GPIOB, GPIO_PIN_12);

    return RT_EOK;
}
/* 導 出 到 自 動 初 始 化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);

 

3、驗證效果

串列埠偵錯助手顯示效果如下

ifconfig : 檢視當前網路的 ip address 、 gw address (閘道器地址)、net mask (子網掩碼)、 dns server (dns伺服器)

ping 172.30.1.103 成功ping通,表示區域網內可以相互訪問了

(注:因爲路由器沒有連到公網,所以沒有ping www.baidu.com)

 

4、與ali-iotkit-v3.0.1 阿裡雲IOT軟體包 MQTT主題訂閱發佈

4.1 新增 ali-iotkit-v3.0.1 軟體包

4.2  設定Ali-iotkit 連線阿裡雲IOT平臺的三元組參數,開啓Samples範例程式碼,其他參數預設即可

4.3 MQTT範例程式碼 mqtt-example.c

在串列埠偵錯助手輸入 ali_mqtt_sample(加回車換行即ENTER鍵)就可以連線阿裡雲IOT雲平臺進行MQTT通訊。

4.4  物模型範例程式碼 linkkit_example_solo.c

在串列埠偵錯助手輸入 ali_linkkit_solo_sample(加回車換行即ENTER鍵)就可以連線阿裡雲IOT雲平臺進行物模型通訊。

4.5 實驗驗證OK