软件和硬件之间的数据交互接口

2023-05-16

已剪辑自: 链接

编者按

软件和硬件,既相互依存又需要某种程度上的相互独立。通过软件和硬件之间的接口把两者连接在一起。软硬件接口,有很多含义:比如指令集是CPU软件和硬件之间的接口;比如一些硬件模块(包括IO接口模块、GPU、各种加速引擎等)暴露出来的可读写寄存器,则为控制接口;再比如,CPU和GPU或其他硬件模块之间通过DMA进行数据交互的(软硬件间的)数据传输接口。软硬件接口,是个非常庞大的命题。本文是《软硬件融合》图书内容的节选,聚焦在软件和硬件之间的数据交互接口。

(标题)软件和硬件之间数据交互接口

我们在计算机的基础课程里一般都学过IO交互的四种模式:寄存器模式、中断模式、DMA模式和通道模式。随着计算机技术的发展,除了IO设备,还有很多独立的硬件组件通过各种类型总线跟CPU连接在一起。接口已经不仅仅是用于IO数据传输场景,也用于软件(运行于CPU的程序)和其他硬件之间的数据交互场景。注:本文用“软硬件接口”特指软件和硬件之间数据交互的接口。

1 软硬件接口定义

传统的非硬件缓存一致性总线,是需要软件驱动显式的控制设备来进行数据交互的。通过梳理软硬件接口的演进,逐步给出软硬件接口的定义。a. 软硬件接口演进图片(a) CPU轮询 (b) CPU中断 © DMA方式图片(d) 共享队列 (e) 用户态轮询 (f) 多队列图1 软硬件接口的演进软硬件接口是在IO接口基础上的扩展,如图1,我们结合IO交互的四种模式,重新梳理一下软硬件接口的演进:

  • 第一阶段,使用软件轮询硬件状态。如图1(a),最开始是通过软件轮询,这时候软件和硬件的交互非常简单。发送的时候,软件会定期的去查询硬件的状态,当发送缓冲为空的时候,就把数据写入到硬件的缓存寄存器;接收的时候,软件会定期的查询硬件的状态,当接收缓冲区有数据的时候,就把数据读取到软件。
  • 第二阶段,使用中断模式。如图1(b),随着CPU的性能快速提升,统计发现,轮询的失败次数很高,大量的CPU时间被浪费在硬件状态查询而不是数据传输,因此引入中断模式。只有当发送缓冲存在空闲区域可以让软件存放一定量待发送数据的时候,或者接收缓冲已经有一定量数据待软件接收的时候,硬件会发起中断,CPU收到中断后进入中断服务程序,在中断服务程序里处理数据的发送和接收。
  • 第三阶段,引入DMA。如图1©,前面的两种情况下,都需要CPU来完成数据的传输,依然会有大量的CPU消耗。因此引入了专用的数据搬运模块DMA来完成CPU和硬件之间的数据传输,某种程度上,DMA可以看做是用于代替CPU进行数据搬运的加速器。发送的时候,当数据在CPU内存准备好,CPU告诉DMA源地址和数据的大小,DMA收到这些信息后主动把数据从CPU内存搬到硬件内部。同样的,接收的时候,CPU开辟好一片内存空间并告知DMA目标地址和空间的长度,DMA负责把硬件内部的数据搬运到CPU内存。
  • 第四阶段,专门的共享队列。如图1(d),引入了DMA之后,如果只有一片空间用于软件和硬件之间的数据交换,则软件和硬件之间的数据交换则是同步的。例如在接收的时候,当DMA把数据搬运到CPU内存之后,CPU需要马上进行处理并释放内存,CPU处理的时候DMA则只能停止工作。后来引入了乒乓缓冲的机制,当一个内存缓冲区用于DMA传输数据的时候,另一个缓冲区的数据由CPU进行处理,实现DMA传输和CPU处理的并行。更进一步的,演变成更多缓冲区组成的循环缓冲队列。这样,CPU的数据处理和DMA的数据传输则完全异步的完成,并且CPU对数据的处理以及DMA对数据的搬运都可以批量操作完成后,再同步状态信息给对方。
  • 第五阶段,用户态的软件轮询共享队列驱动。如图1(e),进一步的,随着带宽和内存的增加,导致数据频繁的在用户态应用程序、内核的堆栈、驱动以及硬件之间交互,并且缓冲区也越来越大,这些都不可避免的增加系统消耗,并且带来更多的延迟;而且,数据交互频繁,导致的中断的开销也是非常庞大的。因此,通过用户态的PMD(Polling Mode Driver,轮询模式驱动)可以高效的在硬件和用户态的应用程序直接传递数据,不需要中断,完全绕开内核,以此来提升性能和降低延迟。
  • 第六阶段,支持多队列。如图1(f),随着硬件设计规模扩大,硬件资源越来越多,在单个设备里,可以通过多队列的支持,来提高并行性。驱动也需要加入对多队列的支持,这样我们甚至可以为每个应用程序配置专用的队列或队列组,通过多队列的并行性来提升性能和应用数据的安全性。

