在这里插入图片描述

近两年做工业上位机项目,国产化适配已经从可选项变成了硬性门槛。越来越多的制造业客户明确要求,产线控制系统必须支持统信UOS、银河麒麟,同时还要兼容存量Windows工控机,实现一套代码跨系统无缝切换。

最开始我们沿用传统WPF技术栈,一碰到国产化需求就得推倒重写,一个项目光移植就要半个月,现场调试更是坑不断:串口找不到设备、中文显示成方块、无桌面环境启动失败、国产CPU指令集不兼容、权限问题层出不穷。前后踩了20多个生产环境的坑之后,我们基于.NET 8 + Avalonia重构了整套架构,把所有平台差异收敛到底层抽象层,实现了一套代码同时兼容Windows、统信UOS、银河麒麟三大系统,覆盖x86、飞腾、鲲鹏、龙芯全架构,目前已经在5条离散制造产线稳定运行超过8个月。

本文把完整的架构设计、核心实现、部署流程和踩坑清单全部整理出来,所有方案和代码都经过生产环境验证。

一、整体架构:四层解耦,一次编译三端运行

整套架构的核心原则是业务代码零平台感知,所有系统差异、硬件差异、国产环境差异全部下沉到最底层的抽象层,业务开发全程不需要关心运行在哪个系统上。新增国产化系统只需要补充对应实现类,不需要修改任何业务逻辑。
在这里插入图片描述

架构选型上我们做了三个关键决策,直接决定了后续的落地效率:

  1. UI层统一用Avalonia,彻底放弃WPF。WPF只能运行在Windows上,MAUI更偏向消费端移动设备,工业场景的无桌面嵌入式环境、长时运行稳定性、触控交互都不如Avalonia。它支持X11和DRM直出,能直接跑在没有桌面环境的国产工控机上,XAML语法和WPF高度接近,原有代码迁移成本很低。
  2. 采用.NET 8自包含发布。目标机器不需要预装.NET运行时,拷贝发布包即可运行,避免了国产系统下运行时安装、版本兼容的问题,同时支持x64、ARM64、龙芯等全架构。
  3. 所有硬件与系统接口全部抽象。串口、CAN、相机、系统API都定义统一接口,通过依赖注入根据运行平台注入不同实现,业务层完全感知不到底层差异。

二、核心模块的国产化适配实现

2.1 系统API抽象层:抹平三大系统差异

这是跨平台最核心的一层。Windows、统信UOS、麒麟OS在设备命名、路径规则、权限机制、系统配置上差异极大,如果硬编码到业务代码里,换系统必然全面崩溃。

我们定义了统一的平台服务接口,业务层只依赖这个接口,三个系统分别实现:

// 业务层仅依赖此接口,完全不感知具体系统
public interface IPlatformService
{
    // 逻辑端口映射为物理设备名
    string MapSerialPort(string logicalPort);
    // 获取应用数据存储目录
    string GetAppDataDirectory();
    // 设置开机自启
    bool SetAutoStart(bool enable);
    // 检查设备访问权限
    bool CheckDevicePermission(string devicePath);
    // 获取系统与CPU架构信息
    SystemInfo GetSystemInfo();
}

最容易出问题的是串口设备映射和权限。Windows下端口名是COM3,统信和麒麟下是/dev/ttyUSB0/dev/ttyS0,而且默认普通用户没有串口访问权限。实现时需要按平台动态映射,并提前做权限检查:

public string MapSerialPort(string logicalPort)
{
    if (OperatingSystem.IsWindows())
    {
        return logicalPort.StartsWith("COM") 
            ? logicalPort 
            : $"COM{logicalPort}";
    }

    // 统信UOS/麒麟OS 统一按Linux规则映射
    if (int.TryParse(logicalPort.Replace("COM", ""), out int portNum))
    {
        // USB转串口优先匹配ttyUSB,原生串口匹配ttyS
        return portNum < 10 
            ? $"/dev/ttyUSB{portNum - 1}" 
            : $"/dev/ttyS{portNum - 10}";
    }
    return logicalPort;
}

开机自启也是典型的平台差异点:Windows通过注册表实现,统信和麒麟通过systemd服务实现。全部封装在接口内部,业务层只需要调用SetAutoStart(true)即可。

