管理端口_Linux系统对IO端口和IO内存的管理

一、I/O端口

端口(port)是接口电路中能被CPU直接访问的寄存器的地址。几乎每一种外设都是通过读写设备上的寄存器来进行的。CPU通过这些地址即端口向接口电路中的寄存器发送命令,读取状态和传送数据。外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。

二、IO内存

例如,在PC上可以插上一块图形卡,有2MB的存储空间,甚至可能还带有ROM,其中装有可执行代码。

8ae80d51a5107c7d73cb2e463acee0cb.png

三、IO端口和IO内存的区分及联系

这两者如何区分就涉及到硬件知识,X86体系中,具有两个地址空间:IO空间和内存空间,而RISC指令系统的CPU(如ARM、PowerPC等)通常只实现一个物理地址空间,即内存空间。内存空间:内存地址寻址范围,32位操作系统内存空间为2的32次幂,即4G。IO空间:X86特有的一个空间,与内存空间彼此独立的地址空间,32位X86有64K的IO空间。

IO端口:当寄存器或内存位于IO空间时,称为IO端口。一般寄存器也俗称I/O端口,或者说I/O ports,这个I/O端口可以被映射在Memory Space,也可以被映射在I/O Space。

IO内存:当寄存器或内存位于内存空间时,称为IO内存。

四、外设IO端口物理地址的编址方式

CPU对外设IO端口物理地址的编址方式有两种:一种是I/O映射方式(I/O-mapped),另一种是内存映射方式(Memory-mapped)。而具体采用哪一种则取决于CPU的体系结构。

1、统一编址

  RISC指令系统的CPU(如,PowerPC、m68k、ARM等)通常只实现一个物理地址空间(RAM)。在这种情况下,外设I/O端口的物理地址就被映射到CPU的单一物理地址空间中,而成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。

统一编址也称为“I/O内存”方式,外设寄存器位于“内存空间”(很多外设有自己的内存、缓冲区,外设的寄存器和内存统称“I/O空间”)。

2、独立编址

而另外一些体系结构的CPU(典型地如X86)则为外设专门实现了一个单独地地址空间,称为“I/O地址空间”或者“I/O端口空间”。这是一个与CPU地RAM物理地址空间不同的地址空间,所有外设的I/O端口均在这一空间中进行编址。CPU通过设立专门的I/O指令(如X86的IN和OUT指令)来访问这一空间中的地址单元(也即I/O端口)。与RAM物理地址空间相比,I/O地址空间通常都比较小,如x86 CPU的I/O空间就只有64KB(0-0xffff)。这是“I/O映射方式”的一个主要缺点。

独立编址也称为“I/O端口”方式,外设寄存器位于“I/O(地址)空间”。

3、优缺点

独立编址主要优点是:
1)、I/O端口地址不占用存储器空间;使用专门的I/O指令对端口进行操作,I/O指令短,执行速度快。
2)、并且由于专门I/O指令与存储器访问指令有明显的区别,使程序中I/O操作和存储器操作层次清晰,程序的可读性强。
3)、同时,由于使用专门的I/O指令访问端口,并且I/O端口地址和存储器地址是分开的,故I/O端口地址和存储器地址可以重叠,而不会相互混淆。
4)、译码电路比较简单(因为I/0端口的地址空间一般较小,所用地址线也就较少)。
其缺点是:只能用专门的I/0指令,访问端口的方法不如访问存储器的方法多。

统一编址优点:
1)、由于对I/O设备的访问是使用访问存储器的指令,所以指令类型多,功能齐全,这不仅使访问I/O端口可实现输入/输出操作,而且还可对端口内容进行算术逻辑运算,移位等等;
2)、另外,能给端口有较大的编址空间,这对大型控制系统和数据通信系统是很有意义的。
这种方式的缺点是端口占用了存储器的地址空间,使存储器容量减小,另外指令长度比专门I/O指令要长,因而执行速度较慢。
究竟采用哪一种取决于系统的总体设计。在一个系统中也可以同时使用两种方式,前提是首先要支持I/O独立编址。Intel的x86微处理器都支持I/O 独立编址,因为它们的指令系统中都有I/O指令,并设置了可以区分I/O访问和存储器访问的控制信号引脚。而一些微处理器或单片机,为了减少引脚,从而减 少芯片占用面积,不支持I/O独立编址,只能采用存储器统一编址。