说明:本小节所讲的内容,主要是基于传统的非缓存一致性总线的数据交互演进。随着跨芯片的缓存数据一致性总线开始流行,通过硬件完成数据交互,在提升性能的同时,也简化了软件设计。
b. 软硬件接口的组成部分粗略的说,软硬件接口是由驱动(Driver)和设备(Device)组成,驱动和设备的交互也即软件和硬件的交互。更确切一些的说,软硬件接口包括交互的驱动软件、硬件设备的接口部分逻辑,也包括内存中的共享队列,还包括传输控制和数据信息的总线。图片图2软硬件接口硬件架构示意模型如图2,是软硬件接口硬件架构的示意模型。软硬件接口的组件详细介绍如下:

  • 驱动软件。驱动是提供一定的接口API,让上层的软件能够更加方便的与硬件交互。驱动负责硬件设备控制面的配置、运行控制以及设备数据面的数据传输控制等。驱动屏蔽硬件的接口细节,对上层软件提供标准的API函数接口。驱动屏蔽硬件细节,提供标准API给上层软件,在单机系统是非常有价值的。通过不同版本的驱动,既可以屏蔽硬件细节,又可以跟不同的操作系统平台兼容。在云计算场景,要求要更严格一些,云场景期望是完全标准的硬件接口。驱动是代表软件与硬件交互的接口,但依然是软件的一部分,在云计算虚拟机驱动也会迁移到新的环境,这就要求新的运行环境和原始环境一致。也就是说,在IO直通模式下,需要双方的硬件接口本身就是一致的。
  • 设备硬件接口子模块,包括DMA和内部缓冲。高速的设备一般都有专用的DMA,专门负责数据搬运。驱动会通知DMA共享队列状态信息,然后DMA会读取内存中的共享队列描述符,并根据描述符信息负责在CPU内存和内部缓冲之间搬运数据。
  • 共享队列。特定的跟硬件DMA格式兼容的共享队列数据结构,软件和硬件通过共享队列交互数据。每个共享队列包括队列的头和尾指针、组成队列的各个描述符项以及每个描述符项所指向的实际的数据块。共享队列位于软件侧的CPU内存里,由软件驱动负责管理。
  • 传输的总线:软硬件交互可以说是上层功能,需要底层接口总线的承载。例如,在片内通常是通过AXI-Lite总线来实现软件对硬件的寄存器读写控制,而数据总线则是通过AXI实现硬件DMA对软件的CPU内存的读写访问。芯片间的总线常见的主要是PCIe,通过PCIe的TLP包来承载上层的各种类型的读写访问。

2 生产者消费者模型

生产者消费者问题(Producer-Consumer Problem)是多进程同步问题的经典案例之一,描述了共享固定大小缓冲区的两个进程,即所谓的“生产者”和“消费者”,在实际运行时如何处理交互的问题。如图3所示,生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者不会在缓冲区中空时消耗数据。图片图3 经典生产者消费者模型解决问题的基本办法是:让生产者在缓冲区满时休眠,等到消费者消耗缓冲区中的数据,从而缓冲区有了空闲区域的时候,生产者才能被唤醒,开始继续往缓冲区添加数据;同样,也需要让消费者在缓冲区空时进入休眠,等到生产者往缓冲区添加数据之后,再唤醒消费者继续消耗数据。a. 进程间通信一个生产者进程,一个消费者进程,生产者进程通过共享缓冲传递数据给消费者进程。如果程序员不够小心,没有考虑多进程间相互影响的话,很可能写出下面这段会导致“死锁”的代码。

