0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

rt-thread 優(yōu)化系列(五)lwip 裁剪

出出 ? 來源:出出 ? 作者:出出 ? 2022-06-23 10:21 ? 次閱讀

前言

很久之前就開始整理下面的優(yōu)化項(xiàng)列表了,但是有很多問題研究不深,一時(shí)不敢冒失推出。
前不久,有人在論壇上提問,當(dāng)時(shí)我給的答案比現(xiàn)在少,但是現(xiàn)在列出來的這些也不能保證是全部,以后再做補(bǔ)充吧。

lwip 協(xié)議棧、sal socket 抽象層使用了很多全局?jǐn)?shù)組變量當(dāng)作線程棧,可以修改成從內(nèi)存堆動(dòng)態(tài)申請(qǐng)的內(nèi)存。
有些功能和特性在嵌入式設(shè)備里是用不到的,可以先去掉。
還有的是可有可無的特性,如果想用,也存在優(yōu)化空間,可以自己實(shí)現(xiàn)。

以下說明不限于 lwip ,sal 部分也有涉及。

裁剪詳解

sal 可裁剪優(yōu)化項(xiàng)

1. `SAL_INTERNET_CHECK`: 網(wǎng)絡(luò)檢測(cè),使用到了 workqueue 。檢測(cè)原理就是嘗試連接 "link.rt-thread.org::8101",發(fā)送檢測(cè)數(shù)據(jù)。
這個(gè)或者可以去掉檢測(cè),或者換成自家服務(wù)器。
2. `#define SAL_SOCKETS_NUM 4`: 這個(gè)可能是支持創(chuàng)建 socket 的最大數(shù)量。
3. `RT_USING_NETDEV`: 網(wǎng)絡(luò)接口設(shè)備,沒有終端操作的情況下可以優(yōu)化掉。其中,`NETDEV_USING_IFCONFIG` `NETDEV_USING_PING` `NETDEV_USING_NETSTAT` `NETDEV_USING_AUTO_DEFAULT` 分別可以單獨(dú)增刪。
4. `NETDEV_IPV6`: 目前支持還不普及的吧,可以關(guān)掉,如果需要才開啟。

lwip 可裁剪優(yōu)化項(xiàng)

1. `RT_LWIP_IGMP` 組播需要用到的,不用組播可能可以去掉
2. `RT_LWIP_ICMP` ping 命令使用的協(xié)議,沒有 ping 也不需要這個(gè)協(xié)議。
3. `RT_LWIP_DNS` 局域網(wǎng)不需要這個(gè),或者說,直接使用 ip 地址進(jìn)行連接而不是使用 url 鏈接地址,可以不使用 dns。
4. `RT_LWIP_TCP_WND` tcp 接收窗口,這個(gè)應(yīng)該是申請(qǐng)內(nèi)存大小。可以適當(dāng)減小。不定義就是 1460 x 2 字節(jié)
5. `RT_LWIP_TCP_SND_BUF` tcp 發(fā)送緩存,同上,不定義就是 1460 x 2 字節(jié)
6. `LWIP_NO_TX_THREAD` 和 `LWIP_NO_RX_THREAD` eth 線程,發(fā)送一個(gè),接收一個(gè)。以下是幾個(gè)相關(guān)宏定義,如果不定義堆棧大小,默認(rèn)使用 1024

   #define RT_LWIP_ETHTHREAD_PRIORITY 12
   #define RT_LWIP_ETHTHREAD_STACKSIZE 1024
   #define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
   #define LWIP_NO_TX_THREAD
   #define LWIP_NO_RX_THREAD

源碼里,這部分還有很大優(yōu)化空間,具體見下文詳解。
7. `LWIP_NETIF_STATUS_CALLBACK` 和前邊的 SAL_INTERNET_CHECK 有關(guān),這里設(shè)置網(wǎng)絡(luò)連接回調(diào)??梢酝ㄖ獞?yīng)用層連接上 INTERNET 了。
8. `LWIP_NETIF_LINK_CALLBACK` 網(wǎng)卡連接狀態(tài),僅表示物理連接接入網(wǎng)絡(luò),有可能是和電腦直連,或者交換機(jī)、路由器等等。
9. `SO_REUSE` 端口復(fù)用,這個(gè)在組播,而且是 UDP 協(xié)議才有用。不需要就定義成 0
10. `LWIP_SO_SNDTIMEO` `LWIP_SO_RCVTIMEO` `LWIP_SO_RCVBUF` 這三個(gè),如果 rtconf.h 里沒有定義, lwipopts.h 會(huì)定義,所以不需要就定義成 0。
其中 LWIP_SO_RCVBUF 接收緩沖,涉及到接收緩沖上限。多數(shù)情況下不會(huì)有影響,只有網(wǎng)絡(luò)數(shù)據(jù)多的時(shí)候才可能達(dá)到這個(gè)緩存上限。
11. `RT_LWIP_USING_PING` 這個(gè)和前面的 NETDEV_USING_PING RT_LWIP_ICMP 有關(guān)。
12. `RT_LWIP_STATS` 這是一組 stat 的總開關(guān),詳細(xì)細(xì)節(jié)查看 lwipopts.h 文件內(nèi)的定義?;蛘呷∠?RT_LWIP_STATS 定義,關(guān)閉所有 stat 項(xiàng),或者單獨(dú)修改 lwipopts.h 文件中某些 stat 定義。

