色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

發燒友實測 | i.MX8MP 編譯DPDK源碼實現rte_ring無鎖環隊列進程間通信

飛凌嵌入式 ? 2022-01-10 16:29 ? 次閱讀

ad6972f6-6fd6-11ec-86cf-dac502259ad0.jpg

作者|donatello1996

來源 | 電子發燒友

題圖|飛凌嵌入式

rte_ring是一個用CAS實現的無鎖FIFO環形隊列,支持多消費者/生產者同時出入隊列,常用于多線程/多進程之間的通信。具體原理可以查看DPDK官方文檔或者閱讀源碼,本文采用的硬件板卡為飛凌嵌入式OKMX8MP-C開發板,系統版本Linux5.4.70+Qt5.15.0,主要介紹通過編譯DPDK源碼實現rte_ring無鎖環隊列進程間通信

下面就跟著小編一起了解下。

一、內核編譯

下載并解壓飛凌廠商提供的iMX8MP內核源碼壓縮包分卷:

ad94f48a-6fd6-11ec-86cf-dac502259ad0.jpg

在虛擬機中合并壓縮分卷并解壓得出內核源碼包文件夾OK8MP-linux-kernel,將文件夾使用tar打包并復制到TF卡文件系統中解壓:

adcb86f8-6fd6-11ec-86cf-dac502259ad0.jpg

找到內核源碼中的配置文件OK8MP-C_defconfig:

ade9250a-6fd6-11ec-86cf-dac502259ad0.jpg

這個就是make選項,使用

make OK8MP-C_defconfig

指令即可配置編譯選項:

make -j4

開始編譯:

注意開始編譯前需要安裝常用軟件:

apt install bison bc flex

ae1a54cc-6fd6-11ec-86cf-dac502259ad0.jpg

ae5d461a-6fd6-11ec-86cf-dac502259ad0.jpg

增量編譯完畢:

ae99b79e-6fd6-11ec-86cf-dac502259ad0.jpg

二、DPDK編譯

接下來就可以下載DPDK并運行rte_ring無鎖環隊列Demo應用,需要從

https://www.dpdk.org/

官網中下載DPDK 19.11.10 (LTS)長期支持版本:

aed037f6-6fd6-11ec-86cf-dac502259ad0.jpg

在根目錄下的mk/文件夾下找到名為rte_vars.mk設置文件,找到環境變量RTE_KERNELDIR,修改為上述的內核源碼路徑:

aef06c42-6fd6-11ec-86cf-dac502259ad0.jpg

af1baf2e-6fd6-11ec-86cf-dac502259ad0.jpg

RTE_KERNELDIR ?= /home/OK8MP-linux-kernel/

進入usertools文件夾,找到dpdk-setup.sh腳本并運行

af50d12c-6fd6-11ec-86cf-dac502259ad0.jpg

afa77ef0-6fd6-11ec-86cf-dac502259ad0.jpg

選擇8,ARM64-armv8a-linuxapp-gcc,

aff63860-6fd6-11ec-86cf-dac502259ad0.jpg

這個選項會使dpdk的gcc交叉編譯鏈生成適用于armv8a處理器的外部庫,外部庫中有kmod和lib等ko文件和so文件,是用于第三方程序開發和運行的:

b02ae736-6fd6-11ec-86cf-dac502259ad0.jpg

b062a59a-6fd6-11ec-86cf-dac502259ad0.jpg

使用指令

insmod /home/dpdk-stable-19.11.10/arm64-armv8a-linuxapp-gcc/kmod/igb_uio.ko
左右滑動查看完整代碼

加載igb_uio.ko驅動文件,這是進行dpdk開發必備的步驟:

b09bad04-6fd6-11ec-86cf-dac502259ad0.jpg

然后是使用dpdk-devbind.py腳本手動進行hugepage大頁內存綁定,此處為numa方式:

b0c8c2ee-6fd6-11ec-86cf-dac502259ad0.jpg

此舉會將/mnt/huge文件mount成hugepage映射文件,并實實在在地占用內存空間:

b104b54c-6fd6-11ec-86cf-dac502259ad0.jpg
b12e5848-6fd6-11ec-86cf-dac502259ad0.jpg

三、rte_ring無鎖環隊列

準備工作完成,我們接下來可以進行rte_ring無鎖環隊列Demo代碼的編寫,但是在編寫之前,需要對無鎖環隊列有一個基本的認識:https://blog.csdn.net/chen98765432101/article/details/69367633


無論是dpdk第三方開發的rte_ring還是Linux內核中本就存在的無鎖環隊列,其基本原理類似,在一條分配好的隊列型內存空間中,讀寫方式為FIFO(先進先出),讀和寫的動作分別有兩個進程或兩個線程進行,寫進程不斷往地址自增的內存位置寫入數據,讀進程不斷讀取地址自增的內存位置的數據,當寫位置的內存地址已為隊列中內存的最高值時,需要釋放隊列中內存地址最低值的空間供寫進程繼續寫,方式仍與上一周期相同(不斷往地址自增的內存位置寫入數據),釋放過程需要保證對末尾內存地址空間的鎖定與解鎖,避免讀寫過程出錯。而不同的是,Linux內核中的無鎖環隊列,地址管理和讀寫控制均由內核進行,而dpdk的rte_ring則由dpdk內部的控制器進行,因為dpdk這一模塊完整地接管了所分配內存空間的管理權,是直接繞過Linux內核進行管理的,內核也無權訪問dpdk控制器的具體管理細節。

b166ff54-6fd6-11ec-86cf-dac502259ad0.jpg

b1bab982-6fd6-11ec-86cf-dac502259ad0.jpg

b1f20900-6fd6-11ec-86cf-dac502259ad0.jpg

b2256d7c-6fd6-11ec-86cf-dac502259ad0.jpg

編寫無鎖環隊列兩個進程的Demo,先寫Primary進程:

#include #include #include #include #include #include #include #include #include #include 
#include #include 
#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
static const char *_MSG_POOL = "MSG_POOL";static const char *_SEC_2_PRI = "SEC_2_PRI";static const char *_PRI_2_SEC = "PRI_2_SEC";static const char *_PRI_2_THI = "PRI_2_THI";
struct rte_ring *send_ring, *recv_ring , *send_ring_third;struct rte_mempool *message_pool;volatile int quit = 0;
static void * lcore_recv(void *arg){        unsigned lcore_id = rte_lcore_id();
        printf("Starting core %u\n", lcore_id);        while (!quit){                void *msg;                if (rte_ring_dequeue(recv_ring, &msg) < 0)                {                        usleep(5);                        continue;                }                printf("lcore_id = %d Received '%s'\n" , lcore_id , (char *)msg);                rte_mempool_put(message_pool , msg);        }
        return 0;}
int string_size = 100;int elt_size = 128;pthread_t id1;
int main(int argc, char **argv){        const unsigned flags = 0;        const unsigned ring_size = 64;        const unsigned pool_size = 1024;        const unsigned pool_cache = 32;        const unsigned priv_data_sz = 0;
        int ret;        unsigned lcore_id;
        ret = rte_eal_init(argc, argv);        if (ret < 0)                rte_exit(EXIT_FAILURE, "Cannot init EAL\n");
        send_ring = rte_ring_create(_PRI_2_SEC, ring_size, rte_socket_id(), flags);        recv_ring = rte_ring_create(_SEC_2_PRI, ring_size, rte_socket_id(), flags);        send_ring_third = rte_ring_create(_PRI_2_THI, ring_size, rte_socket_id(), flags);        message_pool = rte_mempool_create(_MSG_POOL, pool_size,                        elt_size, pool_cache, priv_data_sz,                        NULL, NULL, NULL, NULL,                        rte_socket_id(), flags);
        if (send_ring == NULL)                rte_exit(EXIT_FAILURE, "Problem getting sending ring\n");
        if (recv_ring == NULL)                rte_exit(EXIT_FAILURE, "Problem getting receiving ring\n");
        if (send_ring_third == NULL)                rte_exit(EXIT_FAILURE, "Problem getting send_ring_third\n");
        if (message_pool == NULL)                rte_exit(EXIT_FAILURE, "Problem getting message pool\n");
        pthread_create(&id1 , NULL , lcore_recv , NULL);        while(1)        {                void *msg = NULL;                if (rte_mempool_get(message_pool, &msg) < 0)                        continue;
                snprintf((char *)msg, string_size, "%s", "primary to secondary");                if (rte_ring_enqueue(send_ring , msg) < 0)                 {                        rte_mempool_put(message_pool, msg);                }
                if (rte_mempool_get(message_pool, &msg) < 0)                        continue;
                snprintf((char *)msg, string_size, "%s", "primary to third");                if (rte_ring_enqueue(send_ring_third , msg) < 0)                 {                        rte_mempool_put(message_pool, msg);                }
                sleep(1);        }
        return 0;}