// 该算法使用了两个系统库函数:sleep 和 wakeup。// 调用 sleep的进程会被阻断,直到有另一个进程用wakeup唤醒之。// 代码中的itemCount用于记录缓冲区中的数据项数。int itemCount = 0;
procedure producer() {    while (true) {        item = produceItem();        if (itemCount == BUFFER_SIZE) {            sleep();        }        putItemIntoBuffer(item);        itemCount = itemCount + 1;        if (itemCount == 1) {            wakeup(consumer);        }    }}
procedure consumer() {    while (true) {        if (itemCount == 0) {            sleep();        }        item = removeItemFromBuffer();        itemCount = itemCount - 1;        if (itemCount == BUFFER_SIZE - 1) {            wakeup(producer);        }        consumeItem(item);    }}

上面代码中的问题在于它可能导致竞争条件,进而引发死锁。考虑下面的情形:

  • 消费者进程把最后一个itemCount的内容读出来(注意它现在是零),消费者进程返回到while的起始处,现在进入if块。
  • 就在调用sleep之前,OS调度,决定将CPU时间片让给生产者进程,于是消费者进程在执行sleep之前就被中断了,生产者进程开始执行。
  • 生产者进程生产出一项数据后将其放入缓冲区,然后在itemCount上加 1;由于缓冲区在上一步加1之前为空,生产者尝试唤醒消费者。
  • 遗憾的是,消费者并没有在休眠,唤醒指令不起作用。当消费者恢复执行的时候,执行 sleep,一觉不醒(出现这种情况的原因在于,消费者只能被生产者在itemCount为1的情况下唤醒)。
  • 生产者不停地循环执行,直到缓冲区满,随后进入休眠。

由于两个进程都进入了永远的休眠,死锁情况出现了。因此,该算法是不完善的。我们可以通过引入信号量(Semaphore)的方式来完善这个算法。信号量能够实现对某个特定资源的互斥访问。

// 该方法使用了两个信号灯,fillCount和emptyCount;// fillCount用于记录缓冲区中存在的数据项数量;// emptyCount用于记录缓冲区中空闲空间数量;
// 当有新数据项被放入缓冲区时,fillCount增加,emptyCount减少;// 当有新数据项被取出缓冲区时,fillCount减少,emptyCount增加;
// 如果在生产者尝试减少emptyCount的时候发现其值为零,那么生产者就进入休眠。// 等到有数据项被消耗,emptyCount增加的时候,生产者才被唤醒。// 消费者的行为类似。
semaphore fillCount = 0;                                         // 生产的项目semaphore emptyCount = BUFFER_SIZE;         // 剩余空间procedure producer() {    while (true) {        item = produceItem();        down(emptyCount);            putItemIntoBuffer(item);        up(fillCount);    }}
procedure consumer() {    while (true) {        down(fillCount);            item = removeItemFromBuffer();        up(emptyCount);        consumeItem(item);    }}

b.分布式消息队列服务
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削峰等问题。消息(Message)是指在应用之间传送的数据,消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,有消息系统来确保信息的可靠传递,消息发布者只管把消息发布到MQ中而不管谁来取,消息使用者只管从MQ中取消息而不管谁发布的,这样发布者和使用者都不用知道对方的存在。如图4,消息队列一般由三部分组成:

  • Producer:消息生产者,负责产生和发送消息到 Broker。
  • Broker:消息处理中心。负责消息存储、确认、重试等,一般其中会包含多个Queue。
  • Consumer:消息消费者,负责从 Broker 中获取消息,并进行相应处理。

图片图4 消息队列模型消息队列具有如下特性:

  • 异步性。将耗时的同步操作,通过发送消息的方式,进行了异步化处理。减少了同步等待的时间。
  • 松耦合。消息队列减少了服务之间的耦合性,不同的服务可以通过消息队列进行通信,而不用关心彼此的实现细节,只要定义好消息的格式就行。
  • 分布式。通过对消费者的横向扩展,降低了消息队列阻塞的风险,以及单个消费者产生单点故障的可能性(当然消息队列本身也可以做成分布式集群)。
  • 可靠性。消息队列一般会把接收到的消息存储到本地硬盘上(当消息被处理完之后,存储信息根据不同的消息队列实现,有可能将其删除),这样即使应用挂掉或者消息队列本身挂掉,消息也能够重新加载。

