当前位置: 首页 > news >正文

ZeroMQ介绍及如何交叉编译在嵌入式Linux下使用

什么是ZeroMQ?

ZeroMQ(也称为ØMQ或ZMQ)是一个高性能的异步消息库,用于在分布式或多线程应用程序中传递消息。它提供了套接字抽象,允许开发人员以简单的API设计复杂的消息模式。ZeroMQ的设计宗旨是为高吞吐量、低延迟的消息传递提供支持,适用于需要快速、可靠和可扩展的数据传输的场景。

ZeroMQ的主要特性

  • 高性能:ZeroMQ在内存管理和调度方面进行了优化,能够达到低延迟和高吞吐量的要求。
  • 跨平台:支持多种操作系统,包括Linux、Windows和OSX。
  • 多种消息模式:支持请求-应答、发布-订阅、推-拉等多种通信模式,灵活性高。
  • 异步I/O:基于事件驱动的模型,能够处理高并发的消息。
  • 轻量级:ZeroMQ的库相对较小,便于嵌入到各种应用程序和设备中。

在嵌入式Linux下使用ZeroMQ

在嵌入式Linux平台上使用ZeroMQ,首先需要交叉编译它的库,以下是详细步骤。

准备交叉编译工具链

首先,确保你有一个合适的交叉编译工具链。以下是一个示例的CMake工具链配置文件,假设目标架构为ARM。

创建一个名为 toolchain.cmake 的文件,内容如下:

# 交叉编译工具链配置文件set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)# 设置ARM工具链的路径
set(ARM_TOOLCHAIN_PREFIX "/path/to/your/toolchain/arm-linux-gnueabi")set(CMAKE_C_COMPILER "${ARM_TOOLCHAIN_PREFIX}-gcc")
set(CMAKE_CXX_COMPILER "${ARM_TOOLCHAIN_PREFIX}-g++")
set(CMAKE_FIND_ROOT_PATH "/path/to/sysroot")# 查找规则
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

请确保将工具链路径和sysroot路径替换为您自己的路径。

获取ZeroMQ源码

从ZeroMQ的GitHub仓库下载源码。您可以通过以下命令获取:

git clone https://github.com/zeromq/libzmq.git
## 如果是c++,则还需要使用下面这个:
git clone https://github.com/zeromq/cppzmq.git

交叉编译ZeroMQ

在下载的ZeroMQ源码目录下创建一个构建目录:

cd libzmq
mkdir build
cd build

然后使用CMake和之前创建的工具链文件进行配置:

cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake -DCMAKE_INSTALL_PREFIX=/path/to/install
  • CMAKE_INSTALL_PREFIX:指定安装路径。

配置完成后,运行Make进行编译和安装:

make
make install

使用cppzmq

 https://github.com/zeromq/cppzmq 

cppzmq 是 libzmq 的 C++ 绑定库。其设计目标如下:

cppzmq 将 libzmq 的 C API 映射到 C++ 概念。具体来说:

  • 它是类型安全的(libzmq 的 C API 将各种类似于类的概念暴露为 void*)
  • 它提供基于异常的错误处理(libzmq 的 C API 提供基于 errno 的错误处理)
  • 它提供遵循 RAII 风格的类以自动化资源管理(libzmq 的 C API
    要求用户显式地释放资源)

cppzmq 是一个轻量级的、仅包含头文件的绑定库。您只需包含头文件 zmq.hpp(及可能的 zmq_addon.hpp)即可使用。
zmq.hpp 旨在包含 libzmq C API 提供的抽象的直接映射,而 zmq_addon.hpp 提供了额外的更高级别的抽象。

注意,使用这个库同样需要先安装上面的libzmq,比如上面的是安装在${HOME}/arm_install路径下。

如果使用cmake的方式使用则需要下面的操作:

#1. cd cppzmq,cd build
cd cppzmd
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=${HOME}/arm_install -DCPPZMQ_BUILD_TESTS=OFF -DZeroMQ_INCLUDE_DIR=${HOME}/arm_install/include/ -DZeroMQ_LIBRARY=${HOME}/arm_install/lib/
#2.
make
#3.安装
make install

在这里插入图片描述
在这里插入图片描述

在嵌入式Linux项目中使用ZeroMQ

在您的嵌入式Linux项目代码中,您可以通过包含ZeroMQ的头文件来使用它:

#include <zmq.hpp>
#include <iostream>int main() {// 创建上下文zmq::context_t context(1);// 创建一个请求套接字zmq::socket_t socket(context, ZMQ_REQ);socket.connect("tcp://localhost:5555");// 发送消息zmq::message_t request(5);memcpy(request.data(), "Hello", 5);socket.send(request);// 接收回复zmq::message_t reply;socket.recv(&reply);std::cout << "Received: " << static_cast<char*>(reply.data()) << std::endl;return 0;
}

测试demo 的 CMakeLists.txt文件内容如下:

cmake_minimum_required(VERSION 3.5)
project(zmq_example)# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 获取 ZeroMQ 库
find_package(cppzmq REQUIRED)# 添加你的可执行文件
add_executable(zmq_example main.cpp)# 链接 cppzmq 库
target_link_libraries(zmq_example cppzmq)

创建build文件夹,cd build, 然后执行以下指令:

cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake -DTARGET_ARCH=arm 
#
make

在这里插入图片描述

在上述示例中,我们创建了一个ZeroMQ请求套接字,连接到指定的端口,发送了一条消息并接收了回复。

