做工业控制这十年我最大的体会是真正卡住项目的往往不是算法而是总线。方案评审会上说得好好的“加两条EtherCAT总线、六路CAN”等硬件拿到手才发现普通工控机贵得离谱树莓派又没有双网口和PCIe扩展能力最后算下来OrangePi 5 Plus反而是最顺手的底座。这块板子用的是瑞芯微RK3588四个A76大核加四个A55小核双2.5G网口M.2槽位还能走PCIe扩展再配上打了PREEMPT_RT补丁的软实时Linux完全当成一台“双EtherCAT主站6路CAN”的开放式运动控制器来用。这篇文章就完整记录我从选型到落地的全过程包括内核怎么编、IgH主站怎么搭、CAN扩展为什么用PCIe卡、以及各种奇奇怪怪的坑给准备在同类型硬件上做实时控制的人一条能直接抄的路线。1. 项目拆解与方案选型思路1.1 为什么是OrangePi 5 Plus而不是传统工控机先说结论如果只做简单点动几十块钱的开发板加一个USB转CAN也能跑。但这次项目的要求是双EtherCAT总线和6路CAN同时工作还要预留视觉和运动学计算余量硬件选型就不是随便找个板子能应付的。OrangePi 5 Plus的核心是RK35884个Cortex-A76大核最高2.4GHz4个Cortex-A55小核最高1.8GHz16GB内存版本跑Linux加实时控制都很宽裕。这颗芯片在嵌入式里的定位类似“手机旗舰SoC做工业控制”性能远远超过传统的ARM9/A7方案。更关键的是它的接口布局非常适合做总线主站硬件资源OrangePi 5 Plus树莓派5低配x86工控机CPURK35884×A764×A55BCM27124×A76常见赛扬/N100网口双2.5G单千兆一般双千兆PCIe扩展M.2 M-KeyPCIe 3.0M.2只有PCIe 2.0 x1丰富但体积大价格千元内同价位但接口少两三千起CAN扩展M.2转PCIe插多路CAN卡只能USB/SPIPCIe卡直插双2.5G网口对EtherCAT来说非常关键——EtherCAT每个网段需要一个物理网口跑两条独立总线就要两个网口。树莓派单网口想双EtherCAT就得外接USB网卡稳定性差一个量级低配x86工控机虽然也能做但体积、功耗、价格都上去了而且很多工控机的BIOS和网卡中断表现并不比这块开发板好。另外OrangePi 5 Plus的两个网口驱动路径不一样一个走原生GMAC一个走PCIe通道。刚开始我觉得这是“割裂感”后来发现这反而是个优点两个网口的中断可以分别绑到不同CPU核做两条EtherCAT总线隔离时互不干扰。1.2 实时方案软实时PREEMPT_RT到底够不够用做EtherCAT主站实时性是绕不开的话题。有人一提实时就上Xenomai甚至直接上RTOS但我的看法是分场景。EtherCAT主站本质上是一个周期任务周期通常1ms到4ms主站需要在这个周期内完成数据收发和用户计算。Xenomai能提供更高的硬实时保证但开发复杂度也高很多现成的Linux库在Xenomai环境里不好跑。PREEMPT_RT也就是“软实时”方案把Linux内核变成一个完全可抢占的系统普通用户态线程通过SCHED_FIFO调度策略拿高优先级跑周期任务。实测数据说话在OrangePi 5 Plus上用cyclictest测99.99%的延迟能压在80微秒左右偶尔的max值也就在150微秒内。这个延迟水平跑2ms甚至1ms的EtherCAT周期完全没问题真正叠加到总线上主站周期抖动能控制在几十微秒以内对绝大多数伺服运动控制场景足够。选软实时还有一个重要原因生态。视觉库、数据库、Web服务、MQTT这些都能直接在普通Linux环境里跑不用再做复杂的RTOS/非RTOS双系统通信。这对一个既要控制总线、又要做设备联网和状态监控的项目来说省了太多事。1.3 两条EtherCAT和六路CAN的总线架构项目标题里写的“2 EtherCAT6 CAN”放在实际设备里就是这么一个结构第一条EtherCAT总线接到eth0挂3个伺服驱动器、1个EtherCAT数字量IO模块负责运动轴和产线信号。第二条EtherCAT总线接到eth1挂远程IO站、编码器模块和阀岛和第一条总线在物理上隔离避免单点故障全线崩溃。六路CAN分成三组一组走CANopen和变频器通信一组接BMS和分布式传感器另一组作为设备调试接口。CAN和EtherCAT的数据最终在应用层汇总我会在第四部分具体展开。这个架构的好处是隔离清晰、故障域小。EtherCAT菊花链本身就是一个接一个某条链路如果插拔或者从站断电最多只影响自己这条总线的设备不至于把另一条也拖下水。CAN这边六个独立通道类似各有各的仲裁和错误管理互不干扰。2. 硬件准备、接口扩展与实时内核构建2.1 硬件清单与外设接口规划搞实时控制硬件清单是个不能马虎的环节。主板选的是OrangePi 5 Plus 16GB版本强烈建议上16GB你永远不知道同时跑EtherCAT主站、CAN网关、Web监控和日志存储需要多少内存8GB版本有些时候会显得局促。扩展方面6路CAN我最推荐的方案是“M.2转PCIe外接多路CAN卡”。OrangePi 5 Plus的M.2插槽是PCIe 3.0 x4买一根M.2转PCIe x4的延长转接板把PCIe卡引到机箱挡板外侧就能插标准PCIe CAN卡。市面上有多路PCIe CAN卡4路、8路的都有我最后用了一张8路卡只启用其中6路这样还有2路做备用万一某路硬件故障可以快速切过去。其他清单列一下OrangePi 5 Plus 16GB版 官方12V/5A电源RK3588满载功耗不低别用杂牌电源。512GB NVMe SSD装系统、存日志和配方文件都靠它。M.2转PCIe x4延长板注意选“转单槽位”的别买那种多槽扩展坞工业环境不稳定。8路PCIe CAN卡。两个EtherCAT从站测试组我用的是汇川伺服、台达伺服和国产EtherCAT远程IO。不同从站混用对DC时钟同步是很好的压力测试。若干屏蔽网线、CAN总线双绞线、预压接端子。接口规划上我给了每个外设独立的物理位置eth0、eth1分属两条总线PCIe CAN卡占M.2NVMe SSD用USB硬盘盒或者干脆后期再说因为M.2被占了。调试串口保留方便内核卡死时看日志。2.2 给OrangePi 5 Plus编译带PREEMPT_RT补丁的内核在OrangePi 5 Plus上用软实时Linux重点就是内核要打PREEMPT_RT补丁。这一步看起来复杂其实分三步走拿源码、打补丁、编译安装。我选择的基准源码是OrangePi官方发布的Linux内核仓库因为RK3588的板级设备树、显示、编解码等驱动都在里面直接用上游kernel会碰到设备树不全的问题。拿到源码后找到和当前内核版本匹配的RT补丁比如内核版本是6.6.x就去kernel.org的realtime分支找对应的6.6.x-rt补丁不打错版本是基本素质。补丁放上去之后关键配置有以下几项CONFIG_PREEMPT_RTy这是核心开启完全抢占。CONFIG_HZ_1000y时钟频率选1000Hz周期任务时间片更细。CONFIG_CPU_FREQ_GOV_PERFORMANCEy后面调频要用。CONFIG_RT_GROUP_SCHEDn关闭实时组调度否则rt线程容易被组限额卡住。编译可以用板载编译RK3588的算力编译内核大概二十分钟到半小时比交叉编译省心。命令大致如下# 在Orangepi 5 Plus上操作 sudo apt install build-essential libncurses-dev flex bison libssl-dev bc # 进入已经打过rt补丁的内核源码目录 make ARCHarm64 orangepi-5-plus.config # 或者官方提供的defconfig scripts/config --enable PREEMPT_RT --enable HZ_1000 --disable HZ_250 make ARCHarm64 -j$(nproc) bindeb-pkg编译完成后会生成deb包直接dpkg安装然后改启动参数。Armbian或官方Debian系统在/boot/armbianEnv.txt里可以追加内核参数比如extraargsthreadirqsthreadirqs把中断强制线程化配合PREEMPT_RT使用效果更好。装完新内核重启后执行uname -a如果看到PREEMPT_RT字样就说明补丁生效了。2.3 实时性基线测试与内核参数调优内核换完别急着上EtherCAT先测一测实时基线。我用的工具是rt-tests里的cyclictestsudo apt install rt-tests sudo cyclictest -m -S -p 95 -i 1000 -d 0 -l 1000000参数含义-m锁定内存-S每个CPU跑一个测试线程-p 95是实时优先级-i 1000是1000微秒间隔-l指定100万次循环。这时候如果直接测会发现一个现象A55小核上的延迟明显比A76大核高而且偶尔会有毛刺。别急着骂内核先看一眼CPU调频是不是在“ondemand”。把调频策略改成performance再做中断亲和性设置。我最终使用的是EtherCAT相关的实时线程绑A76核心网络中断绑到A55核心这样中断处理和业务计算互不抢占。设置方式# 把所有网卡中断绑到CPU0和CPU1A55 for irq in /proc/irq/*/smp_affinity; do echo 3 | sudo tee $irq done # 实时任务运行时用taskset绑定到CPU4 taskset -c 4 ./ecat_thread注意生产环境别把所有中断一股脑绑到同一个核否则那个核会变成热点。我这边eth0的中断绑CPU0eth1的中断绑CPU1PCIe CAN卡中断绑CPU2实时线程固定CPU4或CPU5隔离开以后实测cyclictest的max值稳定在100微秒以内。3. 双EtherCAT主站搭建与DC时钟同步3.1 IgH主站安装与双主站模式配置EtherCAT主站方案我选的是开源IgH EtherCAT Master它成熟、文档全而且对RTL8211FD这类网卡支持很好不需要额外改驱动。IgH代码从EtherLab的仓库拉下来编译安装过程经典make sudo make modules_install sudo make install装完之后就是双主站的核心加载内核模块时指定两个网卡设备。IgH支持通过main_devices参数注册多个主站实例我们用eth0和eth1sudo modprobe ec_master main_deviceseth0,eth1加载成功后用命令确认sudo ethercat master输出里能看到Master 0和Master 1各自对应eth0和eth1状态应该是IDLE或OPERATIONAL。接着扫描一下从站sudo ethercat slaves每条总线的从站数量、厂商信息、产品码都会列出来。如果哪条总线没有扫描到从站先看物理链路再考虑驱动加载顺序别急着重启。这里说个容易踩的坑IgH默认会在模块加载时占用网卡如果系统里NetworkManager还在管理这两个网口会造成冲突。加载ec_master之前先把eth0和eth1从NetworkManager里移除或者干脆禁掉NetworkManager只保留systemd-networkd否则EtherCAT收发会被网卡管理工具搅乱WKC错误率直线上升。3.2 实时线程、中断亲和性与周期代码框架IgH主站搭好之后真正决定周期稳定性的是用户态实时线程怎么写。我的做法是创建两个pthread一个线程对应Master 0一个对应Master 1都用SCHED_FIFO策略优先级80左右用clock_nanosleep的绝对时间模式做周期调度这比usleep准得多因为usleep会受系统负载影响周期越跑越偏。周期线程里最核心的代码框架大致是这样struct timespec next; clock_gettime(CLOCK_MONOTONIC, next); while (run) { ecrt_master_activate(master); // 主站激活 ecrt_master_sync_datagram(master); // 周期同步 ecrt_master_receive(master); // 接收帧 ecrt_domain_process(domain); // 处理domain数据 // 在这里读写PDO数据比如伺服目标位置、控制字 ecrt_domain_queue(domain); ecrt_master_send(master); // 发送帧 next.tv_nsec PERIOD_NS; clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, next, NULL); }这段代码有几个细节很重要。第一周期线程里绝对不能调用printf、malloc、加锁这种操作它们会产生系统调用和调度延迟。日志输出要放到别的线程通过无锁队列传递。第二线程要绑核两个EtherCAT线程分别绑CPU4和CPU5中断已经绑到A55核两边各干各的实测周期抖动最小。第三周期时间用CLOCK_MONOTONIC而不是CLOCK_REALTIME避免NTP校时把周期给跳变。还有一个隐藏参数值得设置把实时线程允许运行的时间上限改掉。Linux默认限制实时线程最多占用CPU的95%即sched_rt_runtime_us。在一个核上只跑一个实时线程时这个限制会导致周期任务被强制让出CPU表现为周期毛刺。通过sysctl或cgroup把限制放宽即可sudo sysctl -w kernel.sched_rt_runtime_us-1测试的时候可以生产环境要评估是否安全但多数单用途实时控制设备上问题不大。3.3 DC分布式时钟同步与实测结果EtherCAT的DC分布式时钟是整个协议里最有含金量的部分。每个从站都有自己的本地时钟芯片EtherCAT通过ARMW命令把第一个具备DC能力的从站作为参考时钟然后周期性地把参考时钟写回到其它从站让所有从站工作在同一时间基准下。从站再根据这个时间基准产生SYNC0同步信号用来触发伺服驱动器的电流环、位置环采样。在IgH里DC同步的实现在主站激活后自动进行。我们可以通过命令查看每个从站的时钟漂移sudo ethercat dcDC同步的效果直接反映在从站SYNC0脉冲的一致性上。我拿示波器同时测了汇川伺服和IO模块的SYNC0在2ms周期下两个从站SYNC0的偏差能压在200纳秒以内。注意这个精度很大程度上取决于从站硬件和网线质量主站这边能做的就是保证DC报文每次都在固定的周期点发出不能忽早忽晚。实际操作中发现DC同步最怕两件事网线质量差和EMI干扰。EtherCAT网线必须用带屏蔽的工业网线屏蔽层要可靠接地如果现场有大功率变频器走线必须远离动力电缆。我曾经在一台伺服驱动器旁边用普通网线做过测试结果SYNC0抖动直接到了十几微秒伺服稍微加速就报跟随误差换成屏蔽网线加磁环之后问题消失。4. 六路CAN接口配置与工程化使用4.1 CAN扩展方案PCIe卡为什么比USB转CAN稳做6路CAN方案从USB转CAN、SPI转CAN到PCIe卡我都考虑过。USB转CAN最方便插六个USB口就行但实际用过就知道USB Host控制器是做批量传输的实时性完全看USB驱动心情。更麻烦的是当某一路CAN总线错误引发驱动异常时整个USB控制器可能重置六路一起掉线这是工业现场不能接受的。SPI转CAN用MCP2515这类的方案也有驱动稳定但每路CAN都需要占用一个SPI片选和中断引脚6路意味着大量GPIO和中断资源布线也复杂。所以最终选了PCIe多路CAN卡。一张8路卡插在M.2转PCIe槽位上驱动加载后系统里直接多出can0到can7八个网络接口启用前6路。PCIe在IO路径上延迟稳定DMA直接读写中断独立实时性比USB方案高一个档次。而且PCIe CAN卡一般自带一个不怕总线短路的物理层保护电路比USB小盒子扎实。4.2 SocketCAN配置、波特率与多路并发收发Linux下CAN接口走的是SocketCAN框架把CAN设备抽象成标准网络接口。配置6路CAN的最基本命令# 配置can0波特率500k sudo ip link set can0 up type can bitrate 500000 # CAN-FD模式可以指定数据段波特率 sudo ip link set can0 up type can bitrate 500000 dbitrate 2000000 fd on用CAN-FD还是经典CAN要看下游设备我这边变频器和BMS大多是经典CANopen所以统一用500kbps。6路逐个配置确实繁琐我当时写了一个开机脚本循环配置can0到can5for i in 0 1 2 3 4 5; do ip link set can$i up type can bitrate 500000 done配置完成后用candump可以监听一路或多路candump any # 监听所有CAN接口多路并发收发的工程化做法是用RAW套接字。每个CAN通道创建独立socket绑定对应接口然后用poll或线程模型统一处理。CAN消息结构是struct can_frame { canid_t can_id; __u8 len; __u8 data[8]; };一个小坑SocketCAN总线上有错误帧时默认不会把错误帧透传给应用层需要设置CAN_RAW_RECV_OWN_MSGS或者用candump -e才能看到。工业调试时最好把错误帧监控打开不然总线悄悄出问题等到设备报故障再排查就被动了。4.3 CANopen与EtherCAT的数据桥接6路CAN在实际项目中不是孤立跑的它们的数据最终要和EtherCAT总线的逻辑连起来。比如BMS通过CAN上报电量和温度控制器需要根据这些信息调整EtherCAT总线上的伺服速度产线的IO信号从EtherCAT远程IO进来又要通过CAN转发给变频器。这就需要一个“桥接层”。我采用的做法是共享一块环形缓冲区EtherCAT实时线程把自己的周期数据写入共享区CAN收发线程读取后组装成CANopen报文发出去反过来也一样。关键点在于不能用普通mutex因为EtherCAT线程里不能阻塞。这里我用的是无锁环形队列配合内存屏障保证数据一致性实测在双EtherCAT加六路CAN全速跑的情况下桥接延迟不超过一个CAN报文时间。如果你不想自己实现CANopen协议栈可以考虑开源方案CANopenNode在OrangePi 5 Plus上编译运行没有问题。但要注意CANopenNode默认的实现是单一接口实例多路CAN需要创建多个实例或者自己改对象字典存储结构。如果只是点对点传数据反而用裸CAN帧加自定义协议更可控毕竟协议栈本身也是有CPU占用的。5. 常见故障排查与避坑实录5.1 实时性毛刺的排查流程就算内核配置正确实际跑起来也经常遇到周期毛刺。我的排查顺序是固定的第一看CPU调频策略是不是被其他程序改回去了再次确认/sys/devices/system/cpu/cpu4/cpufreq/scaling_governor是performance。第二查中断分布用cat /proc/interrupts看网卡和CAN卡中断落在哪个CPU。如果发现所有中断都堆在一个核上用smp_affinity重新分配。第三用trace-cmd抓调度延迟来源sudo trace-cmd record -e sched_switch -e irq_handler_entry sleep 10抓完用kernelshark打开看基本都是NVMe存储的中断或者某个内核线程在抢占。我在项目里发现一个非常隐蔽的毛刺来源systemd-journald每隔一段时间会做日志落盘触发NVMe中断风暴实时线程被挤了一下。解决办法是把journald的同步频率调低并且把日志目录挂到tmpfs上不让它频繁刷NVMe。5.2 EtherCAT从站丢失与WKC异常处理EtherCAT跑着跑着某个从站数据突然不更新了这是老生常谈的问题。在IgH里直接体现为WKC(Working Counter)不对domain检查时发现某个从站的PDO没有返回。常规排查命令sudo ethercat slaves # 看从站是否还在总线上 sudo ethercat master # 看主站状态是否有DC报错 sudo ethercat log -l 20 # 查看最近的日志信息如果从站从slaves列表里消失了多半是物理链路问题网口松动、从站掉电、或者网线中间某个水晶头接触不良。EtherCAT是菊花链拓扑任何一个物理断点都会导致后面所有从站丢失排查时从最靠近主站的从站开始检查。如果从站还在但WKC不匹配重点看从站状态机。EtherCAT从站有INIT、PREOP、SAFEOP、OP四种状态只有OP状态才能正常交换循环数据。用命令直接操作状态sudo ethercat states -l 0x08 # 把所有从站切到OP如果切不过去大概率是PDO映射和从站厂商配置不一致。用ethercat pdos查看当前从站的PDO内容和XML导出的配置对比找到差异重新映射即可。5.3 CAN总线错误帧、总线关闭与恢复多路CAN挂在同一个PCIe卡上最典型的问题是某一路总线错误严重时CAN控制器会进入bus-off状态后续报文全部发不出去。现象也很典型程序正常写socket但总线上看不到任何波形。排查从物理层开始。CAN总线调试三板斧先量终端电阻在总线两端各有一个120欧电阻断电测量两根线之间的阻值应该是60欧左右这是最简单也最查不出问题的一个测试然后检查CAN_H和CAN_L有没有接反最后确认所有节点的波特率一致。多路CAN共地问题也常被忽略各节点之间必须有参考地否则共模电压异常会导致大量错误帧。总线关闭之后SocketCAN有自动恢复机制默认恢复时间比较长实测大概要几百毫秒到一秒。如果想缩短恢复时间可以调整sudo ip link set can0 down sudo ip link set can0 up type can bitrate 500000 restart-ms 100把restart-ms设成100总线出问题后100毫秒自动尝试恢复。这种恢复机制只适合非安全关键通道涉及安全功能的CAN通信最好还是设计成停机报警让上位机介入。5.4 问题速查表现象可能原因排查与解决EtherCAT周期偶发毛刺日志落盘触发NVMe中断journald挂tmpfs隔离中断两条总线中一条从站全丢该链路网线/从站电源断检查菊花链物理链路从站WKC异常PDO映射不一致、状态机未到OPethercat pdos对比XML强制切OPCAN总线bus-off终端电阻缺失/总线短路断电量阻值检查CAN_H/CAN_L多路CAN偶发错误帧共地不良或干扰加共地线走屏蔽双绞线加载ec_master后网卡不通NetworkManager抢占网口禁掉NetworkManager管理接口cyclictest延迟整体偏高CPU调频在ondemand调performance绑核隔离文末彩蛋一个总线状态总览脚本既然标题写了文末有彩蛋就把我在项目里一直在用的小脚本放出来。它能在同一屏里看到双EtherCAT主站状态、从站数量、六路CAN的收发错误计数现场调试时直接挂着看比来回敲命令方便太多#!/bin/bash # ecat_can_monitor.sh 总线状态总览 while true; do clear echo EtherCAT Master sudo ethercat master 2/dev/null | grep -E Master|Link state|DC echo ECAT Slaves sudo ethercat slaves 2/dev/null | wc -l echo CAN Errors for i in 0 1 2 3 4 5; do stats$(ip -s -details link show can$i 2/dev/null | grep -E can|ERROR|RX|TX) if [ -n $stats ]; then echo --- can$i --- echo $stats fi done sleep 2 done这个脚本我通常配合tmux在调试终端里跑左边是实时日志右边就是这个监控一目了然。收藏下来下次做RK3588的工控项目直接拿来用。最后再分享一个小技巧调试双EtherCAT时尽量让两条总线的周期错开半个周期比如Master 0在周期起点发帧Master 1在周期中点发帧这样两个网卡的DMA不会在同一瞬间争抢内存带宽。实测下来周期抖动还能再降一些这属于文档里不会写、但实际效果明显的优化手段。
企业数字化 ERP 产品动态
相关推荐
2023攻防演练防守报告模板:从结构设计到自动化生成 简介:2023年攻防演练防守报告模板,主要面向安全运维、应急响应及等保重保人员,用于快速规范地撰写攻防演练期间的防守事件总结。模板以真实攻击链为主线,完整覆盖事件概述、清除代码、攻击路径图示、事件响应处置、溯源反制、原因… · 2026/9/25 2:07:12
VideoDownloadHelper拆解:Chrome Manifest V3扩展架构全解析 VideoDownloadHelper拆解:Chrome Manifest V3扩展架构全解析 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper
VideoDownloadHelper… · 2026/9/25 2:07:12
Windows游戏编程大师源码新编:DirectX老工程Win11移植指南 简介:《Windows游戏编程大师技巧(第二版)》随书光盘中的源码包,面向想真正动手实践经典游戏开发技术的读者,尤其适合刚学完Windows编程基础、希望以完整例子快速理解游戏循环、位图动画、输入响应等核心环节的初学者。… · 2026/9/25 2:07:12
Breach 3靶场实战:从环境搭建到信息收集拿下第一个入口 最近在复盘vulnhub上的Breach 3靶场,把它当成一次完整的实战前演练。说实话,这几年带人入门安全测试,最常被问到的问题不是“漏洞怎么利用”,而是“我连入口都找不到,接下来干什么”。DVWA和Pikachu这类靶场练的是漏洞… · 2026/9/25 3:32:27
机房管理系统源码包复现:反编译、重建数据库与运行排坑 简介:机房管理系统代码文件.zip是一套基于Java的机房管理信息系统源码包,面向需要开发或学习设备管理、上机统计、故障处理等场景的开发者与学生。压缩包共140个文件,体积约5MB,包含30个Java源文件、54个class编译文件、3个SQL脚本… · 2026/9/25 3:32:27
urql populateExchange 深度指南:用 @populate 指令自动填充 Mutation 查询字段 前端 【免费下载链接】urql The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow. 项目地址: https://gitcode.com/gh_mirrors/ur/urql 点击查看 免费下载 populateExchange 是 urql 生态中… · 2026/9/25 3:32:21
全域智能管控平台权限管理:RBAC模型落地与安全管控实践 聊到权限管理,很多人第一反应就是"给谁开通什么功能",似乎建个用户列表再打个勾就完事了。但真正做过安防平台、物联网管控平台或者企业内部中台的人都会明白,权限管理从来不是界面交互问题,而是整个系统的安全底座。尤… · 2026/9/25 3:32:21
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37