需要C/C++ Linux服务器架构师学习资料加qun获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

0f1cfbbb33f0eeb812d4cafd5c3d94da.png

五、Linux下访问IO端口

对于某一既定的系统,它要么是独立编址、要么是统一编址,具体采用哪一种则取决于CPU的体系结构。 如,PowerPC、m68k等采用统一编址,而X86等则采用独立编址,存在IO空间的概念。目前,大多数嵌入式微控制器如ARM、PowerPC等并不提供I/O空间,仅有内存空间,可直接用地址、指针访问。但对于Linux内核而言,它可能用于不同的CPU,所以它必须都要考虑这两种方式,于是它采用一种新的方法,将基于I/O映射方式的或内存映射方式的I/O端口通称为“I/O区域”(I/O region),不论你采用哪种方式,都要先申请IO区域:request_resource(),结束时释放它:release_resource()。

IO region是一种IO资源,因此它可以用resource结构类型来描述。

访问IO端口有2种途径:I/O映射方式(I/O-mapped)、内存映射方式(Memory-mapped)。前一种途径不映射到内存空间,直接使用 intb()/outb()之类的函数来读写IO端口;后一种MMIO是先把IO端口映射到IO内存(“内存空间”),再使用访问IO内存的函数来访问 IO端口。

1、I/O映射方式

直接使用IO端口操作函数:在设备打开或驱动模块被加载时申请IO端口区域,之后使用inb(),outb()等进行端口访问,最后在设备关闭或驱动被卸载时释放IO端口范围。

in、out、ins和outs汇编语言指令都可以访问I/O端口。内核中包含了以下辅助函数来简化这种访问:

inb( )、inw( )、inl( )
分别从I/O端口读取1、2或4个连续字节。后缀“b”、“w”、“l”分别代表一个字节(8位)、一个字(16位)以及一个长整型(32位)。

inb_p( )、inw_p( )、inl_p( )
分别从I/O端口读取1、2或4个连续字节,然后执行一条“哑元(dummy,即空指令)”指令使CPU暂停。

outb( )、outw( )、outl( )
分别向一个I/O端口写入1、2或4个连续字节。

outb_p( )、outw_p( )、outl_p( )
分别向一个I/O端口写入1、2或4个连续字节,然后执行一条“哑元”指令使CPU暂停。

insb( )、insw( )、insl( )
分别从I/O端口读入以1、2或4个字节为一组的连续字节序列。字节序列的长度由该函数的参数给出。

outsb( )、outsw( )、outsl( )
分别向I/O端口写入以1、2或4个字节为一组的连续字节序列。

流程如下:

1a7078dbaf9084a96ff7ba6b18ee1f4d.png

虽然访问I/O端口非常简单,但是检测哪些I/O端口已经分配给I/O设备可能就不这么简单了,对基于ISA总线的系统来说更是如此。通常,I/O设备驱动程序为了探测硬件设备,需要盲目地向某一I/O端口写入数据;但是,如果其他硬件设备已经使用这个端口,那么系统就会崩溃。为了防止这种情况的发生,内核必须使用“资源”来记录分配给每个硬件设备的I/O端口。资源表示某个实体的一部分,这部分被互斥地分配给设备驱动程序。在这里,资源表示I/O端口地址的一个范围。每个资源对应的信息存放在resource数据结构中:

struct resource {  
         resource_size_t start;// 资源范围的开始  
         resource_size_t end;// 资源范围的结束  
         const char *name; //资源拥有者的名字  
         unsigned long flags;// 各种标志  
         struct resource *parent, *sibling, *child;// 指向资源树中父亲,兄弟和孩子的指针  
};  

所有的同种资源都插入到一个树型数据结构(父亲、兄弟和孩子)中;例如,表示I/O端口地址范围的所有资源都包括在一个根节点为ioport_resource的树中。节点的孩子被收集在一个链表中,其第一个元素由child指向。sibling字段指向链表中的下一个节点。

