☰
Linux下Moxa多串口卡npreal2驱动安装与避坑指南
2026/10/17 9:13:15 网站建设 项目流程

简介:本资源为Moxa RealTTY串口驱动npreal2的Linux内核适配源码包,面向需要在Linux服务器或工控设备上驱动Moxa多串口卡的内核开发者与运维人员。存储库按内核版本划分多个分支,4.x内核对应kernel_4.xx分支,5.x内核对应kernel_5.xx分支,并整合了来自AUR仓库的补丁,可解决新内核下编译失败、proc接口变更等兼容性问题。压缩包共35个文件,约132KB,以C源码与头文件为主体,包含npreal2核心驱动、冗余模块及misc等实现,另附Makefile、VERSION与README等说明文档、多个patch补丁及安装卸载脚本,便于直接编译与部署。目前已有310人学习下载。读者可据此获得完整驱动源码、分内核补丁与排错参考,快速完成Moxa串口卡在4.x/5.x内核上的编译适配与功能验证。

1. 串口设备不识别?先别急着换线,从 npreal2 驱动装起

工控现场最让人头疼的往往不是业务代码,而是系统压根认不到串口卡。一块 Moxa 多串口卡插进工控机,/dev/ttyS*里翻来覆去只有主板自带的两个口,外接的八路、十六路一个都不冒头。这种情况十有八九不是硬件坏了,而是 RealTTY 驱动没装对。npreal2 就是 Moxa 官方为 Linux 提供的 RealTTY 驱动模块,负责把 PCI/PCIe 多串口卡映射成标准 tty 设备节点。它常见于电力监控、轨道交通、自助终端这类需要多路串口并发的场景。装不好,轻则设备号错乱,重则内核模块冲突直接 panic。这篇笔记按我实际部署的流程走一遍,从版本确认到编译加载再到验证,新手能照着跑通,熟手可以对照看参数取舍。

2. 装前把环境摸清:内核版本、编译器和设备型号一个都不能少

2.1 先确认内核头文件和编译工具链

npreal2 是内核模块,编译时强依赖当前运行内核的头文件。很多人上来就make,结果报linux/module.h: No such file or directory,本质就是头文件没装或版本对不上。先跑这几条命令把底摸清:

# 查看当前运行内核版本,注意是 running 不是 installed uname -r # 确认内核头文件目录是否存在,路径必须和 uname -r 完全一致 ls -d /lib/modules/$(uname -r)/build # 检查 gcc 和 make 是否就位 gcc --version make --version

如果/lib/modules/$(uname -r)/build是个死链接或者根本不存在,说明头文件缺失。Debian/Ubuntu 系用apt install linux-headers-$(uname -r),RHEL/CentOS 系用yum install kernel-devel-$(uname -r)。这里有个血泪经验:uname -r带的是 running 内核,而yum默认可能装的是最新 installed 内核的头文件,两者版本号差一位都编译不过。装完再ls一次确认链接指向正确。

2.2 确认 Moxa 卡型号和驱动包版本对应关系

不同代的 Moxa 多串口卡用的驱动包不一样。CP-114、CP-134 这类走 PCI 的老卡和 CP-118E、CP-138E 这类 PCIe 卡,虽然都归在 npreal2 驱动下,但驱动包内的Makefile对内核版本有最低要求。我一般会先lspci | grep -i moxa确认卡被总线识别到了:

# 列出所有 Moxa 相关 PCI 设备,确认卡本身没掉 lspci -nn | grep -i "moxa\|multiport" # 查看驱动包解压后的目录结构,确认有 npreal2 源码 tar -tzf npreal2-x.x.x.tar.gz | head -20

如果lspci都看不到卡,那先别折腾驱动,去 BIOS 里看 PCIe 插槽有没有被禁用,或者换槽位试。驱动包版本建议选比内核版本稍新的,比如内核 4.19 就选驱动包里标注支持 4.19 到 5.x 的那一版。太老的驱动包在新内核上编译会撞上kernel_write之类的 API 变更,报错信息看着像天书,其实就是函数签名对不上。

2.3 关掉可能冲突的旧驱动和串口占用

有些发行版自带8250或serial8250驱动,会抢先占用 Moxa 卡的 I/O 资源,导致 npreal2 加载后设备节点出不来。装之前先看一眼:

# 查看当前已加载的串口相关模块 lsmod | grep -E "8250|serial|moxa" # 如果看到 8250 占用了目标卡,先卸载(临时生效) rmmod 8250 rmmod serial8250

注意rmmod只是临时卸载,重启后会回来。永久屏蔽需要在/etc/modprobe.d/下加黑名单文件,比如blacklist 8250。但这一步要谨慎,如果主板自带的串口也要用,黑名单会把它们一起干掉。我一般只在确认 Moxa 卡和自带串口不共存时才做永久屏蔽。

3. 编译与加载:从源码到 /dev/ttyM* 的完整链路

3.1 解压驱动包并检查 Makefile 关键变量

拿到驱动包后先解压,别急着 make。进去看一眼Makefile里的KERNELDIR和TARGET变量:

tar -xzf npreal2-x.x.x.tar.gz cd npreal2-x.x.x # 查看 Makefile 前 40 行,确认内核路径变量 sed -n '1,40p' Makefile

常见做法是KERNELDIR ?= /lib/modules/$(shell uname -r)/build,如果这行被改过或者写死了别的路径,编译时就会去错误的地方找头文件。我遇到过有人把KERNELDIR指向了/usr/src/linux,结果那个目录是空的,编译报错还以为是驱动包坏了。确认无误后直接:

# 编译驱动模块,-j 后面跟 CPU 核心数加速 make -j$(nproc) # 编译成功后应该生成 npreal2.ko ls -lh npreal2.ko

如果make报错,重点看第一行错误。常见的是implicit declaration of function 'xxx',说明内核 API 变了,需要去驱动包里的源码文件手动改函数名。这种改动一般驱动包发布说明里会提,没有说明就只能对着内核头文件搜替代函数。

3.2 加载模块并确认设备节点生成

编译出.ko文件后,用insmod加载。注意加载顺序,先加载依赖模块再加载 npreal2:

# 加载驱动,注意用绝对路径或 ./ 前缀 insmod ./npreal2.ko # 确认模块已加载 lsmod | grep npreal2 # 查看内核日志最后 20 行,看有没有报错 dmesg | tail -20

加载成功后,dmesg里应该能看到类似npreal2: Moxa RealTTY driver initialized和每个端口注册的信息。然后检查设备节点:

# Moxa RealTTY 驱动生成的设备节点通常是 /dev/ttyM* ls -l /dev/ttyM*

如果/dev/ttyM*一个都没有,先看dmesg有没有register port failed之类的错误。常见原因是 I/O 端口被占用,或者卡上的拨码开关设了不兼容的中断号。PCIe 卡一般不需要手动设中断,但老 PCI 卡可能需要跳线。

3.3 配置开机自动加载和权限持久化

手动insmod重启就没了,得写进开机加载配置。同时串口设备默认权限是root:dialout,普通用户访问不了,需要加 udev 规则:

# 把模块加入开机自动加载列表 echo "npreal2" >> /etc/modules-load.d/npreal2.conf # 把 .ko 文件复制到内核模块目录并更新依赖 cp npreal2.ko /lib/modules/$(uname -r)/kernel/drivers/char/ depmod -a # 创建 udev 规则,让 ttyM* 设备属于 dialout 组且权限 660 cat > /etc/udev/rules.d/99-moxa-npreal2.rules << 'EOF' KERNEL=="ttyM*", GROUP="dialout", MODE="0660" EOF # 重新加载 udev 规则 udevadm control --reload-rules udevadm trigger

这里有个细节:/etc/modules-load.d/里的模块名不带.ko后缀,写npreal2就行。depmod -a是重建模块依赖关系,不跑这一步modprobe可能找不到模块。udev 规则里的KERNEL=="ttyM*"匹配的是内核设备名,不是/dev/下的路径,别写成/dev/ttyM*。

4. 避坑与排查:五个让我加班到凌晨的典型问题