2.2 UI层:国产系统的工业级适配

Avalonia本身跨平台能力很强,但工业场景和国产系统有很多细节需要单独处理,直接用默认配置大概率在现场翻车。

中文字体适配

统信UOS和麒麟OS的嵌入式版本经常缺少完整的中文字体,直接运行会导致中文全部显示为方块。我们的方案是将思源黑体嵌入程序资源,启动时指定默认字体,完全不依赖系统字体:

<!-- App.axaml 全局指定嵌入式中文字体 -->
<Application.Resources>
    <FontFamily x:Key="DefaultFont">
        /Assets/Fonts/SourceHanSansCN-Regular.ttf#Source Han Sans CN
    </FontFamily>
</Application.Resources>
无桌面环境适配

很多国产工控机只安装了最小化系统,没有桌面环境,默认的X11渲染会直接启动失败。Avalonia支持DRM模式直接渲染到帧缓冲,不需要X Server,这是工业嵌入式场景的核心能力:

// Program.cs 跨平台入口
public static int Main(string[] args)
{
    var appBuilder = BuildAvaloniaApp();
    
    if (OperatingSystem.IsLinux() && !args.Contains("--windowed"))
    {
        // 统信/麒麟无桌面环境,启用DRM直出
        return appBuilder.StartLinuxDrm(args, new DrmOutputOptions
        {
            // 适配国产触摸屏旋转
            Orientation = DrmOrientation.Landscape,
            // 自动匹配主显示设备
            SelectCard = cards => cards.First()
        });
    }
    
    return appBuilder.StartWithClassicDesktopLifetime(args);
}
工业触摸屏适配

国产工控触摸屏普遍存在DPI不标准、触摸坐标偏移、戴手套操作误触等问题。我们统一扩大了按钮点击热区,关闭了系统级触摸手势,同时针对DRM模式下的屏幕旋转做了坐标校准,确保点击位置和显示位置完全一致。

2.3 硬件通信层:国产化全兼容

工业上位机离不开串口、CAN、PLC通信,这也是国产化适配最容易踩坑的部分。

  • 串口通信:统一使用System.IO.Ports.SerialPort,在统信和麒麟下需要将运行用户加入dialout用户组,避免每次都要用root权限启动。同时封装了端口扫描功能,自动识别可用串口。
  • CAN总线:Windows下使用周立功、研华等厂商SDK,统信和麒麟下使用原生SocketCAN,统一封装为ICanService接口,业务层只收发标准CAN报文。
  • OPC UA:使用OPC Foundation官方跨平台库,Windows和国产系统完全通用,针对汇川、禾川、信捷等国产PLC做了适配,解决了国产系统下证书信任的问题。
  • Modbus TCP/RTU:基于NModbus封装,跨平台无差异,支持串口和以太网两种方式。
  • 工业相机:海康、大恒、Basler等主流相机都提供了统信和麒麟的ARM64/x86版本SDK,统一封装为ICameraService,业务层不需要关心具体厂商。

2.4 运行时与依赖避坑

国产化环境下有几个高频崩溃点,几乎每个项目都会碰到:

  1. 彻底移除System.Drawing.Common。微软已经停止了它的跨平台支持,在统信和麒麟下运行会直接抛出GDI+异常。所有图像处理全部替换为SixLabors.ImageSharp或OpenCVSharp。
  2. 原生库指令集兼容。ONNX Runtime、OpenCV等原生库默认使用AVX2指令集,在飞腾、龙芯等国产CPU上会直接报“非法指令”错误。需要选用对应架构的原生库,或者降级到支持SSE/通用指令集的版本。
  3. 路径大小写敏感。Windows不区分大小写,统信和麒麟严格区分。所有文件路径统一使用小写,避免硬编码,全部通过Path.Combine拼接。
  4. 数据库适配。轻量场景用SQLite,需要信创验收的场景替换为达梦、人大金仓等国产数据库,通过EF Core统一封装,业务层代码不需要修改。

三、三端部署与上线流程

采用.NET自包含发布模式,三个系统使用同一套源代码,分别发布对应运行时即可,不需要做任何代码修改。

发布命令

# Windows x64 发布
dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true

# 统信UOS x64 发布
dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true

