首页 / 资讯中心 / 文章详情

Linux下Moxa多串口卡npreal2驱动安装与避坑指南

Linux下Moxa多串口卡npreal2驱动安装与避坑指南 ★ FEATURED ARTICLE
简介本资源为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 KERNELttyM*, GROUPdialout, MODE0660 EOF # 重新加载 udev 规则 udevadm control --reload-rules udevadm trigger这里有个细节/etc/modules-load.d/里的模块名不带.ko后缀写npreal2就行。depmod -a是重建模块依赖关系不跑这一步modprobe可能找不到模块。udev 规则里的KERNELttyM*匹配的是内核设备名不是/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 的 RXM0 的 RX 接 M1 的 TX然后在两个 minicom 里互相打字。能互相看到对方输入的内容就说明两路都正常。minicom 的配置命令是minicom -D /dev/ttyM0 -b 9600-D指定设备-b指定波特率。验证通过后把自环线拔掉接上真实设备再测一轮。真实设备那边注意流控设置如果设备要求硬件流控stty里要加crtscts否则数据发一半就卡住。我一般会在部署文档里把每一路的stty配置写死避免现场人员接错线后反复调参数。从那以后我每次装完 npreal2不管多急都强制走一遍自环加 minicom 对敲确认每一路都通再交付。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站