MPSOC上UIO中断机制详解:PL到PS用户态中断链路实战
1. UIO中断机制的前置认知1.1 为什么MPSOC上要单独处理中断MPSOC多处理器片上系统在嵌入式领域用得越来越广尤其是同时集成了PS处理系统通常是ARM核和PL可编程逻辑也就是FPGA逻辑的芯片。这种架构最大的优势在于软硬件协同——PS端跑Linux系统处理复杂任务PL端做高速并行逻辑处理实时性要求高的信号。但两者一旦要协作中断就成了绕不开的环节。PL端产生的中断信号如果想让PS端Linux里的应用程序及时感知并响应通常有三个思路用GPIO模拟中断轮询或者通过内核GPIO子系统上报把硬件中断设备树配置好写一个完整的内核驱动来管理用UIOUserspace I/O机制把中断和寄存器映射直接暴露给用户态程序不写完整内核驱动。前两种方案的共性是你得维护内核态代码编译进内核或者作为模块加载调试要反复交叉编译、烧写、重启非常折腾。第三种方案UIO就是专门为“不想写内核驱动”的场景准备的——中断来了以后内核只负责把硬件中断转发到用户态用户程序自己决定怎么响应。我在实际项目中用过一段时间的UIO方案老实说它在某些场景下确实省事但也有不少坑。这篇文章就把PS和PL之间通过UIO传递中断这件事掰开揉碎讲清楚。1.2 什么场景适合UIO方案UIO的定位是“轻量级用户态驱动框架”。它适合以下几类情况你只是想快速验证PL逻辑和PS端的联动不想一开始就陷入内核驱动开发的泥潭你的中断处理逻辑很特殊放在内核态反而麻烦比如业务处理本身就在用户态中断触发后需要直接访问大量应用层数据你希望驱动开发和业务开发解耦PL侧的寄存器频繁变动每一次改动都重新编译内核模块太痛苦你用的是Yocto或者PetaLinux这类工具链内核模块的交叉编译环境配置繁琐改用UIO可以让你直接用交叉编译的纯C程序甚至Python调用mmap完成任务。当然UIO并不适合对实时性和中断延迟有极高要求的场合。毕竟一次中断从硬件触发到用户态程序跑起来中间经历过内核UIO框架的转发。如果PL端中断频率非常高比如十几微秒一次你还要考虑用户态程序的处理能力和调度延迟这时候老老实实写内核驱动反而更靠谱。注意UIO不是万金油它适合“中等频率、秒级到毫秒级响应都够用”的典型场景。我见过有人把UIO用在光纤通信的MAC中断上结果用户态处理不过来导致丢包最后还是回归内核态驱动。选型阶段一定要把中断频率和应用延迟需求先摆出来。2. UIO中断链路在MPSOC上的整体结构2.1 PS与PL中断信号的物理通路在MPSOC芯片内部PL端的中断信号要到达PS端的GIC通用中断控制器得经过一套固定硬件通路。以常见的美满/Xilinx系列MPSOC为例PL端的中断通常连到PS端的IRQ编号区间上每条中断线对应一个中断ID。这部分属于硬件管脚分配和Block Design连线的问题。你在Vivado里做Block Design时需要给PL的中断输出引脚绑定到PS端的中断输入端口上通常是通过Concat模块把多个PL中断汇总成一路或几路再接到ps_pl_interrupt端口。关键点在于PL逻辑中中断信号必须是脉冲或电平有效的方式而且要在设备树中指定正确的中断号。如果设备树里写的中断号不对Linux内核根本不知道这个中断对应哪个设备UIO自然也就无法正常工作。以典型配置为例UIO设备在设备树中的中断属性通常写成interrupts 0 29 4;这行配置的含义是GIC类型为SPI共享外设中断时第一个参数填0第二个参数是中断ID第三个参数是中断触发方式。其中触发方式4代表高电平有效。2.2 设备树里UIO节点的配置要点设备树是PS端硬件资源的描述语言Linux内核对UIO框架的支持来自通用UIO驱动设备树里只要挂上“generic-uio”这个compatible系统启动后就会自动生成/dev/uioN节点。我常用的UIO中断节点模板如下/ { reserved-memory { #address-cells 2; #size-cells 2; ranges; uio_reserved: uio0x40000000 { reg 0x0 0x40000000 0x0 0x10000000; no-map; }; }; }; axi { uio_pl_dev: uio-pla0000000 { compatible generic-uio; reg 0x0 0xa0000000 0x0 0x1000; interrupts 0 31 4; interrupt-parent gic; memory-region uio_reserved; }; };这里有两个重点。第一reg中的物理地址要和Vivado里PL逻辑的地址分配一致第二如果PL侧需要和PS侧共享大块内存做数据交互最好预留reserved-memory这块内存不在Linux管理范围内PS用户态程序可以直接读写PL侧的DMA引擎也可以直接访问两边不会因为Linux的缓存一致性机制出问题。实战心得设备树里UIO节点的interrupts配置经常踩坑。有人用interrupts 0 31 4没问题有人改成0 31 1上升沿触发就失效了。原因是PL端逻辑输出中断信号的电平/脉冲方式必须与触发类型匹配。如果你的PL逻辑是持续高电平输出设备树触发方式必须是4高电平有效设成1上升沿只在边沿瞬间有效一旦逻辑保持高电平UIO就可能收不到第二次中断。这点在调试时一定要先确认PL端的信号行为。3. UIO用户态联动设计3.1 用户态与UIO共享内存通信分析UIO不只是中断转发它还同时把PL侧的寄存器空间映射到了用户态让写应用和写嵌入SQL一样的便利。一般使用UIO的PL与PS的联动机制包含两条链路其中一条是PL中断到PS另一条是其反向链路。先说PL到PS的中断链路。硬件上PL逻辑通过Interrupt端口发出中断请求经过PS的PL中断控制逻辑到GIC再触发UIO内核驱动最终通过文件描述符把事件通知用户态。用户在用户态通过select/poll/epoll监听该文件描述符。再说PS到PL的控制链路。用户态程序打开/dev/uioN之后调用mmap映射PL寄存器。比如你将PL中某个寄存器映射到用户空间的虚拟地址向该地址写一个控制字PL端逻辑就能立刻响应比如启动数据采集或改变输出状态。这两条链路一组合整个“双向实时控制”的闭环就通了用户态程序向控制寄存器发指令PL开始干活干完了发中断用户态读状态寄存器确认结果再发下一步指令。3.2 mmap映射寄存器空间的机制拆解UIO设备的mmap行为是内核UIO框架驱动的它的实现原理是把注册时传入的物理地址区域映射到用户空间的虚拟地址段。整个过程不需要用户写任何内核代码这就是UIO最爽的地方。在实际写用户态程序时我通常这样做#include fcntl.h #include sys/mman.h #include unistd.h #include stdio.h int main(int argc, char *argv[]) { int fd open(/dev/uio0, O_RDWR | O_SYNC); if (fd 0) { perror(open /dev/uio0 failed); return -1; } unsigned int *pl_regs mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (pl_regs MAP_FAILED) { perror(mmap failed); return -1; } /* 写控制寄存器 */ pl_regs[0] 0x01; /* 等待中断 */ unsigned int irq_count 0; ssize_t nread read(fd, irq_count, sizeof(irq_count)); if (nread sizeof(irq_count)) { printf(interrupt count %u\n, irq_count); } /* 读状态寄存器 */ unsigned int status pl_regs[1]; printf(status 0x%08x\n, status); munmap(pl_regs, 4096); close(fd); return 0; }这里有个很容易犯的致命错误打开UIO设备时只用了O_RDWR没有加O_SYNC。对硬件寄存器来说一般必须用O_SYNC打开否则mmap出来的内存是带Cache的你写入的数据可能停留在Cache中不会立即到达PL寄存器PL等半天等不到数据或者读回的寄存器永远是旧值。4. 中断信号与设备树中断号映射关系4.1 MPSOC中断号的计算方法MPSOC的中断控制器是GIC支持两种中断类型SPI共享外设中断— 对应设备树interrupts属性第一个参数为0PPI私有外设中断— 对应设备树interrupts属性第一个参数为1。在Linux系统中IRQ number不是简单的硬件中断IDGIC驱动会把硬件中断号映射成一个Linux内部的IRQ number。通常SPI的起始IRQ number在系统里有一个偏移量比如是32也就是说硬件中断ID是31的SPI系统IRQ number可能是63。但在设备树里你不需要关心LinuxIRQ number只需要写硬件中断ID。这个ID怎么确定MPSOC芯片手册的“PS-PL interrupt”小节里会给出一个表列出PL端每个中断端口对应的中断ID。以常见芯片为例PL到PS的中断ID范围是121到135共16根线。如果你在Vivado里把PL的中断接到了第0号PL中断端口对应中断ID就是121那么设备树里写interrupts 0 121 4;4.2 interrupt-parent的作用与常见误区设备树里中断控制器是一个树状结构SoC上可能存在多个中断控制器。interrupt-parent属性就是告诉内核“我这个设备的中断是挂在哪个中断控制器上的”。在MPSOC的设备树里最常见的写法是gic { #interrupt-cells 3; }; uart1 { interrupt-parent gic; interrupts 0 22 4; };如果设备树里漏了interrupt-parent内核会沿着设备节点的父节点向上查找默认中断控制器大多数时候系统能自动找到GIC但为了阅读和维护的清晰度显式写出来是最佳习惯。这里有一个需要注意的地方MPSOC的GIC版本不同中断触发类型的编码可能不同。GIC v2的触发类型编码是1上升沿触发2下降沿触发4高电平触发8低电平触发。如果你把4写成1PL端发出高电平中断时UIO可能在中断第一次触发后就不再响应了。5. UIO驱动在内核态的工作流程5.1 UIO框架的注册与设备节点生成UIO框架是Linux内核自带的标准框架核心代码路径是内核启动时扫描设备树发现compatible属性为“generic-uio”的节点调用uio_register_device注册一个UIO设备框架自动创建/dev/uioN字符设备节点为每个UIO设备分配一个中断号注册中断处理函数uio_interrupt中断到来时uio_interrupt调用用户的irqcontrol回调generic-uio的回调为空然后唤醒等待队列中阻塞的read/poll用户。这个流程不需要你写任何内核代码设备树配好了中断链路就能自动建立。5.2 UIO中断处理与用户态唤醒的时序当PL端中断信号到达GIC时内核中断子系统先把中断分发到UIO设备的处理函数。UIO驱动做的第一件事是禁掉该中断防止在用户态还没响应时频繁触发导致中断风暴。然后它把中断计数加1并且唤醒等待在该设备文件描述符上的进程。用户态read函数此时返回返回值为一个无符号整数表示累计中断次数。重点来了用户态程序在中断处理完成后必须重新“使能”中断否则后续的中断不会再上报。这个动作是通过write一个int值到UIO设备文件实现的无论写什么值都是使能中断的意思。int irq_enable 1; write(fd, irq_enable, sizeof(irq_enable));这一步非常容易漏。我在最初调试时第一次中断能收到第二次就再也没反应被这个问题折磨过半天。原因是中断处理完成之后没有重新写设备文件使能中断。6. 核心实操验证中断链路的过程记录6.1 环境准备与工具清单做这个实验建议准备以下工具和环境一块MPSOC开发板PS端能启动LinuxPetaLinux或Yocto构建出的内核镜像和设备树内核开启CONFIG_UIO和CONFIG_UIO_PDRV_GENIRQPL端烧录好一个最简单的Verilog中断发生器通过一个计数器每计数到某个值拉高中断引脚一个时钟周期USB转串口工具用来查看Linux控制台日志交叉编译工具链PL端逻辑不需要太复杂一个简单的中断发生器就够用module intr_gen ( input clk, input rst_n, output reg intr ); reg [31:0] cnt; always (posedge clk or negedge rst_n) begin if (!rst_n) begin cnt 32d0; intr 1b0; end else begin cnt cnt 1; if (cnt 32d1000000) begin intr 1b1; cnt 32d0; end else begin intr 1b0; end end end endmodule这个模块的作用是每1000000个时钟周期输出一个时钟周期的高电平脉冲中断信号相当于周期性产生中断。时钟采用PS端输出的PL时钟比如100MHz那就是每10ms产生一次中断非常适合验证。6.2 设备树配置与内核启动验证设备树里我使用的是前面提到的generic-uio节点。编译设备树后重新烧写启动进入Linux后首先查看设备节点是否生成ls -l /dev/uio*如果看到/dev/uio0说明UIO设备注册成功。再查看系统中断分配cat /proc/interrupts | grep uio输出里能看到类似这样的内容63: 0 0 GIC-0 121 uio-pl其中第一列是Linux里的IRQ number最后一列是设备名称这就是你的UIO设备。中断计数值是0因为还没有程序打开这个设备并等待中断。6.3 用户态测试程序与预期结果接下来运行一个简单的测试程序验证中断链路是否完全打通#include fcntl.h #include sys/mmap.h #include stdio.h #include unistd.h #include stdint.h int main() { int fd open(/dev/uio0, O_RDWR | O_SYNC); if (fd 0) { perror(open); return -1; } unsigned int *regs mmap(NULL, 16384, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (regs MAP_FAILED) { perror(mmap); return -1; } printf(waiting for interrupt...\n); for (int i 0; i 10; i) { uint32_t irq_count; int res read(fd, irq_count, sizeof(irq_count)); if (res ! sizeof(irq_count)) perror(read); printf([%d] got interrupt, total %u\n, i, irq_count); /* 重新使能中断这步必须做 */ int enable 1; res write(fd, enable, sizeof(enable)); if (res ! sizeof(enable)) perror(write); } munmap(regs, 16384); close(fd); return 0; }预期结果每秒约100次中断取决于PL逻辑的中断周期程序打印出不断增长的中断计数。如果中断计数器递增正常说明从PL逻辑、物理连线、设备树、内核UIO驱动、用户态程序全链路打通。注意中断计数返回的是累计值不是增量值。每次read拿到的数值都是历史累计的。程序里用这个值来判断中断是否真的发生过同时也能用来检测中断是否有丢失——如果前后两次读到的差值大于预期说明中断处理不够及时。7. 常见问题与排查技巧7.1 /dev/uioN节点不存在设备节点没有生成多数是设备树没配对或是内核配置没有打开UIO框架。检查方法dmesg | grep -i uio如果没有任何输出多半是内核没配置CONFIG_UIO_PDRV_GENIRQ。打开该配置并重新编译内核。如果内核报错了节点解析错误检查设备树语法和compatible字符串是否与驱动匹配。7.2 中断收到一次后不再触发这个问题在实操中非常普遍。原因通常是用户态在中断处理完之后没有重新写UIO设备文件使能中断PL端中断信号是持续电平而非脉冲且设备树触发类型配置为边沿触发用户态read中断后程序忙别的事情太久没有及时重新使能中断。排查方法在中断处理完成后立即将使能写回如果还不行检查PL端的信号波形确认中断是否真的是脉冲信号。7.3 中断回调触发风暴导致系统假死如果PL端中断信号异常一直是高电平并且设备树里配置成了高电平触发UIO框架虽然会自动屏蔽中断但如果用户态处理完成又重新使能会立刻再次触发中断导致程序陷入死循环。这种情况看起来很像是系统崩溃了实际上只是用户态程序在反复响应中断。解决方法是修改PL端逻辑把持续电平改成短的脉冲信号或者在设备树里把中断触发类型改为上升沿。7.4 UIO中断失效排查速查表现象可能原因排查动作设备节点不存在内核配置未开检查CONFIG_UIO_PDRV_GENIRQ节点存在但无中断上报设备树interrupts写错核对硬件中断ID和类型第一次中断能收到后续无未重新使能中断在read后write任意intmmap后寄存器读写无效打开文件没带O_SYNC改为open(“/dev/uio0”, O_RDWR/SYNC)中断风暴PL端中断信号异常修改PL逻辑为脉冲输出读寄存器一直是0地址映射错误核对设备树reg地址和Vivado地址一致7.5 个人调试技巧总结我在用UIO调试MPSOC中断时有几个从实践中沉淀出来的好习惯第一拿到板子先做“裸跑测试”。也就是PL端逻辑里加一个调试寄存器通过JTAG或者Vivado的ILA观察中断信号到底有没有产生。先确认信号没问题再去查软件配置能帮你把排查范围砍掉一大半。第二设备树的修改要养成版本管理习惯。MPSOC的设备树编译后烧写比较费时我一般会先在开发环境里把.dtsi文件放Git每次改动都做diff避免烧一次板子才发现是自己把数字改错了。第三UIO设备节点在多个PL中断时每个中断单独注册一个UIO设备这样用户态可以用多个文件描述符分别处理不同中断优先级。我见过有人把多个中断合到一个UIO设备上结果用户态不知道是谁触发了处理逻辑一团乱麻。多注册几个UIO设备成本很低收益却很明显。第四如果PL和PS需要大量数据交互优先用reserved-memory做无缓存共享内存。用UIO直接mmap PL的BRAM虽然方便但没法解决缓存一致性问题数据容易错乱。8. 方案延伸与反思8.1 UIO方案在MPSOC项目中的扩展思路UIO方案不止能处理简单的中断还能做大块数据搬运。配合PS端的DMA控制器用户态程序可以在UIO映射的寄存器里配置DMA源地址、目的地址和数据长度PL端发一个“DMA完成”中断用户态就能在共享内存里拿到一整块数据。这种模式在数据采集卡、高速ADC采样、视频帧抓取之类的场景里非常常见。8.2 与DMA结合时的注意事项DMA和UIO一起用时最需要关注的是内存物理地址连续性。用户态malloc出来的内存是虚拟地址其物理页不一定连续DMA控制器需要物理地址。通常做法是在设备树里预留一段连续的物理内存reserved-memory然后通过UIO mmap把它映射到用户态DMA的源和目的都指向这段内存。这种方式下PL和PS的数据通路可以是PS写共享内存中的命令区PL通过AXI接口轮询命令区PL执行完成后写结果区并拉高中断PS收到中断后在共享内存中取结果整个数据流不需要任何内核态代码参与用户态程序全包了。实际项目中我曾遇到一次共享内存被Linux回收导致PL读到错误数据的问题。后来将那段reserved-memory加上no-map属性并确保用户的应用程序中不会直接free该区域的虚拟地址才稳定下来。8.3 UIO方案的适用边界UIO方案看上去很完美但也需要清醒认识其边界。对于中断频率非常高的场景比如几十纳秒一次的中断用户态程序频繁切换上下文消耗太大UIO框架的两次复制、唤醒、等待队列调度带来的延迟不可忽视。这时候正确做法是写内核驱动用底部一半逻辑处理高频事件只把关键状态放在共享内存供用户态按需读取。如果项目对稳定性要求极高比如医疗设备、工业控制我更建议用主线内核的标准框架而不是UIO。UIO的好处是开发快坏处是内核态和用户态之间隔着一个“不可控”的调度层中断延迟抖动完全取决于系统负载。对我个人来说选型逻辑是验证阶段、Demo阶段、或者PL逻辑还在频繁变动的时期用UIO产品化定型、要求极致稳定性的模块花时间把驱动写成内核态更值得。写过完整内核驱动之后再回头看UIO你会更理解Linux中断机制的两面性——UIO把复杂藏在框架里内核驱动把控制权交给你。两条路各有各的门道关键在于你对项目的阶段目标和风险承受能力有清晰判断。

相关新闻

《链表常见手撕代码总结》

《链表常见手撕代码总结》

1.一个单链表&#xff0c;如何操作将整个链表进行反转&#xff1f;方式一&#xff1a;使用Stack栈创建 Stack<Integer> 保存链表结点数据&#xff0c;遍历原链表将所有数据入栈&#xff0c;再新建结果链表&#xff0c;不断弹出栈顶元素尾插进新链表&#xff0c;以此完成链…

2026/10/15 3:20:38 阅读更多 →
易语言乐玩插件实战:图片密码设置与枚举卡屏判断

易语言乐玩插件实战:图片密码设置与枚举卡屏判断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 3:20:38 阅读更多 →
红日安全靶机实战:从信息收集到提权的完整渗透链路

红日安全靶机实战:从信息收集到提权的完整渗透链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 3:20:38 阅读更多 →

最新新闻

git 源代码里,出现一大堆红色文件的一次思考

git 源代码里,出现一大堆红色文件的一次思考

git 源代码里&#xff0c;出现一大堆红色文件 是因为切换分支的时候&#xff0c;底座导致的。 1.首先要理解rebase是什么意思&#xff1f; rebase是录制本地代码&#xff0c;把最新的代码作为背景&#xff0c;然后把最新修改加在最新代码后面。 2.如何解决呢&#xff1f; git c…

2026/10/15 4:02:46 阅读更多 →
18.从 IP 到 MQTT:STM32 用 AT 指令驱动 ESP-12F 上云的完整链路(含全套实战代码 + 踩坑清单)

18.从 IP 到 MQTT:STM32 用 AT 指令驱动 ESP-12F 上云的完整链路(含全套实战代码 + 踩坑清单)

这是我做 STM32F411 ESP-12F 跑通 MQTT 上云之后的一次系统复盘。上一篇讲了「网络地基 → MQTT 模型 → AT 指令遥控」三层逻辑&#xff0c;有同学说想要能直接抄走跑的代码。这篇我把全套实战代码补上&#xff1a;mqtt.h 头文件、mqtt.c 逐函数实现&#xff08;每步为什么这…

2026/10/15 4:02:46 阅读更多 →
git 里的 rebase到底是什么?

git 里的 rebase到底是什么?

一句话&#xff1a;rebase-把本地代码录制下来&#xff0c;把背景换成别人的最新代码&#xff0c;然后把本地代码在最新代码基础上播放出来。那么 git pull --rebase origin master 是什么意思呢&#xff1f;意思是什么 取服务器的最新代码作为底座&#xff0c;origin 代码仓库…

2026/10/15 4:02:46 阅读更多 →
从背了就忘到主动复习 江苏一个初中英语班的变化

从背了就忘到主动复习 江苏一个初中英语班的变化

苏南一位初三孩子的妈妈跟我聊起上学期的事。孩子英语卷子拿回来&#xff0c;阅读错一半&#xff0c;完形填空连蒙带猜&#xff0c;最让她头疼的是词汇——今天默写全对&#xff0c;三天后再测&#xff0c;能记住的不到三成。她试过打印单词表、买过卡片、也盯着孩子抄过几遍&a…

2026/10/15 4:02:46 阅读更多 →
GitHub Copilot Chat:用对话方式让 AI 帮你重构代码

GitHub Copilot Chat:用对话方式让 AI 帮你重构代码

GitHub Copilot Chat&#xff1a;用对话方式让 AI 帮你重构代码一、重构——AI 编程的"杀手级场景" 在所有的编程任务中&#xff0c;代码重构是从 AI 辅助中获益最大的场景之一。重构有个特点&#xff1a;它需要理解现有代码的逻辑&#xff0c;然后进行"安全的变…

2026/10/15 4:02:46 阅读更多 →
一种可快速恢复的Zabbix高可用架构设计

一种可快速恢复的Zabbix高可用架构设计

做运维的朋友们可能都有过这样的深夜惊魂&#xff1a;好容器完成了监控的Server、Proxy的部署、告警的收敛&#xff0c;监控的覆盖率也达标了&#xff0c;结果承载Zabbix Server和PostgreSQL的机器突然宕机。那一刻&#xff0c;不是“少看几张图”的问题&#xff0c;而是整个团…

2026/10/15 4:01:45 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时&#xff0c;网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上&#xff0c;依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里&#xff0c;扩缩容到底难在哪做过大模型推理服务部署的人&#xff0c;大概都经历过这样的场景&#xff1a;一个团队共用一套推理集群&#xff0c;A 业务跑的是 7B 的小模型&#xff0c;B 业务跑的是 72B 的大模型&#xff0c;C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子&#xff1a;一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减&#xff0c;为了把启动时间压进两秒以内&#xff0c;我手贱地把一串自认为“没用”的 systemd 服务给 disable 了&#xff0c;其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →