news 2026/10/1 16:27:54

树莓派变工业控制器:BL460如何打通PLC与Linux生态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
树莓派变工业控制器:BL460如何打通PLC与Linux生态

第一次拿到BL460的时候,我以为是某个同行给产品起的内部代号。直到拆开外壳,看到里头的核心板是树莓派CM4,才意识到这是个很有意思的形态:它把树莓派的生态彻底“工业化”了——不是一块开发板,而是一台可以直接装进配电柜、卡在DIN导轨上的整机。这篇文章就拿BL460当靶子,聊聊这类“面向树莓派生态的工业级控制器”到底解决了什么问题、硬件软件怎么组织、现场怎么部署,以及哪些人其实不该买。

这几年找我咨询的场景很典型:设备厂想给旧产线加数据采集,但PLC自带的上位机软件贵、封闭;想直接用树莓派4B去现场,又担心供电、静电、RS485通信不稳定,老板一看裸露的板子和快递盒一样的壳子就不批经费。BL460这类产品正是在这个空档里长出来的——保留树莓派的软件生态,把供电、隔离、通讯、外壳、安装这些都做成“工业公差不”。至于它算不算真正的工业级,值不值得用,看完下面的拆解,你自己就会有判断。

1. 为什么“树莓派生态+工业级”这个组合会成立

1.1 树莓派开发板的“玩具感”从哪来

树莓派本身已经很稳了,尤其树莓派4B和5这两代,CPU性能、内存容量都在向入门x86看齐。但客户不会只看性能,他们一定会问三个问题:这板子怎么装进配电柜?坏了怎么换?能不能7x24小时跑一年?这不是刁难,而是正经的工程问题。裸树莓派有几个先天的“玩具感”:只有一个USB-C/Type-C的5V输入,现场可没有这种电源;40pin排针直接裸露,信号没有任何隔离防护;microSD卡在高温和振动环境里容易掉数据;外壳要么没有,要么是官方那两个塑料壳,没法锁在导轨上。用是能用,但每个项目都靠自己去做外围电路和结构件,开发周期就失控了。

我不是说树莓派不能上工业项目。我见过有人用树莓派4B做设备状态监测,板子用扎带绑在导轨上,电源是淘宝买的山寨DC-DC,串口用杜邦线引出来,最后也跑了大半年。但那种方案只有一个人维护的时候没问题,一旦要交付、要验收、要多发几十台,所有“临时凑合”都会变成事故隐患。BL460这类产品想解决的,恰恰是把这些“凑合”变成标准品。

1.2 现场设备缺的是一个“会跑Linux的PLC”

传统PLC确实稳定,但它解决的是逻辑控制和实时性,不是数据采集和业务逻辑。想从PLC里把数据拿出来,通常要走OPC服务器、专用网关或者厂商私有协议,这些组件在项目里都是额外的预算和调试成本。PLC上的高级语言能力弱,想在上面跑Python、Node-RED、MQTT客户端,基本不现实。而现场的新需求是:把Modbus仪表的数据读上来、做点计算、打包成MQTT消息上云,同时还要能处理本地的继电器输出。

这套事用PLC做非常别扭,用裸树莓派做又太“野”。BL460这一类产品,本质上是把两者拼到一起:底层跑完整的Linux,上层提供PLC常用的通信和IO接口,再加上一个软件PLC运行时,让电气工程师也能用梯形图写逻辑。程序员管数据链路,电气工程师管设备逻辑,两边各干各擅长的,这是它和纯开发板最大的区别。

1.3 BL460的产品定位:不是替代PLC

如果非要用一句话给BL460定位,我会说它是一台边缘控制器:实时性要求高的逻辑控制交给PLC,它负责数据采集、协议转换、边缘计算、轻量控制和远程运维。拿车间打个比方,PLC是那个必须手快、手稳的老师傅,BL460是站在旁边的助理,负责记录每一次操作、发现问题、打电话给总部汇报。老师傅不能随便换,但助理能省下大量沟通成本。

这个定位决定了它不该去跟PLC比毫秒级响应,它更适合做数据密集、连接密集、需要频繁改业务逻辑的场合。想清楚这一点,后面所有选型判断都会变得简单。

