linux_learn/learn/NPU/01-NPU硬件与驱动基础.md

7.9 KiB
Raw Blame History

01 — NPU 硬件架构与驱动基础

一、RK3568 NPU 硬件架构

1.1 整体结构

RK3568 SoC 内部
┌──────────────────────────────────────────────────────┐
│  CPU 子系统 (4×Cortex-A55)                           │
│  ┌──────────────────────────────────────────────┐   │
│  │  Linux 应用层 (你的保护程序)                    │   │
│  │       │                                       │   │
│  │       ▼ rknn_api.h (librknnrt.so)            │   │
│  │  ┌─────────────────────────────────────┐     │   │
│  │  │  RKNN Runtime (用户态驱动)           │     │   │
│  │  │  - 模型加载/解析                      │     │   │
│  │  │  - 内存管理 (DMA buffer 分配)         │     │   │
│  │  │  - 任务提交/同步                      │     │   │
│  │  └──────────────┬──────────────────────┘     │   │
│  └─────────────────┼────────────────────────────┘   │
│                    │ ioctl()                         │
│  ┌─────────────────▼─────────────────────────────┐  │
│  │  NPU 内核驱动 (drivers/rknpu/)                │  │
│  │  - 电源/时钟管理                               │  │
│  │  - 中断处理 (推理完成通知)                     │  │
│  │  - MMU (NPU 有自己的 IOMMU)                   │  │
│  └──────────────────┬───────────────────────────┘  │
│                     │ AXI 总线                      │
│  ┌──────────────────▼───────────────────────────┐  │
│  │  NPU 硬件 (3 个 NPU 核心)                     │  │
│  │                                               │  │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐     │  │
│  │  │ NPU Core0│ │ NPU Core1│ │ NPU Core2│     │  │
│  │  │ • MAC阵列│ │ • MAC阵列│ │ • MAC阵列│     │  │
│  │  │ • 卷积加速│ │ • 卷积加速│ │ • 卷积加速│     │  │
│  │  │ • 本地SRAM│ │ • 本地SRAM│ │ • 本地SRAM│     │  │
│  │  └──────────┘ └──────────┘ └──────────┘     │  │
│  │                                               │  │
│  │  合计: 1 TOPS (INT8), 192 INT8 MAC/cycle      │  │
│  └───────────────────────────────────────────────┘  │
│                                                      │
│  DDR (共享内存, NPU 通过 IOMMU 访问)                  │
└──────────────────────────────────────────────────────┘

1.2 关键硬件特性

特性 说明 对波形识别的影响
3 个独立 NPU 核心 可并行执行 3 个不同任务 可以同时跑故障识别 + 谐波分析
每核本地 SRAM 减少 DDR 访问延迟 小模型可能完全放在 SRAM 里
专用卷积加速器 卷积+激活+池化 硬件流水线 1D-CNN 推理极快
支持非对称量化 INT8 输入/输出INT32 累加 模型压缩 4×精度损失 < 0.5%
IOMMU NPU 看到连续地址,物理上可以不连续 不需要预留大块连续内存

1.3 NPU 适合的算子

✅ 完全支持 (NPU 硬件原生):
  Conv2D, DepthwiseConv2D, FullyConnected
  AveragePool, MaxPool, GlobalAveragePool
  ReLU, ReLU6, Sigmoid, Tanh
  BatchNorm (可融合到 Conv 中)
  Concat, Reshape, Transpose, Slice

⚠️ 有限支持 (可能回退到 CPU):
  LeakyReLU (仅部分版本), Softmax (仅末层)
  LSTM/GRU (支持不完善,量化损失大)

❌ 不支持 (无法在 NPU 上运行):
  动态 shape 算子, 自定义算子
  RNN 复杂变体, Attention (Transformer 需要 RKNN 2.0+)

对你的波形识别模型的影响:选择 1D-CNN 而非 LSTM/Transformer就是因为 CNN 的算子 NPU 原生支持最优。