为什么使用树?例如,考虑一下IDE硬盘接口所使用的I/O端口地址-比如说从0xf000 到 0xf00f。那么,start字段为0xf000 且end 字段为0xf00f的这样一个资源包含在树中,控制器的常规名字存放在name字段中。但是,IDE设备驱动程序需要记住另外的信息,也就是IDE链主盘使用0xf000 到0xf007的子范围,从盘使用0xf008 到0xf00f的子范围。为了做到这点,设备驱动程序把两个子范围对应的孩子插入到从0xf000 到0xf00f的整个范围对应的资源下。一般来说,树中的每个节点肯定相当于父节点对应范围的一个子范围。I/O端口资源树(ioport_resource)的根节点跨越了整个I/O地址空间(从端口0到65535)。

任何设备驱动程序都可以使用下面三个函数,传递给它们的参数为资源树的根节点和要插入的新资源数据结构的地址:

request_resource( ) //把一个给定范围分配给一个I/O设备。

allocate_resource( ) //在资源树中寻找一个给定大小和排列方式的可用范围;若存在,将这个范围分配给一个I/O设备(主要由PCI设备驱动程序使用,可以使用任意的端口号和主板上的内存地址对其进行配置)。

release_resource( ) //释放以前分配给I/O设备的给定范围。

内核也为以上函数定义了一些应用于I/O端口的快捷函数:request_region( )分配I/O端口的给定范围,release_region( )释放以前分配给I/O端口的范围。当前分配给I/O设备的所有I/O地址的树都可以从/proc/ioports文件中获得。

2、内存映射方式

将IO端口映射为内存进行访问,在设备打开或驱动模块被加载时,申请IO端口区域并使用ioport_map()映射到内存,之后使用IO内存的函数进行端口访问,最后,在设备关闭或驱动模块被卸载时释放IO端口并释放映射。

映射函数的原型为:
void *ioport_map(unsigned long port, unsigned int count);
通过这个函数,可以把port开始的count个连续的I/O端口重映射为一段“内存空间”。然后就可以在其返回的地址上像访问I/O内存一样访问这些I/O端口。但请注意,在进行映射前,还必须通过request_region( )分配I/O端口。

当不再需要这种映射时,需要调用下面的函数来撤消:
void ioport_unmap(void *addr);

在设备的物理地址被映射到虚拟地址之后,尽管可以直接通过指针访问这些地址,但是宜使用Linux内核的如下一组函数来完成访问I/O内存:·读I/O内存
unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);
与上述函数对应的较早版本的函数为(这些函数在Linux 2.6中仍然被支持):
unsigned readb(address);
unsigned readw(address);
unsigned readl(address);
·写I/O内存
void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);
与上述函数对应的较早版本的函数为(这些函数在Linux 2.6中仍然被支持):
void writeb(unsigned value, address);
void writew(unsigned value, address);
void writel(unsigned value, address);

流程如下:

d02204ed992fc62edfabd3ea1f860956.png

六、Linux下访问IO内存

IO内存的访问方法是:首先调用request_mem_region()申请资源,接着将寄存器地址通过ioremap()映射到内核空间的虚拟地址,之后就可以Linux设备访问编程接口访问这些寄存器了,访问完成后,使用ioremap()对申请的虚拟地址进行释放,并释放release_mem_region()申请的IO内存资源。

struct resource *requset_mem_region(unsigned long start, unsigned long len,char *name);
这个函数从内核申请len个内存地址(在3G~4G之间的虚地址),而这里的start为I/O物理地址,name为设备的名称。注意,。如果分配成功,则返回非NULL,否则,返回NULL。
另外,可以通过/proc/iomem查看系统给各种设备的内存范围。

要释放所申请的I/O内存,应当使用release_mem_region()函数:
void release_mem_region(unsigned long start, unsigned long len)

申请一组I/O内存后, 调用ioremap()函数:
void * ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
其中三个参数的含义为:
phys_addr:与requset_mem_region函数中参数start相同的I/O物理地址;
size:要映射的空间的大小;
flags:要映射的IO空间的和权限有关的标志;

功能:将一个I/O地址空间映射到内核的虚拟地址空间上(通过release_mem_region()申请到的)

流程如下:

bbf15739eeca5bf4b7add6e06852b858.png

六、ioremap和ioport_map

下面具体看一下ioport_map和ioport_umap的源码:

void __iomem *ioport_map(unsigned long port, unsigned int nr)  
{  
    if (port > PIO_MASK)  
        return NULL;  
    return (void __iomem *) (unsigned long) (port + PIO_OFFSET);  
}  
 
void ioport_unmap(void __iomem *addr)  
{  
    /* Nothing to do */  
}  

ioport_map仅仅是将port加上PIO_OFFSET(64k),而ioport_unmap则什么都不做。这样portio的64k空间就被映射到虚拟地址的64k~128k之间,而ioremap返回的虚拟地址则肯定在3G之上。ioport_map函数的目的是试图提供与ioremap一致的虚拟地址空间。分析ioport_map()的源代码可发现,所谓的映射到内存空间行为实际上是给开发人员制造的一个“假象”,并没有映射到内核虚拟地址,仅仅是为了让工程师可使用统一的I/O内存访问接口ioread8/iowrite8(......)访问I/O端口。
最后来看一下ioread8的源码,其实现也就是对虚拟地址进行了判断,以区分IO端口和IO内存,然后分别使用inb/outb和readb/writeb来读写。

unsigned int fastcall ioread8(void __iomem *addr)  
{  
    IO_COND(addr, return inb(port), return readb(addr));  
}  
 
#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET)  
#define IO_COND(addr, is_pio, is_mmio) do {   
    unsigned long port = (unsigned long __force)addr;   
        if (port < PIO_RESERVED) {   
            VERIFY_PIO(port);   
            port &= PIO_MASK;   
            is_pio;   
        } else {   
            is_mmio;   
        }   
} while (0)  
 
展开:  
unsigned int fastcall ioread8(void __iomem *addr)  
{  
    unsigned long port = (unsigned long __force)addr;  
    if( port < 0x40000UL ) {  
        BUG_ON( (port & ~PIO_MASK) != PIO_OFFSET );  
        port &= PIO_MASK;  
        return inb(port);  
    }else{  
        return readb(addr);  
    }  
}  

七、总结

外设IO寄存器地址独立编址的CPU,这时应该称外设IO寄存器为IO端口,访问IO寄存器可通过ioport_map将其映射到虚拟地址空间,但实际上这是给开发人员制造的一个“假象”,并没有映射到内核虚拟地址,仅仅是为了可以使用和IO内存一样的接口访问IO寄存器;也可以直接使用in/out指令访问IO寄存器。

例如:Intel x86平台普通使用了名为内存映射(MMIO)的技术,该技术是PCI规范的一部分,IO设备端口被映射到内存空间,映射后,CPU访问IO端口就如同访 问内存一样。

外设IO寄存器地址统一编址的CPU,这时应该称外设IO寄存器为IO内存,访问IO寄存器可通过ioremap将其映射到虚拟地址空间,然后再使用read/write接口访问。

开发Linux 服务程序与windows service程序的主要区别 <br /><br />我曾经经历了unix开发向windows 开发的转型现在又开始经历windows 开发向linux开发的转型<br />经过最近的知识回顾和实际工作,我总结出几点,给大家的一点提示,对于windows开发人员转移到linux平台上或许有点作用:经验总体总结:不要照搬照抄windows上的开发经验,应该深入学习linux的技术特点,并根据linux的特点去进行开发,有以下几点重点的经验,由于我们开发的主要程序在windows上都已windows service形式存在,因此主要对比一下 阅读详情

相关推荐

MinIO Docker 部署:9000/9090端口映射与MINIO_BROWSER_REDIRECT_URL配置详解

本文详细解析了MinIO在Docker环境中的部署实践,重点讲解9000/9090端口映射配置与MINIO_BROWSER_REDIRECT_URL环境变量的关键作用。通过实战示例展示如何解决反向代理场景下的重定向问题,并提供Docker Compose完整配置方案,帮助开发者快速搭建高性能对象存储服务。

458

Linux下的IO port, IO mem, IO space, Mem space及访问方式

经常看到这些个名词,大致弄清了他们的区别和联系,以x86架构为例,简要说明下。哪里不对,还请指正。 关键词:内存空间、I/O空间,I/Oport,I/O mem 1 内存空间和I/O空间 所有的设备中的每一个可访问单元,要想被CPU访问,都要有一个独立的可识别的地址,不然就混乱了。CPU所能访问的全部地址范围,被化分到内存空间和IO空间。 两个空间彼此独立,各有自己的访问方式,硬件...