2. 硬件拆解:BL460为什么敢把“工业级”三个字挂身上

2.1 核心板选型:CM4与整板树莓派的区别

先说明,我不是在给某个具体厂商写软文。BL460更像是一类产品线的代称,不同厂家的命名和接口都不一样,但核心逻辑一致。这类面向树莓派生态的工业控制器,核心板几乎清一色是树莓派Compute Module 4(CM4),而不是树莓派4B/5整板。原因很直接:整板自带USB、HDMI、音频口这些工业现场用不上的接口,体积大,固定孔位是给消费类外壳准备的。CM4是一个SoC模块,内存和eMMC都在模块上,通过两个连接器插到载板,载板想怎么设计就怎么设计。

这就像自己攒台式机,你不买整机,而是买CPU套装,然后主板、供电、机箱全部按需求定制。CM4分eMMC版本和无eMMC版本,工业现场我强烈建议用eMMC版本,eMMC不像SD卡那样受接触不良和氧化影响。无线版本自带2.4GHz/5GHz Wi-Fi,但很多工厂对无线有顾虑,选型时按需购买就行,也可以选带4G/5G模块的版本。有人问为什么不干脆用树莓派400,那个键盘整机性价比高,但键盘机身这个形态太占地方,散热和接口布局也不是为嵌入式准备的。

2.2 载板上那些普通用户不会注意的“工业细节”

BL460和裸树莓派真正的差距不在核心板,在载板。载板决定了它能接什么设备、扛得住什么环境。我见过的这类产品,典型接口配置大致是这样:

功能模块常见规格为什么需要
供电输入24V DC宽压,带反接保护和保险丝现场标配24V,宽压防电压波动
隔离串口1~2路RS485/RS232,光电隔离应对电机启动时的干扰脉冲
数字量IO4~16路DI/DO,光耦隔离接限位开关、光电开关、继电器
网络接口1~2路千兆/百兆,可选PoE供电同时连内网和上云网络
扩展接口CAN、M.2、mini-PCIe接伺服/步进设备、4G/Wi-Fi模块
安装方式DIN导轨卡扣、金属外壳直接装进配电柜

工业现场不会给你干净稳定的USB电源,也不会只用一根网线。传感器仪表最常见的就是两线制RS485,阀门和接触器要靠DO去驱动,限位开关和光电开关要进DI。所以“有没有隔离”很关键:没隔离的RS485在电机启动时很容易通信乱码,光耦隔离能在几十毫秒的干扰脉冲下保住数据完整性。这个细节是最容易被只看参数的人忽略的。

2.3 外壳、安装与散热:无风扇的代价

这类控制器通常是一体成型金属外壳,或者是阻燃ABS外壳,两侧带DIN导轨卡扣,可以直接卡在配电柜的标准导轨上。外壳不只是为了好看,它要承担屏蔽和散热任务。CM4在高负载下发热不小,纯无风扇方案要做整机被动散热——把SoC的热量通过导热垫引导到外壳翅片上。

我的经验是:别选那种“板子裸奔、外壳封闭得严严实实”的机型,要选有翅片、有气流通道的金属壳。车间配电柜夏天温度经常超过40度,无风扇整机放到柜子角落里,连续跑几天就可能触发过热降频。如果实在压不住,再考虑加一个温度控制的小风扇,理想状态是核心温度到65度再启动,别一开机就满速转。

3. 软件栈:一块树莓派怎么变成“会听话的工控设备”

3.1 系统镜像与基础适配

这类整机出厂一般预装了定制镜像,通常是Raspberry Pi OS Lite(不带桌面),工业现场要桌面环境干嘛?省内存、少挨攻击面才是正事。如果是裸机或者想重刷,直接从官网下载Raspberry Pi OS Lite。注意,先别装Ubuntu桌面版,尤其是树莓派5装Ubuntu听起来很酷,但第三方Ubuntu镜像对CM4载板上的设备树支持不一定齐全,工业上求稳,先用官方镜像或者厂商定制的Yocto发行版。