互联网场景使用较多的消息队列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ等。c. 驱动和设备通信NIC(Network Interface Adapter,网络接口卡)是典型的IO设备,网络数据包的传输有发送Tx和接收Rx两个方向。通过贡献的Tx Queue和Rx Queue来交互数据传输。我们以网络Tx的传输为例,介绍基于生产者消费者模型的驱动和设备数据交互。如图5,给出了网络包处理Tx发送的基本原理示意图(Rx接收跟Tx发送类似,控制流程一致,数据方向相反)。可以看到,在Tx的时候,驱动是生产者,设备是消费者,他们通过内存中共享的环形队列传输数据。一般在环形队列中的是用于描述数据的描述符,通过指针指向实际的数据块。当上层应用通过驱动把数据写到环形队列以后,驱动会把环形队列相关的状态信息告知设备端。设备端接收到信息后DMA开始工作,首先读取环形队列中的相应描述符,然后通过描述符信息搬运实际的数据块到硬件内部。搬运完成后硬件通过中断告知驱动,然后驱动会释放此块缓冲。图片图5 网络驱动和设备通信示意图

3 用户态轮询驱动:DPDK和SPDK

DPDK和SPDK是当前主流的开源高速接口框架,核心的技术是用户态的轮询驱动。DPDK/SPDK支持两个核心的设备类型:DPDK聚焦高性能网络处理,SPDK聚焦高性能存储处理。a. DPDK介绍

DPDK(Data Plane Development Kit,数据平面开发套件)是在用户态中运行的一组软件库和驱动程序,可加速在CPU架构上运行的数据包处理工作负载。DPDK由英特尔大约在2010年创建,现在作为Linux基金会下的一个开源项目提供,在拓展通用CPU的应用方面发挥了重要作用。

图片图片
(a) 基于Linux内核的包处理(b) 基于DPDK的包处理

图6 基于DPDK的包处理如图6(a),传统Linux网络驱动存在如下一些问题:

  • 中断开销大,大量数据传输会频繁触发中断,中断开销系统无法承受;
  • 数据包从内核缓冲区拷贝到用户缓冲区,带来系统调用和数据包复制的开销;
  • 对于很多网络功能来说,TCP/IP协议并非数据转发必需;
  • 操作系统调度带来的缓存替换也会对性能产生负面影响。

如图6(b),DPDK最核心的功能是提供了用户态的轮询模式驱动,为了加速网络IO,DPDK允许传入的网络数据包直通到用户空间而没有内存复制的开销,不需要用户空间和内核空间切换时的上下文处理。DPDK可在高吞吐量和低延迟敏感的场景加速特定的网络功能,如无线核心、无线访问、有线基础设施、路由器、负载均衡器、防火墙、视频流、VoIP等。DPDK所使用的优化技术主要有:

  • 用户态驱动,减少内核态用户态切换开销,减少缓冲区拷贝;
  • 轮询模式驱动(PMD, Polling Mode Driver),不需要中断,没有中断开销,并且对队列及数据及时处理,降低延迟;
  • 固定处理器核,减少线程切换的开销,减少缓存失效,同时要考虑NUMA特性,确保内存和处理器核在同一个NUMA域中;
  • 大页机制,减少TLB未命中几率;
  • 非锁定的同步,避免等待;
  • 内存对齐和缓存对齐,有利于内存到缓存的加载效率;
  • DDIO机制,从IO设备把数据直接送到L3缓存,而不是送到内存。

b. SPDK介绍在数据中心中,固态存储介质正在逐渐替换机械HDD,NVMe在性能、功耗和机架密度方面具有明显的优势。因为固态存储吞吐量提升,存储软件需要花费更多的CPU资源;因为固态存储延迟性能的大幅提升,存储软件的处理延迟则开始凸显。总结来说,随着存储介质性能的进一步提升,存储软件栈的性能和效率越来越成为存储系统的瓶颈。如图7,SPDK(Storage Performance Development Kit,存储性能开发套件)利用了很多DPDK的组件,在DPDK的基础上,加入了存储的相关组件。SPDK的核心技术依然是用户态的PMD。SPDK已经证明,使用一些处理器内核和一些NVMe驱动器进行存储,而无需额外的卸载硬件,可以轻松实现每秒数百万个IO。图片图7 SPDK基于DPDK和一些新的组件SPDK由许多组件组成,这些组件相互连接并共享用户态和轮询模式操作的通用功能。每个组件都是为了克服特定场景的性能瓶颈而开发的,并且,每个组件也可以集成到非SPDK架构中,从而使客户可以利用SPDK的技术来加速自己的软件应用。从底层到上层,SPDK的组件包括:

  • 用户态PMD驱动:基于PCIe的NVMe驱动、NVMeoF驱动,以及英特尔QuickData驱动(QuickData为Intel志强处理器平台的IO加速引擎)。
  • 后端块设备:Ceph RADOS块设备(Ceph为开源的分布式存储系统,RADOS为Ceph的分布式集群封装),Blobstore块设备(VM或数据库交互的虚拟设备),Linux AIO(异步IO)。
  • 存储服务:块设备抽象层(bdev),Blobstore。
  • 存储协议:iSCSI Target端,NVMeoF Target端,vhost-scsi Target端,vhost-blk Target端。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

