CyberRt源码剖析--06基于有向图的拓扑机制设计
6.1 拓扑图中的角色定义在发布-订阅架构的基础上,进一步抽象出拓扑图中的角色,以清晰描述节点间的通信关系。如图所示,拓扑图中的核心角色包括Publisher(发布者)、Subscriber(订阅者)和Node(节点)。这些角色的定义如下:
Publisher(发布者):负责生成并发布数据的实体,对应于前文所述的Transmitter。一个Publisher通过指定的Channel发布数据,其身份由Identity和RoleAttributes唯一标识。
Subscriber(订阅者):负责订阅并接收数据的实体,对应于Receiver。一个Subscriber通过订阅特定的Channel获取数据,并通过回调函数处理接收到的信息。
Node(节点):通信平面中的基本管理单元,一个Node可以同时包含多个Publisher和Subscriber。在一个进程中,可创建多个Node,Node通过Transport层提供的接口创建和管理这些角色,并维护其与外部节点的连接关系。
6.2 拓扑图的底层数据结构设计前文已阐明,有向图因其在表示方向性关系和支持动态调整方面的优势,被选为拓扑机制的核心模 ...
CyberRt源码剖析--05基于共享内存的通信实现
5.1 什么是共享内存共享内存(Shared Memory)是操作系统层面实现高效进程间通信(Inter-Process Communication, IPC)的关键机制,其核心设计理念在于突破传统进程间内存隔离的限制,使多个进程能够直接访问同一物理内存区域,从而显著提升数据传输效率并减少通信过程中的数据复制开销。
5.2 CyberRT共享内存通信模型
发送进程中的Transmitter在发送数据时会绑定一个确定的channel_id,同时根据此channel_id去创建一片共享内存,这片共享内存被定义成一个Segment。接收进程中的Receiver也会存在自己所关注的channel_id,在接收进程设计了一个SegmentMap:<channel_id, Segment>的数据结构,SegmentMap保存了channel_id和对应共享内存Segment之间的索引关系,Receiver在获取对应channel_id上的数据时会首先向SegmentMap中注册,后续获取数据通过去SegmentMap根据channel_id找到Segment从而拿到数据。Transm ...
CyberRt源码剖析--04基于FastRTPS的通信实现
4.1 FastRTPS通信流程
在基于FastRTPS实现跨进程通信时,发送端和接收端需遵循特定流程完成配置,以实现数据通信。其具体步骤如下所述,在发送端,首先要创建RtpsParticipant。接着,创建RtpsWriter的配置信息实例并完成填充,随后创建RtpsWriter和RtpsWriter History,最后将RtpsWriter进行注册。准备工作完成后,就可以进行数据装载与发送。在接收端,同样需要先创建RtpsParticipant,然后创建RtpsReader的配置信息实例并填充相关信息,创建RtpsReader并为其设置回调函数,再创建RtpsReader History,完成这些步骤后,就能在接收到数据时执行回调操作。当发送端和接收端都按照上述流程配置完成,双方即可开始通信。
4.2 基于FastRTPS的发送端的实现
在本通信架构中,RtpsTransmitter负责实现基于FastRTPS的发送端功能,具体设计思路如下:在FastRTPS通信模型中,一个RtpsParticipant可创建多个RtpsWriter。因此无需为每个RtpsTransmitt ...
CyberRT源码剖析--03通信架构
序列化模块:序列化模块负责将用户自定义的数据结构转换为可传输的二进制格式,并支持反向解析。本模块采用嵌入式序列化方案,用户仅需定义C++数据结构体并通过标准化宏调用即可完成序列化操作。该方案支持C++基本数据类型(如int、float)以及STL容器(如vector、map)
发布订阅系统:发布-订阅系统是本设计中分布式通信中间件的核心模块之一,负责实现节点间高效、解耦的通信。该系统采用基于消息驱动的架构,由发布者、订阅者和消息代理三个部分组成。发布者负责发布特定主题(Channel)的消息,订阅者则订阅感兴趣的主题,消息代理充当中枢,接收并转发发布者的消息至对应的订阅者。在分布式系统中,节点间的通信可能涉及不同的网络环境,如同一主机内的通信与跨主机的通信。针对这一问题,当节点位于同一主机时发布订阅框架会优先选择共享内存进行通信,这样可以避免网络协议栈的开销,从而实现更低延迟的通信;而当节点位于不同主机时,框架则采用基于FastRTPS网络通信方式。在多层次的网络架构中,通信方式会根据实际情况动态选择,确保在不同环境下都能够提供高效的通信服务。
服务发现机制:在点对点通信中,节点需 ...
CyberRT源码剖析--02如何学习CyberRT
2.1 cpp前置知识
cpp基础语法:https://www.bilibili.com/video/BV1et411b73Z/?spm_id_from=333.337.search-card.all.click&vd_source=1325a6af2d360c06e8e0c5e177802b1b
cpp进阶
数据结构:https://dsa.cs.tsinghua.edu.cn/~deng/ds/dsacpp/
cpp11 新特性
智能指针
移动语义:std::move
原子变量,CAS操作(无锁同步)
Lambda表达式 ,std::functon可调用对象
并发与多线程相关:std::thread, std::mutex, std::lock_guard等
SFINAE特性(模板进阶)”Substitution Failure Is Not An Error”
设计模式
工厂模式
单例模式
观察者模式
编译链接
Makefile
g++/gcc 编译
2.2 CyberRT源码文件夹第一步:从基础库入手,读懂源码并仿写
第二步: ...
CyberRt源码剖析--01CyberRT是什么
1.1 ROS1 VS ROS2
ROS2 引入了DDS
ROS1 需要Master节点来管理通信
发布订阅模型:
ROS2 软件架构
1.2 DDSData Distribution Service,也就是数据分发服务,2004年由对象管理组织OMG发布和维护,是一套专门为实时系统设计的数据分发/订阅标准:https://fast-dds.docs.eprosima.com/en/latest/fastdds/library_overview/library_overview.html
DDS软件架构:
从上往下分为三个层级:DDS层、RTPS层、Transport层
可以看见FastDDS现在的架构有四层Application、DDS层、RTPS层Transport层
DDS层是对RTPS层的抽象,可以看见DDS层里有很多角色,如:Publisher、Subscriber、DataWriter、DataReader、Topic、DomainParticipant等,反而搞得很复杂
而RTPS层相对而言比较清晰简单RTPSWriter用于发送数据,RTPSRe ...
Linux内核启动流程分析
Linux内核启动流程分析我在学习Linux驱动的时候总感觉蒙着一层雾,让我看不清Linux内核的核心,Linux内核有很多子系统,我觉得有必要先从Linux Kernel的启动去宏观的看一下各个子系统是哪个时刻被启动的,我主要以ARM64为例子来分析Linux 内核的启动流程。我们知道在Linux内核启动之前是uboot,uboot会做一些初始化工作,如初始化ddr,我使用的内核源码为迅为电子提供的RK3588的linux SDK,内核版本为5.10.198
1. 内核链接文件 内核编译后生成的目标文件是ELF格式的vmlinux,vmlinux文件是各个源代码按照vmlinux.lds设定的规则,链接后得到的Object文件,并不是一个可执行的文件,不能在ARM平台上运行;通常会对其压缩,生成zImage或bzImage;通常内核映像以压缩格式存储,并不是一个可执行的内核;因此内核阶段需要先对内核映像自解压,他们的文件头部打包有解压缩程序
Linux内核的链接文件目录在arch/arm64/kernel/vmlinux.lds.S,内核在编译时会根据vmlinux.lds ...
Linux内核中同步机制的底层实现
Linux内核同步机制剖析在Linux内核中提供了四种处理并发和竞争的方法,分别是原子操作、自旋锁、信号量、互斥量,事先说明下我使用的linux内核为版本为4.19.232
1. 原子变量在了解原子变量在linux内核中是如何实现之前,建议先了解以下SMP系统和UP系统的不同,然后学习以下cache一致性相关知识,这里给出一个参考链接
2.4 CPU 缓存一致性 | 小林coding (xiaolincoding.com)
原子操作又可以进一步细分为“整型原子操作”和“位原子操作”,这里首先对整型原子操作进行讲解。在 Linux 内核中使用 atomic_t 和 atomic64_t 结构体分别来完成 32 位系统和 64 位系统的整形数据原子操作,两个结构体定义在内核源码/include/linux/types.h文件中,具体定义如下:
对整型原子变量的操作有以下一些函数,定义在内核源码的/include/linux/atomic.h中,
函数
描述
ATOMIC_INIT(int i)
定义原子变量的时候对其初始化,赋值为 i
int atomic_read( ...
使用原始套接字剖析TCP
1. 网络分层
按照OSI分层的话从上到下分为7层:物理层、链路层、网络层、传输层、会话层、表示层、应用层
一般来说会话层、表示层、应用层 统一称为 应用层
每张网卡都有一个唯一确定的地址,被称为MAC地址,通过这个全球唯一的MAC地址,就能标识不同的网络设备,MAC地址是一个48bit的值
2. Ethernet 封包格式2.1 以太网封包格式
字段
字段长度(字节)
说明
前导码(preamble)
7
0和1交替变换的码流
帧开始符(SFD)
1
帧起始符
目的地址(DA)
6
目的设备的MAC物理地址
源地址(SA)
6
发送设备的MAC物理地址
长度/类型(Length/Type)
2
帧数据字段长度/帧协议类型
数据及填充(data and pad)
46~1500
帧数据字段
帧校验序列(FCS)
4
数据校验字段
以太网帧大小必须在64-1518字节(不包含前导码和定界符),即包括目的地址(6B)、源地址(6B)、类型(2B)、数据、FCS(4B)在内,其中数据段大小在46~1500字节 ...
CyberRt源码分析-对象池
1. FOR_EACH 宏实现代码目录:cyber/base/for_each.h
DEFINE_TYPE_TRAIT(HasLess, operator<) // NOLINTtemplate <class Value, class End>typename std::enable_if<HasLess<Value>::value && HasLess<End>::value, bool>::typeLessThan(const Value& val, const End& end) { return val < end;}template <class Value, class End>typename std::enable_if<!HasLess<Value>::value || !HasLess<End>::value, bool ...










![ARM64-Trust-Firmware[3]-BL1解析](/2026/01/24/ARM64-Trust-Firmware-3-BL1%E8%A7%A3%E6%9E%90/17692290470595.png)
![ARM64-Trust-Firmware[2]-启动ATF](/2026/01/24/ARM64-Trust-Firmware-2-%E5%90%AF%E5%8A%A8ATF/17692287555201.png)
![ARM64-Trust-Firmware[1]-ARM安全架构](/2026/01/24/ARM64-Trust-Firmware-1-ARM%E5%AE%89%E5%85%A8%E6%9E%B6%E6%9E%84/17692284856153.png)
![Xhyper剖析[6]--中断虚拟化](/2026/01/20/Xhyper%E5%89%96%E6%9E%90-6-%E4%B8%AD%E6%96%AD%E8%99%9A%E6%8B%9F%E5%8C%96/17689244713913.png)
![Xhyper剖析[5]--MMIO虚拟化](/2026/01/20/Xhyper%E5%89%96%E6%9E%90-5-MMIO%E8%99%9A%E6%8B%9F%E5%8C%96/17689243819381.png)