换源是必做动作。国内访问默认源慢到让人怀疑人生。标准操作是备份 /etc/apt/sources.list,把 raspbian.raspberrypi.org 替换成清华或中科大镜像。新版系统还有一个 /etc/apt/sources.list.d/raspi.list,别漏改。顺手把时区、SSH、静态IP都定下来。还有个小建议:除非调试需要,否则把蓝牙和Wi-Fi关掉。很多工业控制器默认就不开无线,一是稳定,二是给电磁兼容减少变量。

3.2 软PLC与实时性:电气工程师和程序员怎么协作

Linux实时性一直是被质疑的点。事实是,现代内核都支持PREEMPT_RT实时补丁,打上之后上下文延迟能压到几十微秒级别。注意,是几十微秒,不是硬PLC的几百纳秒。所以BL460做不了高精度伺服运动控制,但做普通设备逻辑、数据采集、IO联动,完全够用。

电气工程师和程序员的思维差异很大。电气工程师习惯梯形图或ST脚本,程序员习惯Python和Node。很多这类控制器的软件栈里会集成一个软PLC运行时,开源的OpenPLC、商业的Codesys都能在树莓派生态里跑。你在浏览器里拖一拖梯形图,下载到设备里就能跑,同时还能和Python脚本共享变量。这个能力很重要——它决定了你的项目里能不能同时站两个角色:电气工程师去写设备逻辑,程序员去写数据管道和上云流程。

3.3 协议栈与边缘计算:生态才是杀手锏

软件上真正的杀手锏是生态。Modbus RTU/TCP、CANopen、MQTT、InfluxDB、Grafana、Node-RED、Python的Modbus库,这些都不用你自己从零写。比如Node-RED自带Modbus节点和MQTT节点,可视化连线就能拼出一个采集流:Modbus读温度 → JSON格式化 → MQTT发布 → InfluxDB存储 → Grafana展示,整个过程都在一块板上完成,不需要额外买协议转换网关。

这种模式对一个数据采集项目来说,省掉的不光是网关硬件钱,还有调试时间。以前用串口服务器+DTU那套玩法,每个点位都要写文档、配映射表;现在Node-RED里拉两根线就解决。而且树莓派生态里随便一个库都能拿来用,比如用Python写一个自定义采集脚本,然后通过systemd守护进程拉起,稳定性和开发效率都比从零画C++框架高不少。

3.4 传感器、运动控制与AI视觉的接入

有人喜欢拿ADXL345加速度传感器做振动检测,拿OV5647摄像模组做视觉定位,甚至拿树莓派Pico去做舵机控制子节点,这些都可以挂到BL460的统一底座下。ADXL345走I2C或SPI,OV5647直接接CSI口,Pico通过RS485或CAN作为执行末端。这套组合可以组成一个“感知-执行-决策”的边缘节点。

但说实话,树莓派CM4的GPU算力跑YOLOv5这种模型只能说是“能跑”,帧率不会好看。OpenCV装起来容易,pip install opencv-python-headless就行。如果你要在现场做轻量物体识别,建议用MobileNet这类轻量化模型,或者把图像抓取线程放在本地,推理放服务器。工业视觉不是靠一块板子硬扛的,而是靠分层架构。

4. 实操:从零把一个Modbus温度传感器接到云端看板

4.1 准备清单与接线

目标很具体:用一台BL460,通过RS485读取一个Modbus RTU温湿度变送器,数据推送到本地Web看板,同时上云。物料:一台BL460、24V直流电源、一个支持Modbus RTU的温湿度变送器(从站地址设为1,波特率9600)、一台路由器、一台电脑。接线时认准A/B两个端子,接反了通信是没有任何反应的,把A接A、B接B,别把助力电的24V弄到信号线上,烧板子多半是这个原因。

4.2 系统初始化与换源

用Raspberry Pi Imager写系统时,在高级设置里直接开启SSH、设置用户名和密码、配好Wi-Fi,这一步能用好,后面能省很多事。写好后上电开机,通过SSH登录。登录后第一步是系统更新和换源:

# 备份原有源 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak # 以清华源为例,替换镜像站 sudo sed -i 's|http://raspbian.raspberrypi.org/raspbian/|https://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/|g' /etc/apt/sources.list sudo apt update && sudo apt upgrade -y

注意,新版系统还有个 /etc/apt/sources.list.d/raspi.list,也一并用sed替换成镜像站对应地址。如果版本升级太狠,建议保持bookworm不动,工业设备追新不是好事,尤其是内核和固件,稳定了就别乱升级。

4.3 用Python测试RS485和Modbus

把RS485线接到BL460的隔离COM口后,先确认设备节点名。常见的是/dev/ttySC0、/dev/ttyAMA0这类。查一下:

ls -l /dev/tty*

然后在Windows上用MobaXterm连上去,写个简单Python脚本读寄存器。这里最容易被绕晕的是Modbus寄存器地址:手册里写40001的保持寄存器,协议报文里地址要填0,因为它是从0开始编号的。温湿度变送器通常把温度放在保持寄存器0,湿度在寄存器1,数据放大10倍。用pymodbus读取:

from pymodbus.client.sync import ModbusSerialClient client = ModbusSerialClient( port='/dev/ttySC0', # 以实际设备名为准 baudrate=9600, parity='N', stopbits=1, bytesize=8, timeout=2 ) client.connect() # 读保持寄存器,从地址0开始,读2个寄存器,从站地址1 rr = client.read_holding_registers(address=0, count=2, slave=1) if not rr.isError(): registers = rr.registers print("温度: %.1f ℃, 湿度: %.1f %%" % (registers[0] / 10.0, registers[1] / 10.0)) client.close()

第一次能打印出正确的温度值时,整个项目的技术风险就拆掉一半了。后面的逻辑都是在这条数据链路上做文章。

4.4 用Node-RED把数据推到MQTT

Node-RED适合快速搭可视化流。安装:

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-install-script/master/install-node-red.sh) sudo systemctl enable --now nodered

浏览器打开 http://<BL460的IP>:1880,拖一个Modbus Read节点、一个function节点、一个MQTT输出节点。function节点用来组装JSON消息:

var msg = {}; msg.topic = "sensor/temp_humi"; msg.payload = { temperature: context.temp, humidity: context.humidity, timestamp: Date.now() }; return msg;

配好MQTT Broker地址和主题后,点Deploy,数据就出去了。本地想看实时曲线,Node-RED Dashboard节点里拖一个gauge和一个chart,两分钟就能出一个车间看板。

4.5 上云与远程运维的常见套路

本地看板只在车间内网有用,远程看板要靠云。我常用的套路是:BL460 → MQTT over TLS → 云上的EMQX或Mosquitto → Prometheus + Grafana做监控看板。MQTT必须开鉴权,证书最好双向认证,别把数据裸奔在公网上。这一步很多新手会忽略,等到数据被扫到了才慌,不如一开始就配好。

5. 现场最容易踩的坑与排查技巧实录

5.1 TF卡的坑与完整克隆方案

工业现场最大的数据丢失事故源,不是电源,不是程序bug,是TF卡。廉价TF卡在高温、振动、频繁写入的情况下,几个月就能磨掉寿命。选卡至少A2/U3级别,选工业卡更好;能上eMMC版本就上eMMC,从根源上掐掉接触不良的毛病。如果非要用TF卡做系统盘,把日志挂到tmpfs(内存文件系统),减少写放大,能明显延长卡寿命。

“把树莓派400的TF卡内容完整复制到另一张更大更快的卡”这个问题,我经常被问到。原理对所有树莓派都一样,不只是树莓派400。在Linux里最直接的方法是dd整卡镜像:

# 查看盘符,确认谁是旧卡、谁是新卡 sudo fdisk -l # 备份旧卡,假设旧卡是 /dev/sdb sudo dd if=/dev/sdb of=~/pi_backup.img bs=4M status=progress # 换上新卡,假设新卡是 /dev/sdc sudo dd if=~/pi_backup.img of=/dev/sdc bs=4M status=progress

dd是按物理扇区复制的,所以新卡容量会被识别成旧卡一样大。写入后需要扩展根分区,把剩余空间用上:

sudo raspi-config --expand-rootfs # 或者手动方式 sudo growpart /dev/mmcblk0 2 sudo resize2fs /dev/mmcblk0p2

Windows下用Win32DiskImager也可以做同样的事:先“Read”生成img,再“Write”到新卡。写完新卡如果Windows提示“需要格式化”,千万不要点,那只是它不认识Linux分区的正常反应。dd前先拔掉所有无关U盘,确认盘符无误再操作,写错盘后悔都来不及。

5.2 SSH连不上、密码不对的排查顺序

SSH问题是树莓派新手的重灾区。我的排查顺序永远不会变:网络通不通 → SSH服务开没开 → 防火墙 → 用户名密码 → 密钥权限。新版树莓派OS镜像默认关闭SSH,除非你在Raspberry Pi Imager高级设置里提前勾选开启。已经烧好的卡,最简单的方法是重新用一个读卡器挂载SD卡,或者干脆用Imager重新烧一遍并在高级设置里配好SSH。

忘了密码更简单,把卡插到电脑上,打开根目录的cmdline.txt,在末尾加一句 init=/bin/sh,插回机器启动就能进shell改密码,改完把这句话删掉。Windows环境下我习惯用MobaXterm,一个软件同时搞定SSH终端和SFTP传输,比来回切工具舒服太多。注意用户名默认是pi或你新设置的user,root默认没有密码,新手一上来就用root登录自然会报错。

5.3 串口权限与引脚图的坑

访问串口报Permission denied,是用户不在dialout组里。把自己加进去,重登即可:

sudo usermod -a -G dialout $USER

树莓派的GPIO编号还要区分物理引脚和BCM编号,引脚图上标的是物理位置,程序中用的是BCM编号,新手在这上面犯迷糊很正常。如果你用的是工业载板,通常已经把GPIO映射成数字量输入输出,直接通过设备驱动或Modbus寄存器操作就行,不需要自己碰GPIO。反而是在裸树莓派上做原型验证的时候,40pin排针的引脚图要常备一张,我手机里一直留着一张。

5.4 散热、看门狗与长时间运行稳定性

工业设备要7x24小时跑,进程卡死怎么办?硬件看门狗必须安排。很多载板上会带看门狗芯片,Linux下对应/dev/watchdog,运行wdctl能看到状态。程序一旦死锁或系统卡住,看门狗会在几十秒内强制重启,比人工去现场断电强一百倍。如果设备需要频繁重启保持工作,就把看门狗的超时时间、重启策略都测一遍。

风扇转速控制也是踩坑点。三线风扇直接接5V和GND会满速转,噪音大、寿命短。想安静点就用一个GPIO PWM脚控制MOS管,比如GPIO18或GPIO12这样的硬件PWM引脚,配合一个NPN三极管加一个100欧电阻就能驱动小风扇。树莓派5开始标配风扇排针,但CM4载板不一定有,自己接的话注意电流上限,别从一个5V引脚上硬抽大电流,烧了PMIC就麻烦了。

6. 选型:什么项目适合上BL460,什么场景不如买PLC或工控机

6.1 一张表对比四种方案的边界

维度BL460(树莓派生态工业控制器)裸树莓派4B/5传统PLC高性能IPC/工控机
工业接口与供电24V直接入,接口齐需要自己做外围电路自带IO和总路线需要配扩展卡
实时性软实时,一般逻辑够用弱,依赖裁板强,适合硬逻辑一般,依赖Windows/Linux
软件生态树莓派生态+Node-RED同样开放但难工程化封闭、图形库贵应用生态成熟
安装与散热DISC导轨金属壳改造麻烦标准导轨安装体积大、功耗大
典型价格档1000~3000元几百元视点数几千到几万5000元以上
适合的团队有Linux基础+懂工控个人DIY、原型纯电气项目大型上位机系统

别只看价格,裸树莓派看着便宜,算上你自己画载板、做外壳、调EMC、测试老化的时间,成本早超过买整机了。工程项目的成本不只是BOM账单,还有出错的机会成本。