# 银河麒麟 飞腾/ARM64 发布
dotnet publish -c Release -r linux-arm64 --self-contained true -p:PublishSingleFile=true

统信UOS/麒麟OS部署步骤

  1. 将发布包拷贝到/opt/industrial-hmi/目录;
  2. 给可执行文件添加执行权限:chmod +x IndustrialHmi
  3. 将运行用户加入dialoutvideo用户组,获取串口和DRM显示权限;
  4. 配置systemd服务,实现开机自启、崩溃自动重启、日志重定向;
  5. 无桌面环境下直接运行,DRM模式会自动输出到工业触摸屏。

国产化验收注意事项

  • 程序不依赖Windows专属组件,所有依赖均为开源或国产化组件;
  • 支持国产CPU架构,提供兼容适配报告;
  • 配置日志审计、权限控制,满足等保和信创要求;
  • 数据存储优先使用国产数据库,提供数据迁移方案。

四、生产环境高频踩坑清单

跨平台国产化的坑90%都出在细节上,开发环境很难复现,到了现场才集中爆发。这里整理了出现频率最高、影响最大的10个坑:

坑点现象根因解决方案
中文显示方块统信/麒麟下界面中文全部变成方框系统缺少对应中文字体,程序依赖系统字体嵌入思源黑体,全局指定自定义字体
串口找不到设备启动报端口不存在,打开失败设备名规则不同,普通用户无访问权限按平台动态映射端口,用户加入dialout组
无桌面启动失败双击程序无反应,日志报X11错误默认使用X11渲染,系统没有X Server启用Avalonia DRM模式,直接渲染到帧缓冲
启动报非法指令国产CPU下程序直接崩溃原生库使用AVX2指令集,国产CPU不支持替换为对应架构的原生库,使用兼容指令集
GDI+异常崩溃运行图像处理功能时抛出异常使用了System.Drawing.Common,Linux不支持全部替换为SixLabors.ImageSharp或OpenCVSharp
文件路径找不到读取配置、日志时报文件不存在Linux大小写敏感,Windows下正常统一使用小写路径,避免硬编码
开机自启失效重启后程序不自动启动Windows注册表权限不足,Linux systemd配置错误统一封装接口,Linux下配置正确的服务单元
OPC UA连接失败能ping通但连接不上国产系统下证书信任机制差异关闭不必要的证书验证,或导入根证书
触摸屏点击偏移点击位置和实际位置不一致DRM模式下屏幕旋转,触摸坐标未同步配置DrmOutputOptions.Orientation,自动校准坐标
长时间运行内存泄漏运行几天后内存持续上涨频繁创建原生对象,未释放非托管资源复用缓冲区,全局单例通信对象,及时释放原生资源

五、三端性能实测

我们在同配置x86工控机(i5-12400、16G内存)上,分别测试了Windows 10 IoT、统信UOS 1060、银河麒麟V10的运行表现,同时补充了飞腾D2000平台的麒麟系统测试数据。

指标Windows 10 IoT统信UOS 1060银河麒麟V10 x86银河麒麟V10 飞腾D2000
程序启动耗时1.1s1.4s1.3s2.1s
稳态内存占用128MB135MB132MB168MB
串口通信延迟<1ms<1ms<1ms<2ms
UI响应时间<10ms<15ms<12ms<20ms
72小时内存增长+7MB+9MB+8MB+12MB

从测试结果看,x86架构下三个系统的性能差异在10%以内,完全满足工业现场的实时性要求。飞腾ARM平台的启动和响应稍慢,但也在可接受范围内,搭配国产GPU加速后还能进一步提升。

六、总结

这套架构最大的价值不是“能跑在国产系统上”,而是把跨平台和国产化的复杂度全部收敛到底层,业务开发人员完全不需要关心平台差异。原来一个国产化移植项目需要半个月,现在只需要发布对应架构的包,现场部署调试1-2天就能上线,项目交付周期缩短了60%以上。

后续我们还在两个方向持续优化:一是针对飞腾、龙芯、鲲鹏等国产CPU做指令集和内存优化,进一步提升性能;二是适配更多国产PLC、相机、采集卡,完善国产化硬件生态。如果你的项目也面临国产化改造、多系统兼容、老系统迁移的问题,这套架构可以直接参考落地。

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