Dalek的博客 4183

端口复用原理:SO_REUSEADDR与SO_REUSEPORT在Java、Nginx与K8s中的实战解析

在网络编程中,端口是网络通信的端点标识,遵循特定的绑定规则。默认情况下,操作系统遵循‘端口独占’原则,即一个四元组(协议+IP+端口)同一时刻只能被一个套接字绑定,这是经典的‘Address already in use’错误的根源。其原理在于内核通过套接字描述符管理连接,确保数据包准确投递。这一机制的技术价值在于保障了网络通信的确定性和安全性。然而,在高并发服务架构和云原生场景下,严格的独占规则会限制性能与可用性。为此,操作系统提供了SO_REUSEADDR和SO_REUSEPORT两个关键套接字选项来打

weixin_33824363的博客 400

嵌入式Linux系统是如何管理IO端口以及IO内存的呢?老司机给你讲讲

“一、I/O端口端口(port)是接口电路中能被CPU直接访问的寄存器的地址。几乎每一种外设都是通过读写设备上的寄存器来进行的。CPU通过这些地址即端口向接口电路中的寄存器发送命令,读取...

Peter的专栏 678

Unity Mirror游戏服务器Linux部署:从构建到运维完整指南

网络同步是多人联机游戏的核心技术,它通过客户端-服务器模型实现游戏状态的权威同步。其原理在于服务器作为游戏逻辑的权威源,处理所有关键计算和状态验证,客户端则负责发送输入指令并接收状态更新,通过预测和插值技术呈现流畅画面。这项技术的价值在于为玩家提供公平、一致的多人游戏体验,是构建竞技游戏、MMO、合作闯关等应用场景的基础。在Unity引擎生态中,Mirror Networking组件因其开源特性和高性能表现,成为实现中小型多人游戏网络同步的热门解决方案。本文将聚焦于将基于Mirror开发的游戏项目部署到Li

weixin_34315485的博客 375

自动化系统管理任务 Automating System Administration Tasks using Python

随着云计算、容器技术和DevOps理念的流行,越来越多的IT企业开始关注自动化系统管理工作。通过将繁琐重复性的手动操作自动化,能提高工作效率,降低运维成本。提升运维效率,缩短故障排查时间;节省人力资源,减少维护成本;提升组织整体技术能力水平;改善组织结构,合理分配职责,促进协作和沟通。自动化系统管理是一个复杂的系统工程,涉及到多个环节,包括需求分析、设计、编码、测试、部署、监控、迭代更新、运维支持等多个阶段。通过Python语言进行编程可以很方便地实现自动化系统管理任务。

AI天才研究院 1012

嵌入式开发学习--IO进程--标准IO、文件IO(含代码)

嵌入式学习用到的IO,标准IO与文件IO

qq_52407428的博客 1329

拯救我的老平板三星note8.0 table(GT-N5110)升级到lineage os-14.1(android7.1)全记录

买了多年的三星平板note8.0已经闲置了一段时间,今天在家不能出门,也没啥事,就把它拿出来刷新系统。不成想居然搞了一天,还差点变成了砖。 原版的系统是安卓4.0的系统,很多软件已经不能用了,微信、优酷都不支持,而且三星也不提供更新升级,于是寻求第三方解决方案。折腾过程一波三折,就不赘述了,我就讲一下正确的操作过程吧。 切记我这里讲的过程只针对三星note8.0 table,国行版本,版本号是...

weixin_41108814的博客 2万+

访问寄存器方式

访问寄存器方式

qq_41949521的博客 649

从代码学习深度强化学习 - 目标导向的强化学习-HER算法 PyTorch版

经典的深度强化学习算法,如 PPO、SAC 等,在各自擅长的任务中都取得了非常好的效果。但它们通常都局限在解决单个任务上,换句话说,训练好的算法,在运行时也只能完成一个特定的任务。想象一个场景:我们想让一个机械臂能把桌子上的任何一个物体重置到任意一个指定位置。对于传统强化学习而言,如果目标物体的初始位置和目标位置每次都变化,那么这就是一个全新的任务。即便任务的“格式”——抓取并移动——是一样的,但策略本身可能需要重新训练。这显然效率极低。为了解决这类问题,