软件和硬件之间的数据交互接口 的相关文章

  • QT中组件/控件类的关系

    一 常见类继承关系 二 窗口类继承关系 Qt中窗口类的继承关系 说明 xff1a QWidge继承自QObject和QPaintDevice类 QObject是支持QT对象模型的基类 Qt Object Model QPaintDevice
  • Qt QListWidget列表框用法详解

    文章目录 QListWidget列表框的创建QListWidgetItem列表项 QListWidget列表框的使用QListWidget列表框的信号和槽实例演示QListWidget列表框的用法 已剪辑自 http c biancheng
  • Qt QTreeWidget树形控件用法详解

    文章目录 QTreeWidget控件的创建QTreeWidget QTreeView的关系和区别QTreeWidgetItem类 QTreeWidget的实际应用1 添加结点2 给结点添加图标3 给结点添加复选框4 多列树形控件5 QTre
  • Qt QMessageBox用法详解

    文章目录 通用的QMessageBox消息框1 information消息对话框2 critical消息对话框3 question消息对话框4 warning消息对话框5 about和aboutQt对话框 自定义QMessageBox对话框
  • Qt pro文件详解

    文章目录 pro文件中的配置信息QT配置项 已剪辑自 http c biancheng net view vip 9661 html 默认情况下 xff0c 每个 Qt 项目都包含一个后缀名为 pro 名称和项目名相同的文件 xff0c 我
  • mac上用qt创建应用 运行后为什么不显示窗体

    mac上安装了qt xff0c 新建mainwindow窗体应用 xff0c 运行后在程序坞出现了一个图标 xff0c 但是无法显示窗体 解决方法 xff1a 软件配置的SDK远大于电脑配置的SDK xff0c 下个低的版就好了
  • Qt Designer基础控件介绍

    已剪辑自 https blog csdn net qq 37631516 article details 104786627 1 布局类 xff08 4种 xff09 2 固定弹簧类 2种 xff08 不随布局变化 xff09 3 按钮类
  • python开发环境管理:pip和virtualenv

    python开发环境管理 xff1a pip和virtualenv 不同的python软件需要不同的开发环境 xff0c 互相之间甚至可能有冲突 xff0c 怎么处理 xff1f 使用pip virtualenv和virtualenvwra
  • Qt QFile文件操作详解

    文章目录 QFile文件操作QFile 43 QTextStreamQFile 43 QDataStream 文件操作是非常重要的 xff0c 是数据持久化的方法 通过文件操作 xff0c 我们可以把在软件中设置的数据保存起来 已剪辑自 h
  • Qt布局管理详解(5种布局控件)

    文章目录 QVBoxLayout垂直布局QHBoxLayout水平布局QGridLayout网格布局QFormLayout表单布局QStackedLayout分组布局 已剪辑自 http c biancheng net view vip 9
  • 基于优先级的时间片轮转调度算法(C语言实现)

    已剪辑自 http www demodashi com demo 15341 html 基于优先级的时间片轮转调度算法 1 PCB结构 xff08 Block xff09 由此定义如下结构体 xff1a span class token k
  • Qt自定义信号和槽函数

    文章目录 自定义信号函数自定义槽函数自定义信号和槽的完整实例 已剪辑自 http c biancheng net view vip 9662 html 实际开发中 xff0c 如果仅使用 Qt 提供的信号函数和槽函数 xff0c 会经常遇到
  • QT中信号和槽之间的参数传递和参数匹配

    已剪辑自 https blog csdn net lyc daniel article details 12047819 信号槽如何传递参数 xff08 或带参数的信号槽 xff09 利用Qt进行程序开发时 xff0c 有时需要信号槽来完成
  • QT使用信号与槽时编译错误“no matching function for call to connect“

    转转于 xff1a http t csdn cn K3aYh 初学QT xff0c 在尝试用connect手动关联一个按钮和QlineEdit的时候编译报错 xff0c 如下 xff1a 然后贴上主要代码块 xff1a span class
  • QT-QTableWidget中的cell和item的区别

    文章目录 QTableWidget中单击一个单元格响应不同的函数 xff1a cell和item的区别 xff1a 单击单元格响应自定义函数我的错误思路 xff1a 已剪辑自 https blog csdn net CCLasdfg art
  • QT开发网络调试助手项目总结

    之前整理了一些使用QT开发串口调试助手的项目 博客地址 xff1a 上位机总结 这次继续整理一些使用QT开发网络调试助手的项目 Qt开源作品41 网络调试助手增强版V2022 我的QT学习之路 xff0c 编写UDP 43 tcp网络调试助
  • QT开源项目总结-总有一款适合你

    Qt Open Source Project 开源项目推荐 xff1a 本人收集的有关Qt的GitHub Gitee开源项目 精品收藏 我的Qt作品 Github上的一些高分Qt开源项目 Qt编写项目作品大全 Qt 开源作品
  • Qt 打印调试信息-怎样获取QTableWidget的行数和列数-读取QTableWidget表格中的数据

    文章目录 Qt 打印调试信息怎样获取QTableWidget的行数和列数Qt怎么把QTableWidget表格中的数据读取出来 Qt 打印调试信息 打印当前目录代码如下 xff0c 别忘了头文件 include include lt QtD
  • VR游戏交互开发的一些体验

    VR游戏交互开发的一些体验 本文主要写Unity开发手游过程中VR交互输入控制的一些浅薄的经验交互方面 xff0c 头控和视线按钮依然较为主流 xff0c 可以获得传感器数据来获得输入除了实体按钮输入之外还可以探索其他交互方式 xff0c