左右滑動查看完整代碼

注意在Makefile文件里面要關閉WERROR相關編譯選項:

#   BSD LICENSE##   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.#   All rights reserved.##   Redistribution and use in source and binary forms, with or without#   modification, are permitted provided that the following conditions#   are met:##     * Redistributions of source code must retain the above copyright#       notice, this list of conditions and the following disclaimer.#     * Redistributions in binary form must reproduce the above copyright#       notice, this list of conditions and the following disclaimer in#       the documentation and/or other materials provided with the#       distribution.#     * Neither the name of Intel Corporation nor the names of its#       contributors may be used to endorse or promote products derived#       from this software without specific prior written permission.##   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ifeq ($(RTE_SDK),)$(error "Please define RTE_SDK environment variable")endif
# Default target, can be overridden by command line or environmentRTE_TARGET ?= arm64-armv8a-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
# binary nameAPP = rte_ring_primary
# all source are stored in SRCS-ySRCS-y := main.c
CFLAGS += -O0CFLAGS += 
include $(RTE_SDK)/mk/rte.extapp.mk
左右滑動查看完整代碼

Secondary進程:

#include #include #include #include #include #include #include #include #include #include 
#include #include 
#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
static const char *_MSG_POOL = "MSG_POOL";static const char *_SEC_2_PRI = "SEC_2_PRI";static const char *_PRI_2_SEC = "PRI_2_SEC";
struct rte_ring *send_ring, *recv_ring;struct rte_mempool *message_pool;volatile int quit = 0;int string_size = 100;
static int lcore_send(__attribute__((unused)) void *arg){        unsigned lcore_id = rte_lcore_id();
        while(1)        {                void *msg = NULL;                if (rte_mempool_get(message_pool, &msg) < 0)                        continue;
                snprintf((char *)msg , string_size , "%s", "secondary to primary");                if (rte_ring_enqueue(send_ring , msg) < 0)                 {                        rte_mempool_put(message_pool, msg);                }                sleep(1);        }        return 0;}
pthread_t id1;
int main(int argc, char **argv){        const unsigned flags = 0;        const unsigned ring_size = 64;        const unsigned pool_size = 1024;        const unsigned pool_cache = 32;        const unsigned priv_data_sz = 0;
        int ret;        unsigned lcore_id;        ret = rte_eal_init(argc, argv);        if (ret < 0)                rte_exit(EXIT_FAILURE, "Cannot init EAL\n");
        recv_ring = rte_ring_lookup(_PRI_2_SEC);        send_ring = rte_ring_lookup(_SEC_2_PRI);        message_pool = rte_mempool_lookup(_MSG_POOL);
        if (send_ring == NULL)                rte_exit(EXIT_FAILURE, "Problem getting sending ring\n");        if (recv_ring == NULL)                rte_exit(EXIT_FAILURE, "Problem getting receiving ring\n");        if (message_pool == NULL)                rte_exit(EXIT_FAILURE, "Problem getting message pool\n");
        pthread_create(&id1 , NULL , lcore_send , NULL);    while (1)        {                lcore_id = rte_lcore_id();        void * msg = NULL;        if (rte_ring_dequeue(recv_ring, &msg) < 0)                {            usleep(5);            continue;        }
        printf("lcore_id = %d Received: %s\n" , lcore_id , (char *)msg);
        rte_mempool_put(message_pool, msg);    }
        return 0;}

左右滑動查看完整代碼

同樣在Makefile文件里面要關閉WERROR相關編譯選項:

