/ ai资讯

在Zephyr OS上启用NPU的实用方案

发布时间:2026-03-09 11:47:42

前两期中我们已经把所有准备工作一步步铺垫到位:

Zephyr迎来AI加速时代:NPU驱动集成从未如此简单

为Zephyr AI加速做好准备:模型转换

现在,是时候把准备工作真正转化为成果了!

今天,我们将正式在Zephyr中加入NPU软件支持,让模型不仅能“跑起来”,还能“跑得飞快”。是的,本期开始就是实战环节!

本次的适配工作将以tflite_micro/hello_world工程为基础展开。我们首先将其完整复制一份,并命名为hello_world_neutron。后续所有与Neutron NPU相关的移植步骤和配置修改,都将在这个新工程中进行。

Zephyr的移植工作我们基于tfltie_micro/hello_world工程进行,将其复制一份重命名为hello_world_neutron:

一、改造思路

整体改造大致分为三个主要步骤:

开启C /FPU/TFLM支持

添加NPU相关驱动与接口层代码

修改CMakeLists.txt让工程真正“认识” NPU

除此之外,还需要将模型文件替换为NPU可执行的版本,并手动注册Neutron自定义算子,使TFLM能够调用NPU。下面我们一步一步来。

二、工程配置

1.修改prj.conf文件,添加FPU与CXX的支持:

CONFIG_CPP=y
CONFIG_STD_CPP17=y
CONFIG_FPU=y
CONFIG_FPU_SHARING=y
CONFIG_TENSORFLOW_LITE_MICRO=y
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_REQUIRES_FLOAT_PRINTF=y

三、加入NPU相关代码

NPU 的组件大致可分为两部分:

1. Neutron 与 TFLM 的接口层 2. Neutron 底层 Driver

3.1将NPU相关Driver从SDK中拷贝到工程目录中

主要分为两部分:NPU底层Driver以及NPU与TFLM的接口层代码:

a) TFLM接口层代码:

我们可以在SDK代码中的eiq ensorflow-lite ensorflowlitemicrokernels eutron路径下找到这两个文件,

一定要注意:SDK版本要和转换工具的版本一致,这里我们选择的是2.16.0版本的SDK代码以及针对于2.16.0 SDK版本的Neutron-converter.exe:

将这两个文件拷贝到工程目录中:

3.2NPU底层驱动:

可以在eiq ensorflow-lite hird_party eutron路径找到:

将其同样拷贝到工程目录下,完整的目录结构如下:

四、修改CMakeLists,加入NPU依赖

我们需要让工程能够正确包含头文件、链接NPU相关库,完整示例如下:

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(tensorflow_hello_world)
# These samples use local static initialization. Since Zephyr doesn't support the
# C ABI for thread-safe initialization of local statics and the constructors don't
# appear to require thread safety, we turn it off in the C compiler.
set(NO_THREADSAFE_STATICS $ )
zephyr_compile_options($<$ :${NO_THREADSAFE_STATICS}>)
#头文件依赖
target_include_directories(app PRIVATE neutron/driver/include)
target_include_directories(app PRIVATE neutron/common/include)
target_include_directories(app PRIVATE neutron/source)
#库依赖
add_library(libneutron1 STATIC IMPORTED GLOBAL)
set_target_properties(libneutron1 PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/neutron/libNeutronDriver.a)
add_library(libneutron2 STATIC IMPORTED GLOBAL)
set_target_properties(libneutron2 PROPERTIES IMPORTED_LOCATION
${CMAKE_CURRENT_SOURCE_DIR}/neutron/libNeutronFirmware.a)
add_library(libneutron INTERFACE)
target_link_libraries(libneutron INTERFACE libneutron1 libneutron2)
target_link_libraries(app PUBLIC libneutron)
#添加源文件
file(GLOB app_sources src/*)
target_sources(app PRIVATE ${app_sources})
target_sources(app PRIVATE neutron/source/neutron.cpp)

到这里,工程已经具备NPU支持能力。

五、替换模型文件

将src/目录下的model.cpp替换为你通过xxd转换得到的NPU版本模型。

模型来源应为Neutron-converter转换后的.bin,格式已经适配NPU。

六、注册Neutron自定义算子

注册Neutron算子:

因为TFLM本身不支持Neutron算子,这里需要我们手动添加,添加方式是修改src/main_functions.cpp:

/* This pulls in the operation implementations we need.
* NOLINTNEXTLINE(runtime-global-variables)
*/
static tflite::MicroMutableOpResolver <1> resolver;
resolver.AddCustom(tflite::GetString_NEUTRON_GRAPH(),
tflite::Register_NEUTRON_GRAPH());

因Zephyr自带的模型算子类型是FullyConnected,这里将他替换为NeutronGraph,同时在文件开头添加头文件引用:

至此,所有软件工作就都完成了,接下来就是使用west工具进行编译:

west build -b frdm_mcxn947/mcxn947/cpu0

七、编译,下载运行

使用west编译工程,下载运行:

当我们看到正常输出、并且没有任何错误时,就说明:

模型成功转换

Neutron NPU驱动加载成功

TFLM已正确调度NPU推理

模型已顺利跑在NPU上进行加速!

八、完整链路走通

至此,小编跨越三期,带大家完整走了一遍流程:

1. 自主训练模型

2. 使用转换工具生成NPU 可执行格式

3. 在ZephyrOS 中添加 Neutron NPU 驱动支持

4. 让模型真正跑在NPU 上加速推理

这条链路虽然步骤较多,但每一步都是构建“嵌入式AI”所必需的关键环节。

也期待未来ZephyrOS能继续完善AI支持,让NPU适配更加自动化,让开发者可以更加专注于算法本身。

  • 移植 移植 关注

    关注

    1

    文章

    415

    浏览量

    29414
  • AI AI 关注

    关注

    91

    文章

    39804

    浏览量

    301479

免责声明:本文为转载,非本网原创内容,不代表本网观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

如有疑问请发送邮件至:bangqikeconnect@gmail.com