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

201 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 驱动已加载
```bash
# 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 驱动检查内核配置
```bash
# 确认内核编译了 NPU 驱动
zcat /proc/config.gz | grep RKNPU
# 应有: CONFIG_RKNPU=y
```
### 2.2 安装 RKNN Runtime
板端推理只需要 **librknnrt.so**不需要完整的 RKNN-Toolkit2那个只在 PC 端做模型转换用)。
```bash
# 方式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`
```bash
# 启动 proxy通常在 init 脚本中自动启动)
npu_transfer_proxy &
# 监听 /tmp/rknpu.sock
# 应用程序通过 proxy 与 NPU 通信
# librknnrt.so 内部自动通过 proxy应用层无感知
```
### 2.4 快速验证:跑通 YOLOv5 Demo
创龙已提供 YOLOv5 推理 Demo用来验证 NPU 环境
```bash
# 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 驱动调试命令速查
```bash
# 查看 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"
```