#   BSD LICENSE##   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.#   All rights reserved.##   Redistribution and use in source and binary forms, with or without#   modification, are permitted provided that the following conditions#   are met:##     * Redistributions of source code must retain the above copyright#       notice, this list of conditions and the following disclaimer.#     * Redistributions in binary form must reproduce the above copyright#       notice, this list of conditions and the following disclaimer in#       the documentation and/or other materials provided with the#       distribution.#     * Neither the name of Intel Corporation nor the names of its#       contributors may be used to endorse or promote products derived#       from this software without specific prior written permission.##   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ifeq ($(RTE_SDK),)$(error "Please define RTE_SDK environment variable")endif
# Default target, can be overridden by command line or environmentRTE_TARGET ?= arm64-armv8a-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
# binary nameAPP = rte_ring_secondary
# all source are stored in SRCS-ySRCS-y := main.c
CFLAGS += -O3CFLAGS += $()
include $(RTE_SDK)/mk/rte.extapp.mk
左右滑動查看完整代碼

運行,這里說一下,基于rte_ring的進程間通信,Secondary進程最好是使用auto類型:

./rte_ring_primary --proc-type primary./rte_ring_secondary --proc-type auto

運行效果:

b254fb0a-6fd6-11ec-86cf-dac502259ad0.jpg

b2a99c3c-6fd6-11ec-86cf-dac502259ad0.jpg

作者簡介

donatello1996,某大型企業資深嵌入式工程師,電子發燒友論壇技術大牛,同時也是飛凌嵌入式多年鐵粉,曾基于飛凌多款板卡產出過優質測評文章或使用心得。本期三篇文章為donatello1996在使用OKMX8MP-C開發板過程中精心產出的干貨,在此對donatello1996表示感謝。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5085

    文章

    19138

    瀏覽量

    305700