13. 修改 eth_rx_thread 和 eth_tx_thread ,啟用 RT_USING_HEAP 后,添加動(dòng)態(tài)創(chuàng)建線程。這兩個(gè)線程被初始化在 INIT_PREV_EXPORT 階段。片上內(nèi)存堆和片外內(nèi)地堆初始化注冊(cè)都在 INIT_BOARD_EXPORT 階段,可以申請(qǐng)使用動(dòng)態(tài)內(nèi)存。

erx etx 兩個(gè)線程

以 etx 為例。`ethernetif_linkoutput` 函數(shù)主要操作如下:

   if (rt_mb_send(e_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK)
   {
       /* waiting for ack */
       rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER);
   }

發(fā)送了一個(gè)郵箱,然后等待一個(gè)信號(hào)量。這個(gè)信號(hào)量從哪兒來?看下面的 etx 線程入口函數(shù)。

static void eth_tx_thread_entry(void* parameter)
{
   struct eth_tx_msg* msg;
   while (1)
   {
       if (rt_mb_recv(e_tx_thread_mb, (rt_ubase_t *)&msg, RT_WAITING_FOREVER) == RT_EOK)
       {
           struct eth_device* enetif;

           RT_ASSERT(msg->netif != RT_NULL);
           RT_ASSERT(msg->buf   != RT_NULL);

           enetif = (struct eth_device*)msg->netif->state;
           if (enetif != RT_NULL)
           {
               /* call driver's interface */
               if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK)
               {
                   /* transmit eth packet failed */
               }
           }

           /* send ACK */
           rt_sem_release(&(enetif->tx_ack));
       }
   }
}

etx 等待 `ethernetif_linkoutput` 的郵件消息,然后調(diào)用 eth 驅(qū)動(dòng)接口函數(shù),完成后釋放信號(hào)量給 `ethernetif_linkoutput`一個(gè)應(yīng)答。

從這里看,用上這個(gè)線程,需要額外增加兩次 ipc 消息。
去掉 etx 之后呢?`ethernetif_linkoutput` 變成下面的樣子。

static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{
   struct eth_device* enetif;
   RT_ASSERT(netif != RT_NULL);
   enetif = (struct eth_device*)netif->state;

   if (enetif->eth_tx(&(enetif->parent), p) != RT_EOK)
   {
       return ERR_IF;
   }
   return ERR_OK;
}

與使用 etx 線程唯一不同的是:使用線程時(shí),發(fā)送數(shù)據(jù)操作 eth 驅(qū)動(dòng)都在 etx 線程里進(jìn)行的;如果去掉,就有可能多個(gè)應(yīng)用線程同時(shí)發(fā)送數(shù)據(jù),出現(xiàn)多個(gè)線程競(jìng)爭(zhēng) eth 驅(qū)動(dòng)資源的現(xiàn)象。但是,這個(gè)可以經(jīng)過優(yōu)化應(yīng)用層業(yè)務(wù)邏輯進(jìn)行規(guī)避。

更多關(guān)于不使用 etx 和 erx 線程的修改,請(qǐng)移步我的 gitee 倉(cāng)庫(kù)。