二、驱动环境搭建

2.1 确认 NPU 驱动已加载

# 1. 检查 NPU 设备节点
ls -la /dev/rknpu
# 预期输出: crw-rw---- 1 root root 10, 58 Jan 1 00:00 /dev/rknpu

# 2. 检查内核模块
lsmod | grep rknpu
# 预期输出: rknpu  xxxxxx 0

# 3. 检查 NPU 使用情况
cat /sys/kernel/debug/rknpu/load
# 预期输出: NPU load: 0%

如果设备节点不存在,说明内核没有开启 NPU 驱动。检查内核配置:

# 确认内核编译了 NPU 驱动
zcat /proc/config.gz | grep RKNPU
# 应有: CONFIG_RKNPU=y

2.2 安装 RKNN Runtime

板端推理只需要 librknnrt.so,不需要完整的 RKNN-Toolkit2那个只在 PC 端做模型转换用)。

# 方式1: 从 Rockchip SDK 提取
# SDK 路径: external/rknn-toolkit2/rknpu2/runtime/Linux/librknn_api/aarch64/
cp librknnrt.so /usr/lib/
cp rknn_server /usr/bin/   # 可选,用于代理模式

ldconfig
ldconfig -p | grep rknnrt
# 预期输出: librknnrt.so => /usr/lib/librknnrt.so

# 方式2: 从 buildroot 镜像中确认是否已包含
# 创龙 TL3568-EVM 默认 Buildroot 已包含 NPU 驱动

2.3 npu_transfer_proxy重要

RK3568 推荐使用 npu_transfer_proxy 机制NPU 推理请求从一个代理进程转发,避免每个应用都打开 /dev/rknpu

# 启动 proxy通常在 init 脚本中自动启动)
npu_transfer_proxy &
# 监听 /tmp/rknpu.sock

# 应用程序通过 proxy 与 NPU 通信
# librknnrt.so 内部自动通过 proxy应用层无感知

2.4 快速验证:跑通 YOLOv5 Demo

创龙已提供 YOLOv5 推理 Demo用来验证 NPU 环境:

# Demo 路径 (在仓库中)
# TL3568-EVM.../4-软件资料/Demo/platform-demos/yolov5_object_detect/

# 运行验证
cd /path/to/yolov5_demo
./rknn_yolov5_demo ./model/yolov5s.rknn ./test.jpg

# 预期输出:
#   NPU init success
#   model load success
#   inference time: 15.2 ms
#   detected: person (0.95), car (0.87)

如果这一步跑通了NPU 环境就是正常的。


三、NPU 内存管理要点

3.1 两种内存模式

模式 A: 拷贝模式 (简单,适合开发阶段)
  应用层 buffer → rknn_inputs_set() → 内部拷贝到 NPU DMA buffer
  + 简单,不需要关心物理内存
  - 每次推理多一次 memcpy (~几十 μs)

模式 B: 零拷贝模式 (高效,适合生产环境)
  应用层分配 DMA buffer → rknn_set_io_mem() → NPU 直接访问
  + 无 CPU 拷贝开销
  - 需要通过 DMA API 分配内存 (dma_alloc_coherent 或 ion)

3.2 建议

开发阶段先用拷贝模式代码简单稳定后改为零拷贝性能最优。对于你的波形推理1~3ms单次 memcpy 的几十 μs 影响不大。


四、NPU 驱动调试命令速查

# 查看 NPU 负载
cat /sys/kernel/debug/rknpu/load

# 查看 NPU 频率
cat /sys/class/devfreq/ffbc0000.npu/cur_freq

# 查看 NPU 电源状态
cat /sys/kernel/debug/rknpu/power

# 查看最近一次推理耗时
cat /sys/kernel/debug/rknpu/profile

# dmesg 中查看 NPU 错误
dmesg | grep -i rknpu
dmesg | grep -i "npu.*error"