4.1 编译报错 “too many arguments to function”

现象:make时提示某个内核函数参数数量不对,比如kernel_write或access_ok。原因:内核 5.x 之后部分函数签名变了,老驱动包没跟上。解决:去驱动源码里找到报错的文件和行号,对照当前内核头文件里的函数声明改参数。比如access_ok在新内核里从三个参数变成两个,去掉第一个type参数即可。改完重新make。

4.2 加载后 /dev/ttyM* 不出现但 dmesg 无报错

现象:insmod成功,lsmod能看到模块,但设备节点死活不出来。原因:大概率是 udev 没触发或者设备号被其他驱动抢了。解决:先cat /proc/devices | grep ttyM看主设备号有没有注册。如果注册了但/dev下没有,手动mknod一个测试:mknod /dev/ttyM0 c <主设备号> 0。如果手动能创建且能读写,那就是 udev 规则问题,检查规则文件路径和语法。

4.3 重启后模块加载顺序错乱导致串口失效

现象:手动加载一切正常,重启后/dev/ttyM*时有时无。原因:/etc/modules-load.d/里的加载顺序和实际依赖不符,或者 8250 驱动抢先加载。解决:在/etc/modprobe.d/下加blacklist 8250和blacklist serial8250,然后update-initramfs -u更新 initramfs。注意这一步会影响主板自带串口,确认不需要后再做。

4.4 串口能打开但收发数据乱码

现象:/dev/ttyM0能open,但读出来全是乱码。原因:波特率、数据位、停止位不匹配,或者卡上的时钟频率设错了。解决:先用stty -F /dev/ttyM0 -a看当前配置,确认波特率和对端一致。如果配置正确仍乱码,检查 Moxa 卡上的拨码开关是否设了非标准时钟。PCIe 卡一般不需要动拨码,但老 PCI 卡有。

4.5 卸载模块时报 “Device or resource busy”

现象:rmmod npreal2提示资源忙,卸不掉。原因:有进程还占着/dev/ttyM*没释放。解决:lsof /dev/ttyM*找到占用进程,先 kill 掉再rmmod。如果lsof没输出但还是卸不掉,可能是内核线程占着,直接重启最省事。我一般会在卸载前先fuser -k /dev/ttyM*强制释放。

5. 装完怎么验证:用 minicom 和自环测试确认每一路都通

驱动装完、设备节点出来,不代表每一路串口都能正常收发。我习惯用两个手段交叉验证:自环测试和 minicom 对敲。自环测试需要一根杜邦线把串口的 TX 和 RX 短接,然后跑一个简单的读写脚本:

# 配置 ttyM0 为 9600 波特率,8N1 stty -F /dev/ttyM0 9600 cs8 -cstopb -parenb # 后台读 ttyM0,同时往 ttyM0 写数据,自环下应该能读回同样的内容 cat /dev/ttyM0 & echo "npreal2_test_ok" > /dev/ttyM0

如果终端上回显了npreal2_test_ok,说明这一路的收发链路是通的。对多路卡,把ttyM0换成ttyM1、ttyM2逐个跑一遍。注意cat会一直阻塞,测完用kill %1或者pkill cat结束。

更直观的方式是用 minicom 对敲。开两个终端,一个连/dev/ttyM0,一个连/dev/ttyM1,把两个口的 TX/RX 交叉短接(M0 的 TX 接 M1 的 RX,M0 的 RX 接 M1 的 TX),然后在两个 minicom 里互相打字。能互相看到对方输入的内容,就说明两路都正常。minicom 的配置命令是minicom -D /dev/ttyM0 -b 9600,-D指定设备,-b指定波特率。

验证通过后,把自环线拔掉,接上真实设备再测一轮。真实设备那边注意流控设置,如果设备要求硬件流控,stty里要加crtscts,否则数据发一半就卡住。我一般会在部署文档里把每一路的stty配置写死,避免现场人员接错线后反复调参数。

从那以后我每次装完 npreal2,不管多急,都强制走一遍自环加 minicom 对敲,确认每一路都通再交付。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询