本系列提到的所有代碼更改已經(jīng)提交到 gitee ,歡迎大家測(cè)試
https://gitee.com/thewon/rt_thread_repo

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • LwIP
    +關(guān)注

    關(guān)注

    2

    文章

    84

    瀏覽量

    26935
  • 裁剪
    +關(guān)注

    關(guān)注

    0

    文章

    8

    瀏覽量

    7091
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1239

    瀏覽量

    39435
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【原創(chuàng)精選】RT-Thread征文精選技術(shù)文章合集

    漂移問題分析rt-thread 優(yōu)化系列(四)信號(hào)對(duì) ipc 的影響rt-thread 優(yōu)化系列
    發(fā)表于 07-26 14:56

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開發(fā)組(2015-03-31)。RT-Thread做為國(guó)內(nèi)有較大影響力的開源實(shí)時(shí)操作系統(tǒng),本文是RT-Thread實(shí)時(shí)操作系統(tǒng)的編程指南
    發(fā)表于 11-26 16:06 ?0次下載

    RT-Thread開發(fā),如何有效學(xué)習(xí)RT-Thread個(gè)步驟

    RT-Thread推出RT-Thread Inside戰(zhàn)略開放RT-Thread開發(fā)平臺(tái)授權(quán)合作,與硬件十萬個(gè)為什么合作首次推出第一款RT-Inside的開發(fā)板——iBox物聯(lián)網(wǎng)開發(fā)套
    的頭像 發(fā)表于 09-25 09:55 ?3.4w次閱讀
    <b class='flag-5'>RT-Thread</b>開發(fā),如何有效學(xué)習(xí)<b class='flag-5'>RT-Thread</b>的<b class='flag-5'>五</b>個(gè)步驟

    RT-Thread Smart已正式上線

    rt-smart內(nèi)核即可包含基本功能,同時(shí)也可定制裁剪。rt-smart用戶態(tài)應(yīng)用環(huán)境采用musl libc提供POSIX接口調(diào)用及C運(yùn)行環(huán)境,延續(xù) RT-Thread 原有的生態(tài),使
    的頭像 發(fā)表于 11-29 10:31 ?2688次閱讀

    RT-Thread (2) RTT SPI設(shè)備驅(qū)動(dòng)流程 || LWIP + ENC28J60

    系列文章目錄RT-Thread (1) 添加外部?jī)?nèi)存到內(nèi)存管理RT-Thread (2) RTT SPI設(shè)備驅(qū)動(dòng)流程 || LWIP + ENC28J60目錄0 概述0.0 參考資料0
    發(fā)表于 11-19 14:21 ?15次下載
    <b class='flag-5'>RT-Thread</b> (2) RTT SPI設(shè)備驅(qū)動(dòng)流程 || <b class='flag-5'>LWIP</b> + ENC28J60

    RT-thread】如何將RT-thread系統(tǒng)移植到stm32

    設(shè)備,RT-Thread 又能使用在線的軟件包管理工具,配合系統(tǒng)配置工具實(shí)現(xiàn)直觀快速的模塊化裁剪,無縫地
    發(fā)表于 12-08 11:06 ?20次下載
    【<b class='flag-5'>RT-thread</b>】如何將<b class='flag-5'>RT-thread</b>系統(tǒng)移植到stm32

    RT-Thread學(xué)習(xí)筆記 RT-Thread的架構(gòu)概述

    RT-Thread 簡(jiǎn)介 作為一名 RTOS 的初學(xué)者,也許你對(duì) RT-Thread 還比較陌生。然而,隨著你的深入接觸,你會(huì)逐漸發(fā)現(xiàn) RT-Thread 的魅力和它相較于其他同類型 RTOS
    的頭像 發(fā)表于 07-09 11:27 ?4321次閱讀
    <b class='flag-5'>RT-Thread</b>學(xué)習(xí)筆記 <b class='flag-5'>RT-Thread</b>的架構(gòu)概述

    RT-Thread文檔_RT-Thread 簡(jiǎn)介

    RT-Thread文檔_RT-Thread 簡(jiǎn)介
    發(fā)表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡(jiǎn)介

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南
    發(fā)表于 02-22 18:23 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發(fā)表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    基于RT-Thread Studio學(xué)習(xí)

    前期準(zhǔn)備:從官網(wǎng)下載 RT-Thread Studio,弄個(gè)賬號(hào)登陸,開啟rt-thread學(xué)習(xí)之旅。
    的頭像 發(fā)表于 05-15 11:00 ?3497次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio學(xué)習(xí)

    RT-Thread標(biāo)準(zhǔn)版裁剪記錄

    RT-Thread 下的 BSP 里適配了非常豐富的工具,但有的時(shí)候既想直接使用這些便捷的工具,又想縮減代碼體量。
    的頭像 發(fā)表于 07-31 14:28 ?736次閱讀
    <b class='flag-5'>RT-Thread</b>標(biāo)準(zhǔn)版<b class='flag-5'>裁剪</b>記錄

    RT-Thread v5.0.2 發(fā)布

    RT-Thread 代碼倉(cāng)庫(kù)地址: ●? https://github.com/RT-Thread/rt-thread RT-Thread 5.0.2 版本發(fā)布日志詳情: ●? htt
    的頭像 發(fā)表于 10-10 18:45 ?1202次閱讀
    <b class='flag-5'>RT-Thread</b> v5.0.2 發(fā)布

    RT-Thread移植使用webserver (lwip+httpd)

    開發(fā)環(huán)境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的資源包為0.2.2,rt-thread版本為4.0.3。
    的頭像 發(fā)表于 10-12 12:49 ?1072次閱讀
    <b class='flag-5'>RT-Thread</b>移植使用webserver (<b class='flag-5'>lwip</b>+httpd)

    RT-Thread在Lan8720a和 lwip基礎(chǔ)上移植ntp流程

    開發(fā)環(huán)境:野火的stm32f407,rt-thread studio版本是版本: 2.2.6,stm32f4的資源包為0.2.2。以RT-Thread中Lan8720和lwip協(xié)議棧的使用文章創(chuàng)建的工程為基礎(chǔ)。
    的頭像 發(fā)表于 10-12 16:59 ?1479次閱讀
    <b class='flag-5'>RT-Thread</b>在Lan8720a和 <b class='flag-5'>lwip</b>基礎(chǔ)上移植ntp流程