weixin_43887510的博客 1499

BIDS数据存储格式介绍与dcm2bids安装与使用

BIDS格式&dcm2bids安装与使用

machinelearning_er的博客 7317

管理端口_嵌入式Linux系统是如何管理IO端口以及IO内存的呢?老司机给你讲讲

“一、I/O端口端口(port)是接口电路中能被CPU直接访问的寄存器的地址。几乎每一种外设都是通过读写设备上的寄存器来进行的。CPU通过这些地址即端口向接口电路中的寄存器发送命令,读取状态和传送数据。外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。“二、IO内存例如,在PC上可以插上一块图形卡,有2MB的存储空间...

weixin_34796621的博客 193

个人顶级AI助手OpenClaw(Clawdbot) - 新手快速入门指南

本文详细介绍了个人顶级AI助手OpenClaw(Clawdbot) 的快速入门指南,包括安装部署和使用配置及注意事项

program哲学 5305

Linux内核对I/O端口的管理实现

本文主要从内核实现的角度分析Linux 2.4.0内核IO子系统中对IO端口资源的管理的实现原理。本文是为那些想要深入分析Linux的IO子系统的读者和设备驱动程序开发人员而写的。 几乎每一种外设都是通过读写设备上的寄存器来进行的。外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。CPU对外设IO端口物理地址的编址方式

thewayma的专栏 1122

kaggle学习笔记-餐厅数据挖掘

分析Zomato数据集的基本思想是为了公平地了解影响在班加罗尔不同地方建立不同类型餐厅的因素,每个餐厅的总评级,班加罗尔是这样一个城市,拥有超过12,000家餐厅,餐厅供应来自世界各地的菜肴。每天都有新的餐馆开业,这个行业还没有饱和,需求也在与日俱增。然而,尽管需求不断增加,新餐馆却很难与老牌餐馆竞争。大多数餐厅都供应同样的食物。班加罗尔是印度的IT之都。这里的大多数人主要依靠餐馆的食物,因为他们没有时间自己做饭。由于对餐馆的需求如此巨大,因此研究一个地方的人口统计学就变得很重要。

优快云XXCQ的博客 1862

视频压缩的工作原理

当你正在观看你最喜欢的节目,出现缓冲的时候,这是什么原因?当 Wi-Fi 带宽不足以下载传输视频流所需的数据时,就会发生缓冲。也有可能是视频网站发布了未压缩版本的视频文件,因此视频文件太大而无法流畅地流式传输。在高清模式下,图像分辨率为1080x1920像素,如果我们想象一个视频由许多这些图像组成,称为帧,那么 Wi-Fi 连接必须多快才能播放24帧/秒?答案是超1000兆,没错。由于每一帧都是48兆比特的数据,它实际上需要48×24每秒兆比特 (Mbps) 以观看视频24帧/秒。

学以致用 知行合一 1280

理解UART 子系统:Linux Kernel 4.9.88 中的核心结构体与设计详解

本文详细探讨了 Linux 内核中串口(UART)和 TTY 驱动的核心数据结构及其作用。通过分析 uart_port、uart_driver、tty_port、tty_driver 等关键结构体,阐述了串口硬件配置、驱动信息管理、TTY 端口资源状态维护,以及驱动与设备交互的实现细节。此外,还介绍了 uart_state 和 tty_operations 的核心功能,展示了 UART 与 TTY 子系统如何协同工作,完成设备控制和数据传输任务。

caiji0169的博客 3084

车间数据孤岛终于破了!C#上位机+MQTT打通产线与MES,数据延迟从小时级降到秒级

本文针对工业上位机开发中常见的车间数据与企业管理系统(MES)割裂问题,提出基于C#和MQTT协议的完整解决方案。通过EMQX MQTT Broker实现数据实时双向传输,将质量追溯时间从2小时缩短至10秒,生产计划自动下发,实现秒级数据延迟。方案采用分层解耦架构,支持设备更换和系统升级,核心优势包括低延迟、高可靠性和易扩展性。文章详细介绍了MQTT协议选型理由、整体架构设计、技术选型(EMQX Broker和MqttNet客户端),并提供了C#实现代码和部署流程。该方案已在实际产线验证,可有效解决&quo

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 480