收藏 人收藏

    評論

    相關推薦

    電子發燒友網祝大家新春快樂?。?/a>

    電子發燒友網祝大家新春快樂!
    的頭像 發表于 02-09 00:01 ?4908次閱讀
    電子<b class='flag-5'>發燒友</b>網祝大家新春快樂!!

    面向NXP i.MX8處理器的電源解決方案

    電子發燒友網站提供《面向NXP i.MX8處理器的電源解決方案.pdf》資料免費下載
    發表于 12-24 15:53 ?0次下載
    面向NXP <b class='flag-5'>i.MX8</b>處理器的電源解決方案

    華秋電子 | 電子發燒友亮相OpenHarmony人才生態大會2024

    ,分享高校、企業在產學研融合方面的先進經驗,全面展現了OpenHarmony在人才生態領域學-考-用-賽-留各環節的最新成果與發展藍圖。華秋電子<電子發燒友>作為合作社
    發表于 12-02 09:45

    基于AR1335和i.MX8MP的視覺方案

    應用中實現卓越的圖像處理效果。方案采用NXPi.MX8MP處理器和onsemiAR1335圖像傳感器,i.MX8MP集成四核Cortex-A53、NPU及雙ISP
    的頭像 發表于 11-13 01:01 ?240次閱讀
    基于AR1335和<b class='flag-5'>i.MX8MP</b>的視覺方案

    強大視覺方案:i.MX8MP與AR0144的完美結合

    大聯大友尚集團推出基于NXPi.MX8MP處理器和onsemiAR0144圖像傳感器的全新視覺方案。該方案不僅具備強大的圖像處理能力,還能廣泛應用于監控、智能零售、機器人視覺等領域。一、應用場景描述及市場優勢該方案采用NXP的i.MX8MP作為主控平臺,搭配onsemi的
    的頭像 發表于 10-29 08:04 ?229次閱讀
    強大視覺方案:<b class='flag-5'>i.MX8MP</b>與AR0144的完美結合

    i.MX Linux開發實戰指南—基于野火i.MX系列開發板

    電子發燒友網站提供《i.MX Linux開發實戰指南—基于野火i.MX系列開發板.pdf》資料免費下載
    發表于 10-10 17:23 ?11次下載

    使用TPS65051為Freescale? i.MX25供電

    電子發燒友網站提供《使用TPS65051為Freescale? i.MX25供電.pdf》資料免費下載
    發表于 10-10 10:10 ?0次下載
    使用TPS65051為Freescale? <b class='flag-5'>i.MX</b>25供電

    恩智浦i.MX8處理器的集成電源設計

    電子發燒友網站提供《恩智浦i.MX8處理器的集成電源設計.pdf》資料免費下載
    發表于 09-18 14:25 ?0次下載
    恩智浦<b class='flag-5'>i.MX8</b>處理器的集成電源設計

    使用TPS6521825和LP873347 PMIC為NXP i.MX 8M Mini和Nano供電

    電子發燒友網站提供《使用TPS6521825和LP873347 PMIC為NXP i.MX 8M Mini和Nano供電.pdf》資料免費下載
    發表于 09-13 09:42 ?0次下載
    使用TPS6521825和LP873347 PMIC為NXP <b class='flag-5'>i.MX</b> <b class='flag-5'>8</b>M Mini和Nano供電

    MSPM0 UART通信中DMA和Ring Buffer環形緩沖的應用

    電子發燒友網站提供《MSPM0 UART通信中DMA和Ring Buffer環形緩沖的應用.pdf》資料免費下載
    發表于 09-05 11:01 ?0次下載
    MSPM0 UART<b class='flag-5'>通信</b>中DMA和<b class='flag-5'>Ring</b> Buffer環形緩沖的應用

    使用TPS65219為i.MX 8M Plus供電

    電子發燒友網站提供《使用TPS65219為i.MX 8M Plus供電.pdf》資料免費下載
    發表于 08-31 10:15 ?0次下載
    使用TPS65219為<b class='flag-5'>i.MX</b> <b class='flag-5'>8</b>M Plus供電

    互斥和自旋實現原理

    保護共享資源不被多個線程同時訪問。它的實現原理主要包括以下幾個方面: 1. 的初始化 互斥鎖在創建時需要進行初始化,通常包括設置的狀態為“未鎖定”。在某些實現中,還需要初始化
    的頭像 發表于 07-10 10:07 ?505次閱讀

    華秋DFM注冊賬號,電子發燒友論壇改不了id名稱

    我注冊了一個華秋DFM賬號,后用此賬號登錄電子發燒友發現我的名字是系統給的,改也改不了,注銷也注銷不了,請華秋和電子發燒友官方盡快跟進處理
    發表于 07-07 10:45

    進程通信的消息隊列介紹

    消息隊列是一種非常常見的進程通信方式。
    的頭像 發表于 04-08 17:27 ?314次閱讀

    使用i.MX RT500實現SPI/DMA AN14170應用指南

    電子發燒友網站提供《使用i.MX RT500實現SPI/DMA AN14170應用指南.pdf》資料免費下載
    發表于 02-01 10:05 ?0次下載
    使用<b class='flag-5'>i.MX</b> RT500<b class='flag-5'>實現</b>SPI/DMA AN14170應用指南
    主站蜘蛛池模板: 暖暖日本 在线 高清| 99精品视频在线观看免费| 亚洲AV怡红院影院怡春院| 久久久黄色片| 国产99网站| 99国产视频| 一本道无码v亚洲| 偷窥美女3| 好男人社区| 动漫美女3d被爆漫画| 7723日本高清完整版在线观看| 无修肉动漫在线观看影片| 强奷表妺好紧2| 久久综合色视频| 含羞草传媒在线观看| 高H辣肉办公室| 菠萝菠萝蜜视频在线看1| 717影院理论午夜伦不卡久久| 亚洲精品在线免费| 小小水蜜桃视频高清在线观看免费 | 与子敌伦刺激对白亂輪亂性| 偷偷鲁手机在线播放AV| 欧洲美女人 一级毛片| 美女被爽cao免费漫画| 好湿好滑好硬好爽好深视频| 国产精品成人影院| 粗暴玩烂货调教| 芭乐草莓樱桃丝瓜18岁大全| 亚洲国产AV精品卡一卡二| 色婷婷AV国产精品欧美毛片| 青青青手机视频| 全彩无翼污之邪恶女教师| 欧美性最猛xxxx在线观看视频| 蜜桃日本MV免费观看| 凌馨baby| 免费国产福利| 年轻夫妇韩剧中文版免费观看| 六度影院最新| 蜜臀久久99精品久久久久久做爰| 麻豆国产人妻欲求不满| 乱码国产丰满人妻WWW|