随机推荐

  • 一篇文章快速搞懂Qt文件读写操作

    已剪辑自 https www cnblogs com jfzhu p 13546886 html 导读 xff1a Qt当中使用QFile类对文件进行读写操作 xff0c 对文本文件也可以与QTextStream一起使用 xff0c 这样读
  • 完整的PRD文档包含哪些内容?

    完整的PRD文档包含哪些内容 xff1f 千万 xff0c 千万 xff0c 千万别再套模板写需求文档了 xff0c 要想写好需求文档重要的不是包含哪些内容 xff0c 而是为什么包含这些内容 xff01 话不多说 xff0c 直接上干货
  • 分享一个开源的QT的串口示波器

    已剪辑自 https mp weixin qq com s XHELtvZ Wk2hNzsWD52D1w 直接来源 果果小师弟 逛github时看到这个QT的串口示波器 xff0c 完全开源 xff0c 支持串口 TCP 波形显示 通信协议
  • C 语言函数返回值,竟也有潜规则~

    已剪辑自 https mp weixin qq com s WNHx1zhna8iGaYIj6 3 fg 基本上 xff0c 没有人会将大段的C语言代码全部塞入 main 函数 更好的做法是按照复用率高 耦合性低的原则 xff0c 尽可能的
  • 模型在物理学发展中的作用

    已剪辑自 https mp weixin qq com s txS CQAIXPtY6kb2tHukUQ 模型是物理学认识由唯象理论过渡到动力学理论重要的环节 开普勒的行星运行模型 气体的分子运动模型 爱因斯坦的光子模型 卢瑟福 玻尔的原子
  • 第一性原理谈安全性和可靠性

    已剪辑自 https mp weixin qq com s jttd dhv9PmNu25Z zyd5Q 最近从各个行业对系统的安全性的关注度越来越高 xff0c 10月28日 xff0c 工信部公开征求的 道路机动车辆生产准入许可管理条例
  • 在浏览器地址栏输入一个URL后回车,背后会进行哪些技术步骤?

    转载于 xff1a 小林的图解网络系列 关键是要有个上帝视角 xff0c 先要有个网络模型的概念 xff0c 也就是TCP IP 四层网络模型 xff0c 然后针对每一层的协议进行深入 学习计算机网络一定要抓主一个点 xff0c 就是 输入
  • 在MacOS上实现两个网络调试助手的UDP通信测试

    文章目录 一 背景二 网络调试助手软件三 UDP通信过程 一 背景 因为有一个项目要中会使用本机中两个应用程序之间的UDP通信 因此本文记录一下怎么在MacOS上实现两个网络调试助手的UDP通信测试 二 网络调试助手软件 我使用的网络调试助
  • QT和网络调试助手之间的UDP通信

    文章目录 一 背景二 实现过程简述UDP协议工作原理及编程模型UDP 接收端UDP 发送端运行UDP接收端和发送端运行UDP发送端发送数据给网络调试助手 一 背景 之前一篇博客实现了两个网络调试助手之间的UDP通信 文章链接 xff1a 在
  • 一个开源且完全自主开发的国产网络协议栈

    已剪辑自 https mp weixin qq com s 1LE7mGc9mRuajRgNsyirQ onps是一个开源且完全自主开发的国产网络协议栈 xff0c 适用于资源受限的单片机系统 xff0c 提供完整地ethernet ppp
  • PyQt的使用

    使用conda切换到python3 如果不会使用conda xff0c 那么安装anaconda后打开navigator xff0c 再environments中选择创建好的python3环境 xff0c 右键打开terminal即可 安装
  • 前后台系统及嵌入式前后台模式实时性优化

    一 前后台系统 前后台系统 xff0c 即计算机前后台系统 xff0c 早期的嵌入式系统中没有操作系统的概念 xff0c 程序员编写嵌入式程序通常直接面对裸机及裸设备 xff0c 在这种情况下 xff0c 通常把嵌入式程序分成两部分 xff
  • 又一嵌入式开源仿真器

    已剪辑自 https mp weixin qq com s X0I3EotJ8TRqLK8vb8iQvA 同QEMU类似 xff0c Renode也是嵌入式相关的一个模拟器 Renode 针对物联网应用 xff0c QEMU 针对 PC 模
  • SkyEye天目全数字实时仿真软件功能介绍

    文章目录 SkyEye的概念和应用 SkyEye的优势 SkyEye可与第三方语言或者模型集成 基于可视化图形的硬件建模 容器化的仿真平台 FPGA协同仿真 SkyEye的应用案例 SkyEye大规模航电系统仿真案例 SkyEye 飞行器显
  • SkyEye——如何实现1553B总线仿真?

    已剪辑自 https www digiproto com news 204 html 1553B最初是美国军方专为飞机上设备制定的一种信息传输总线标准 xff0c 具有双向传输的特性 xff0c 实时性和可靠性高 xff0c 现已广泛应用于
  • 细数SkyEye异构仿真的5大特色

    已剪辑自 https www digiproto com news 65 html 航天飞行器使用仿真器的重要性 航天飞行器如卫星 载人飞船等需要在空中运行很长的时间 xff0c 如果出现问题回收再调试可能要历时几个月 xff0c 而且不得
  • SkyEye:航空发动机控制系统仿真

    已剪辑自 https www digiproto com news 212 html 航空发动机 xff08 aero engine xff09 是一种高度复杂和精密的热力机械 xff0c 作为飞机的心脏 xff0c 不仅是飞机飞行的动力
  • 基于功能安全的车载计算平台开发:软件层面

    已剪辑自 https mp weixin qq com s SIBvH8u vCk6W28KrPBmA 车载智能计算平台作为智能汽车的安全关键系统 xff0c 软件层面的安全性至关重要 由于车载智能计算平台功能丰富 xff0c 应用场景复杂
  • 软件和硬件中的调用

    文章目录 1 概述 2 1 程序进程内的调用 xff1a 函数调用 2 2 程序进程间的调用 xff1a IPC 2 3 远程程序调用 xff1a RPC 2 4 远程调用REST 3 硬件 调用 3 1 综述 总线模型 3 2 片内的总线
  • 软件和硬件之间的数据交互接口

    已剪辑自 链接 编者按 软件和硬件 xff0c 既相互依存又需要某种程度上的相互独立 通过软件和硬件之间的接口把两者连接在一起 软硬件接口 xff0c 有很多含义 xff1a 比如指令集是CPU软件和硬件之间的接口 xff1b 比如一些硬件