系统管理命令linux,Linux 系统管理命令

查看命令的使用方式help 列出常用的shell命名mkdir --help 列出指定命令(mkdir)的使用方式(参数)命令的历史记录方向键向上 上一条命令方向键向下 下一条命令清屏clear 只是往下翻开新的一页,往上滑仍可以看到之前的内容,常用reset 清空之前输入的内容,速度略慢关机、重启shutdown 关机reboot 重启查看正在执行的程序的信息top...

weixin_42321086的博客 106

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Ogar项目全面解析:从零开始搭建你的Agar.io私人服务器

想要搭建自己的Agar.io游戏服务器吗?🤔 Ogar是一个完全开源的Agar.io服务器实现,使用Node.js编写,让你可以轻松创建私人游戏服务器,与朋友一起享受这款经典的大鱼吃小鱼游戏!无论你是游戏爱好者还是开发者,这篇完整指南将带你从零开始,一步步搭建属于你自己的Agar.io私人服务器。 ## 🚀 为什么选择Ogar私人服务器? Ogar项目让你完全掌控游戏体验!相比官方服务器,

gitblog_00806的博客 736

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

RabbitMq安装部署指南

RabbitMq安装部署指南

li18230143817的博客 2031

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Linux系统管理从入门到精通:25万字实战笔记与核心技能树解析

Linux作为现代计算基础设施的核心操作系统,其系统管理与运维能力是IT工程师的核心竞争力。理解其设计哲学与底层原理,是掌握高效运维的关键。从文件权限、进程管理到网络服务配置,Linux提供了一套完整的工具链与抽象模型,使得自动化运维与性能调优成为可能。在云计算与容器化时代,这些基础技能的价值愈发凸显,能够支撑从传统服务器管理到微服务架构的平滑过渡。本文基于一份超过25万字的实战笔记,系统梳理了Linux学习的核心路径,涵盖从基础命令到内核机制的完整知识体系,并融入了大量生产环境中的真实案例与调优技巧,为工

weixin_30924087的博客 351

Unity Mirror网络游戏Linux服务器部署全攻略:从开发到生产环境

如果你是一名Unity开发者,正在为你的多人游戏项目寻找一个稳定、高效且易于上手的网络同步解决方案,那么Mirror组件很可能已经进入了你的视野。但问题来了:当你兴致勃勃地在本地编辑器里跑通了所有网络逻辑,准备将你的“大作”部署到真正的Linux服务器上时,一系列现实问题会瞬间将你拉回地面。 为什么客户端连不上服务器?为什么在Windows上运行正常的构建,到了Linux服务器就崩溃?Mirror的服务器端到底需要哪些依赖?如何让服务器在后台稳定运行,而不是随着SSH会话的结束而关闭?这些问题,正是从“玩具

aqc802886的博客 344

个人向 Linux 服务器开荒

Node Exporter采集系统指标,配置警报规则可及时发现问题。系统安装时需选择最小化安装,仅勾选SSH服务。top/htop监控实时资源占用,iotop检查磁盘I/O,nethogs分析网络流量。安装后需将用户加入docker组,配置镜像加速器提升拉取速度。配置合理的封禁时间和查找规则,监控认证日志中的异常登录尝试。设置SSH密钥用于代码仓库认证,配置.gitignore文件避免提交敏感信息。UFW或firewalld工具可管理端口开放策略,仅暴露必要端口。,需设置正确的文件权限和SSL证书。

gaize1213的博客 595

1Panel深度体验:除了建站,它的容器管理和主机监控功能到底有多强?

本文深度体验了1Panel在Linux服务器管理中的强大功能,特别是容器管理和主机监控方面。通过可视化操作简化了Docker Compose编排、镜像优化和微服务部署,同时提供了实时资源监控、日志审计和防火墙配置等高级功能,显著提升运维效率。

376
上一篇: feign调用service_SpringCloud Alibaba微服务实战三 - 服务调用
下一篇: vscode 支持ansi_[电脑技巧] 让VSCode支持右键打开文件和目录
唯我一心
博客等级 码龄8年 22粉丝 72原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值