6.2 四个适合上BL460的场景

第一类,旧产线数据采集改造。几十台旧设备没有联网,电机、仪表、传感器都是零散信号,用BL460做旁路采集,不影响原PLC控制,项目风险最低。第二类,小型过程控制与环境监测。冷库、种植大棚、实验室、污水处理站,传感器多且协议杂,需要本地边缘计算和远程上云的联动。第三类,教学科研实训。一个平台可以同时教Python、Modbus总线、Node-RED、视觉基础,学生能在一台设备上看到“从传感器到云平台”的完整链路。第四类,快速原型验证。给客户做POC样机,用树莓派生态两三天就能出效果,比定制硬件方案快得多。

6.3 三种不适合直接上的情况

需要高确定性的伺服控制和安全回路,比如机器人关节联动、安全光幕急停,这些老老实实上专用PLC或安全PLC,别拿Linux开这种玩笑。军工宽温、强腐蚀、剧烈振动这种苛刻环境,树莓派生态还没到那一步。如果只是个人玩树莓派小车、搞智能家居,也用不上BL460,树莓派4B/5开发板顺手得很,无非就是没有工业级接口罢了。项目在哪个赛道,就用哪个赛道的工具,硬跨赛道付出的成本远高于收益。

6.4 选型经验:先跑通流程再采购整机

我个人的意见是,第一次接触这类产品,别急着批量买。先拿手头现有的树莓派4B把Modbus采集、Node-RED、MQTT上云这条链路跑通,跑通之后再考虑买整机做现场试点。买回来也别直接上线,先做一轮通电老化测试、串口长时间通信测试、MQTT丢包率测试,再插到真实配电柜里跑一周。

这个“流程先行、硬件后买”的方法能帮你省下不少冤枉钱。等你在真实现场里体会过一次临时断电后自动重启、一个模块烧掉后现场换板、一个干扰导致通信乱码但系统没有彻底挂掉的经历,你对“工业级”这三个字的理解会比我写一万字都深刻。

最后再分享一个小技巧:不管最后选了哪家的产品,一定确认它做过EMC测试和老化测试,而不是只看原理图看起来不错。这类面向树莓派生态的工业级控制器,本质上是用工程化的服务换了开放生态的福利,只要用对场景,它确实能给传统工控带来一股新鲜劲。祝一次点亮。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 16:27:10

HER算法解析:用后见之明经验回放破解稀疏奖励难题

我在调机械臂抓取任务时&#xff0c;最崩溃的不是写环境代码&#xff0c;而是给自己挖了一个大坑——把任务奖励设成“抓取成功才有 1&#xff0c;否则 0”。模型跑了大半天&#xff0c;成功率一直趴在 1% 出头&#xff0c;回放池里堆满了失败的 transition&#xff0c;跟石头一…

作者头像 李华
网站建设 2026/10/1 16:26:58

OFD文件前端预览实战:从解析原理到Vue3组件封装

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

作者头像 李华
网站建设 2026/10/1 16:26:21

从回形针最大化器到AI对齐:目标错位为何如此危险

paperclip 这个词最近在 AI 圈几乎成了“目标错位”的代名词。我那天收拾办公桌&#xff0c;从抽屉里翻出一盒回形针&#xff0c;忽然想起那个著名的思想实验&#xff1a;如果最聪明的 AI 被设定成“尽可能多地制造回形针”&#xff0c;它最终会不会为了造回形针把人类消灭&…

作者头像 李华
网站建设 2026/10/1 16:25:55

换热器PI参数智能整定:四种优化算法的MATLAB实现

说实话&#xff0c;换热器这东西&#xff0c;看着就是一根管子进、一根管子出&#xff0c;温度到了就行。可真要把出口温度的PI控制做到稳、快、准&#xff0c;几乎每个做过程控制的人都被它折腾过&#xff1a;大惯性、纯滞后、负载变化频繁&#xff0c;常规的Ziegler-Nichols整…

作者头像 李华
网站建设 2026/10/1 16:25:51

Linux时钟中断全链路:从硬件脉冲到tickless与调试

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

作者头像 李华