附:toolchain.cmake文件:
我的开发板环境: 正点原子 imx6ul开发板

# 交叉编译工具链配置文件
# 用于嵌入式Linux系统和RISC-V MCU的交叉编译# 设置系统名称
set(CMAKE_SYSTEM_NAME Linux)# 设置处理器架构变量,可以通过命令行参数传入
# 例如: cmake -DTARGET_ARCH=arm ..
if(NOT DEFINED TARGET_ARCH)set(TARGET_ARCH "arm" CACHE STRING "Target architecture (arm or riscv)")
endif()# 设置ARM工具链路径
set(ARM_TOOLCHAIN_PATH "/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi")
# 设置RISC-V工具链路径
set(RISCV_TOOLCHAIN_PATH "/opt/tronlong/tina5.0_v1.0/rtos/lichee/rtos/tools/riscv64-elf-x86_64-20201104")# 根据目标架构设置主工具链
if(${TARGET_ARCH} STREQUAL "arm")# ARM Linux工具链配置set(CMAKE_C_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-gcc)set(CMAKE_CXX_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-g++)set(CMAKE_FIND_ROOT_PATH /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnueabi/)set(CMAKE_SYSTEM_PROCESSOR arm)# 设置额外的编译标志set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfloat-abi=hard -mfpu=neon" CACHE STRING "" FORCE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfloat-abi=hard -mfpu=neon" CACHE STRING "" FORCE)# 设置链接器set(CMAKE_LINKER ${CMAKE_C_COMPILER})set(CMAKE_AR ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-ar)set(CMAKE_RANLIB ${ARM_TOOLCHAIN_PATH}/arm-poky-linux-gnueabi-ranlib)elseif(${TARGET_ARCH} STREQUAL "riscv")# RISC-V工具链配置 (C906核心)set(CMAKE_C_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-gcc)set(CMAKE_CXX_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-g++)set(CMAKE_FIND_ROOT_PATH ${RISCV_TOOLCHAIN_PATH}/riscv64-unknown-elf)set(CMAKE_SYSTEM_PROCESSOR riscv)# 设置RISC-V特定的编译标志 (C906核心)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv64gcv0p7 -mabi=lp64d" CACHE STRING "" FORCE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64gcv0p7 -mabi=lp64d" CACHE STRING "" FORCE)# 设置链接器set(CMAKE_LINKER ${CMAKE_C_COMPILER})set(CMAKE_AR ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ar)set(CMAKE_RANLIB ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ranlib)else()message(FATAL_ERROR "不支持的目标架构: ${TARGET_ARCH}. 请使用 'arm' 或 'riscv'")
endif()# 定义ARM工具链变量,供CMakeLists.txt使用
set(ARM_C_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-gcc)
set(ARM_CXX_COMPILER ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-g++)
set(ARM_AR ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-ar)
set(ARM_RANLIB ${ARM_TOOLCHAIN_PATH}/arm-linux-gnueabi-ranlib)
set(ARM_C_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")
set(ARM_CXX_FLAGS "-march=armv7-a -mfloat-abi=hard -mfpu=neon")# 定义RISC-V工具链变量,供CMakeLists.txt使用
set(RISCV_C_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-gcc)
set(RISCV_CXX_COMPILER ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-g++)
set(RISCV_AR ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ar)
set(RISCV_RANLIB ${RISCV_TOOLCHAIN_PATH}/bin/riscv64-unknown-elf-ranlib)
set(RISCV_C_FLAGS "-march=rv64gcv0p7 -mabi=lp64d")
set(RISCV_CXX_FLAGS "-march=rv64gcv0p7 -mabi=lp64d")# 设置查找规则
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)# 禁用系统库路径
set(CMAKE_SKIP_RPATH TRUE)# 设置交叉编译环境的库和头文件搜索路径
set(CMAKE_SYSROOT ${CMAKE_FIND_ROOT_PATH}) # 关键!!!,不能漏掉这个设置
set(CMAKE_FIND_ROOT_PATH /root/arm_install)

总结

ZeroMQ是一个强大且灵活的消息传递库,适合多种场景,尤其是在嵌入式Linux系统中。通过交叉编译,您可以轻松将ZeroMQ集成到嵌入式项目中,为您的应用提供高性能的消息传递能力。希望本文对您在嵌入式环境中使用ZeroMQ有所帮助!


http://www.mrgr.cn/news/96184.html

相关文章:

  • ESP32-CAM在PlatformIO IDE里实现OTA的几个小TIPS
  • 骨密度以及骨密度测量,测量方案,意义;提高;实现方案
  • jmeter 镜像构建
  • C语言学习关键笔记
  • 数据结构C语言练习(顺序表)
  • 论文阅读笔记:Denoising Diffusion Implicit Models
  • nara wpe去混响学习笔记
  • 力扣刷题第一遍
  • Microi吾码界面设计引擎之基础组件用法大全【内置组件篇·中】
  • Leetcode算法方法总结
  • 生成器的应用 async与await实现
  • 【leetcode hot 100 347】前 K 个高频元素
  • centos8上实现lvs集群负载均衡nat模式
  • mysql--主从复制--部署
  • 循环神经网络(RNN)
  • 大数据(2)Hadoop架构深度拆解:HDFS与MapReduce企业级实战与高阶调优
  • STM32F103_LL库+寄存器学习笔记08 - DMA串口发送,开启DMA传输完成中断
  • java程序员实用英语学习总结
  • STM32F103_LL库+寄存器学习笔记07 - 串口接收缓冲区非空中断
  • 网络安全法律法规简介