二、软件开发
本系列设备使用TACO-SDK进行软件功能开发。 TACO-SDK 是一套完整的开发工具包,提供了丰富的视频处理、计算机视觉和AI推理功能。该 SDK 包含了必要的库文件、工具和示例,使开发者能够快速构建和部署视频分析应用。
2.1 SDK 架构说明
其目录架构及其作用如下所示:
tps-future/
├── debs # 库的安装包
├── ta-base/ # 基础运行库
│ ├── ta-runtime/ # 运行时库
│ │ └── lib/ # 运行时库文件
│ │ └── include/ # 头文件
│ └── ta-cv/ # 计算机视觉相关库
│ ├── lib/ # 计算机视觉库文件
│ └── include/ # 计算机视觉库头文件
├── ta-vsp/ # 视频处理相关组件
│ ├── README.md # 视频处理组件说明文档
│ ├── ta-opencv/ # OpenCV 相关库和工具
│ │ ├── lib/ # 库文件
│ │ └── include/ # 头文件
│ ├── ta-ffmpeg/ # FFmpeg 相关库和工具
│ │ ├── lib/ # 库文件
│ │ └── include/ # 头文件
│ ├── ta-samples/ # 示例代码
│ │ ├── npu_infer_sample/ # NPU 推理示例
│ │ │ ├── Makefile # 编译脚本
│ │ │ └── dual_core_fps.c # 示例源代码
│ │ ├── single_buffer_pipeline_sample # 单 vb 管道处理示例
│ │ │ ├── Makefile # 编译脚本
│ │ │ └── single_buffer_pipeline.cpp # 示例源代码
│ │ ├── taco_40pin_sample # 40pin 示例
│ │ │ └── 40pin_sample.py # 40pin function 示例
│ │ ├── taco_ffmpeg_decode_sample # FFmpeg 解码示例
│ │ │ ├── Makefile # 编译脚本
│ │ │ └── taco_decoder_sample.cpp # 示例源代码
│ │ ├── taco_ffmpeg_encode_sample # FFmpeg 视频解码示例
│ │ │ ├── Makefile # 编译脚本
│ │ │ └── taco_encoder_sample.cpp # 示例源代码
│ │ ├── tacv_sample # 计算机视觉示例
│ │ │ ├── CMakeLists.txt # CMake 构建文件
│ │ │ ├── tacv_sample_crop.cpp # 裁剪示例
│ │ │ ├── tacv_sample_csc.cpp # 格式转换示例
│ │ │ ├── tacv_sample_jpeg_dec.cpp # jpeg 解码示例
│ │ │ ├── tacv_sample_jpeg_enc.cpp # jpeg 编码示例
│ │ │ ├── tacv_sample_resize.cpp # 缩放示例
│ │ │ ├── tacv_sample_resize_stride.cpp # 缩放 + stride 示例
│ │ │ └── tacv_sample_yuv2rgb.cpp # 色彩转换示例
│ │ ├── tademo_sample # NPU推理性能
│ │ │ ├── CMakeLists.txt # 编译脚本
│ │ │ ├── README.md # 说明文档
│ │ │ ├── samples # 示例源代码
│ │ │ ├── soc240401_riscv64 # 共版示例依赖的库
│ │ │ └── toolchain.cmake # 工具链设置脚本
│ │ ├── taopencv_sample # OpenCV 示例
│ │ │ ├── Makefile # 编译脚本
│ │ │ └── taopencv_sample.cpp # 示例源代码
│ │ ├── yolov5_tracker_sample # 单 pipeline 串联解码,推理,编码
│ │ │ ├── CMakeLists.txt # 编译脚本
│ │ │ ├── data # 数据
│ │ │ ├── libs # 示例源代码库
│ │ │ ├── README.md # 简要说明
│ │ │ ├── samples # 示例源代码
│ │ │ ├── soc240401_riscv64 # 共版示例依赖的库
│ │ │ └── toolchain.cmake # 工具链设置脚本
│ ├── ta-unify-9200O/ # NPU 统一推理接口库
│ │ ├── lib/ # 库文件
│ │ └── include/ # 头文件
│ ├── ta-viplite-9200o/ # NPU 低层驱动库
│ │ ├── lib/ # 库文件
│ │ └── include/ # 头文件
│ ├── ta-sys/ # 系统相关组件
│ │ ├── lib/ # 库文件
│ │ └── include/ # 头文件
│ ├── ta-libenc/ # 视频编码库
│ │ ├── lib/ # 库文件
│ │ └── include/ # 头文件
│ ├── ta-libdec/ # 视频解码库
│ │ ├── lib/ # 库文件
│ │ └── include/ # 头文件
│ └── ta-pipeworks/ # 管道处理框架
│ └── lib/ # 库文件
├── ta-docker-image/ # Docker 镜像相关文件和说明
│ └── README.md # Docker 镜像使用说明
├── ta-image/ # 系统镜像工具
│ ├── README.md # 镜像工具说明文档
│ ├── install_sdk_img.sh # 固件下载脚本
│ └── update/ # 更新工具
│ └── mk-tf.sh # 系统镜像制作和烧录工具
├── start_tanntc_docker.sh # 启动 NPU 推理编译环境 Docker 容器脚本
├── start_workshop_docker.sh # 启动 SDK 编译工作环境 Docker 容器脚本
└── README.md # 当前 SDK 总体说明文档
2.2 SDK示例使用
先安装 tps-test 下载测试资源
sudo apt update
sudo apt install tps-test
2.2.1 NPU infer Sample
- 在 docker 中,进入
npu_infer_sample目录,输入make开始编译,即可在npu_infer_sample目录下获得板端可执行程序npu_infer
cd ta-vsp/ta-samples/npu_infer_sample
make
- 通过
scp命令将程序发送到板端的/usr/bin目录下
scp -r npu_infer root@192.168.56.171:/usr/bin/ # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/npu目录,查看并确定一个网络模型(例如 inception_v3),进入对应目录,里边会有一个sample.txt文件,它描述了模型信息和输入输出配置,输入以下命令执行一次推理
root@taco-dk:/usr/data/npu/inception_v3# npu_infer -s sample.txt
config file read network count=1
create network file_path = ./network_binary.nb
create network status = 0, core_mask =1
FPS -Core0: 0, Core1: 1
destroy test resource task_count=1
2.2.2 tademo Sample
tademo 包含了解码和推理 2 个过程,是个综合的 Sample。
- 在 docker 中,进入
tademo_sample目录,使用以下命令进行编译
cd ta-vsp/ta-samples/tademo_sample
mkdir build
cd build
cmake ../ -DTARGET_ARCH=soc -DTACO_SDK_SOC=/tps-future/ta-vsp/ta-samples/tademo_sample/soc240401_riscv64 -DCMAKE_TOOLCHAIN_FILE=/tps-future/ta-vsp/ta-samples/tademo_sample/toolchain.cmake
make -j16
编译结果显示如下:
tps@tps-sdk:/tps-future/ta-vsp/ta-samples/tademo_sample/build# cmake ../ -DTARGET_ARCH=soc -DTACO_SDK_SOC=/tps-future/ta-vsp/ta-samples/tademo_sample/soc240401_riscv64 -DCMAKE_TOOLCHAIN_FILE=/tps-future/ta-vsp/ta-samples/tademo_sample/toolchain.cmake
-- Toolchain file loaded: /tps-future/ta-vsp/ta-samples/tademo_sample/toolchain.cmake
-- toolchain.Using C Compiler: /toolchain/bin/riscv64-unknown-linux-gnu-gcc
-- toolchain.Using CXX Compiler: /toolchain/bin/riscv64-unknown-linux-gnu-g++
-- Toolchain file loaded: /tps-future/ta-vsp/ta-samples/tademo_sample/toolchain.cmake
-- toolchain.Using C Compiler: /toolchain/bin/riscv64-unknown-linux-gnu-gcc
-- toolchain.Using CXX Compiler: /toolchain/bin/riscv64-unknown-linux-gnu-g++
-- The C compiler identification is GNU 14.1.1
-- The CXX compiler identification is GNU 14.1.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /toolchain/bin/riscv64-unknown-linux-gnu-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /toolchain/bin/riscv64-unknown-linux-gnu-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- TACO_SDK_DIR: /tps-future
-- CMAKE_TOOLCHAIN_FILE: /tps-future/ta-vsp/ta-samples/tademo_sample/toolchain.cmake
-- tademo.CMAKE_BINARY_DIR: /tps-future/ta-vsp/ta-samples/tademo_sample/build
-- tademo.CMAKE_SOURCE_DIR: /tps-future/ta-vsp/ta-samples/tademo_sample
-- tademo.DESTINATION:
-- tademo.CMAKE_INSTALL_PREFIX: /usr/local
PROJECT_ROOT = /tps-future/ta-vsp/ta-samples/tademo_sample
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
TACO_SDK_SOC
TARGET_ARCH
-- Build files have been written to: /tps-future/ta-vsp/ta-samples/tademo_sample/build
tps@tps-sdk:/tps-future/ta-vsp/ta-samples/tademo_sample/build# make -j 16
[ 50%] Building CXX object samples/CMakeFiles/tademo.dir/src/demo.cpp.o
/tps-future/ta-vsp/ta-samples/tademo_sample/samples/src/demo.cpp: In function 'int main(int, char**)':
/tps-future/ta-vsp/ta-samples/tademo_sample/samples/src/demo.cpp:286:24: warning: 'void av_register_all()' is deprecated [-Wdeprecated-declarations]
286 | av_register_all();
| ~~~~~~~~~~~~~~~^~
In file included from /tps-future/ta-vsp/ta-samples/tademo_sample/samples/./include/demo_function.h:15,
from /tps-future/ta-vsp/ta-samples/tademo_sample/samples/src/demo.cpp:1:
/tps-future/ta-vsp/ta-ffmpeg/include/libavformat/avformat.h:2050:6: note: declared here
2050 | void av_register_all(void);
| ^~~~~~~~~~~~~~~
[100%] Linking CXX executable /tps-future/ta-vsp/ta-samples/tademo_sample/samples/build/tademo
[100%] Built target tademo
编译成功后,会在 tademo_sample/samples/build 目录下生成可执行文件 tademo。
- 将 docker 上的
tademo程序拷贝到板端的/usr/bin目录,执行
scp -r tademo root@192.168.56.171:/usr/bin/ # IP 地址按照实际情况更改
- 登录到板端,在终端上执行
root@taco-dk:/usr/bin#tademo 1
create network file_path = /usr/data/taco-pipeline-1.0.0/network_binary.nb
ta_runtime_load_model_from_file
Model loaded and network prepared
YoloxInference::set_input.st.m_input_num=2
YoloxInference::set_input.ta_runtime_set_input_cva.st
YoloxInference::set_input.ta_runtime_set_input_cva.ed
YoloxInference::set_input.ed ----00
..................
VideoDecFFM::resizeFrame.st resize.blk.st
Pre[PP].duration=947 resize.blk.cost=8531
Predict[NPU].duation=7436 us
at=257:302:454:427,id=2,prob=0.751940
at=219:305:262:334,id=2,prob=0.669507
at=136:294:173:385,id=0,prob=0.589986
at=424:293:570:350,id=2,prob=0.588738
at=33:290:74:399,id=0.prob=0.584781
Post[CPU].duation=1824 us,count=5
..................
predict file.end information:
Total Frame Count= 201
Pre[PP] avgcost=974 us (1026 fps),Infer[NPU]avgcost= 7421 us (134 fps),Post[CPU] avgcost= 1792 us (558 fps) rootataco-dk:~# sudo find / -name "tademo"/usr/local/bin/tademo/root/tademo
- 分析运行结果
对屏幕打印的最后一段 log 进行分析,板端实际跑出的性能结果如下:
Pre[PP] avgcost= 974 us (1026 fps), #用PP硬件做 resize 操作的耗时,及等效帧率
Infer[NPU] avgcost= 7421 us (134 fps), #用 NPU 做推理的软件接口时间,及等效帧率
Post[CPU] avgcost= 1792 us (558 fps) #用 CPU 推理后处理时间,及等效帧率
值得说明的是,NPU推理时间 7421 us 是每次调用推理接口的耗时,它略大于纯硬件推理时间。如果只考察一个推理线程(不含后处理),134 fps(per cluster @ 1 GHz)就是该线程能够输出的最大帧率;如果考察多个线程同时工作的情况,则软件开销大部分可以多线程被隐藏掉,总的推理帧率能够达到 182 fps(per cluster @ 1 GHz)。
2.2.3 解码 Sample
- 在 docker 中,进入
taco_ffmpeg_decode_sample目录,输入make开始编译,即可获得板端可执行程序taco_decoder_sample:
cd ta-vsp/ta-samples/taco_ffmpeg_decode_sample
make
- 通过
scp命令将程序发送到板端的/usr/data/vdec目录下:
scp -r taco_decoder_sample root@192.168.56.171:/usr/data/vdec # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/vdec目录,目录下有一个视频文件input.mp4,它用于测试解码功能:
./taco_decoder_sample
-
解码停止后,会在当前目录下生成
result.yuv文件,它包含一组分辨率为640x640的NV12视频帧。 -
将
result.yuv拷回主机,用ffmpeg提供的ffplay工具进行播放,观察图像正确性。播放命令为:
ffplay -video_size 640x640 -pixel_format nv12 -i result.yuv
2.2.4 编码 Sample
- 在 docker 中,进入
taco_ffmpeg_encode_sample目录,输入make开始编译,即可获得板端可执行程序taco_encoder_sample:
cd ta-vsp/ta-samples/taco_ffmpeg_encode_sample
make
- 通过
scp命令将程序发送到板端的/usr/data/venc目录下:
scp -r taco_encoder_sample root@192.168.56.171:/usr/data/venc # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/venc目录:
./taco_encoder_sample
-
编码停止后,会在当前目录下生成
output_yuv420p_10f.h264文件,它是h264格式的文件。 -
将
output_yuv420p_10f.h264拷回主机,用ffmpeg提供的ffplay工具进行播放,观察图像正确性。播放命令为:
ffplay -f h264 output_yuv420p_10f.h264
2.2.5 taCV Sample
- 在 docker 中,进入
tacv_sample目录,创建build文件夹并进入,输入cmake .. && make开始编译,即可获得板端可执行程序tacv_sample_resize等。
cd ta-vsp/ta-samples/tacv_sample
mkdir build && cd build
cmake .. && make
- 通过
scp命令将想要运行的程序发送到板端的/usr/data/libcv目录下:
scp -r tacv_sample_resize root@192.168.56.171:/usr/data/libcv # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/libcv目录:
./tacv_sample_resize sample_src/LenaNV12.bin 512 512 256 256
-
运行结束后当前目录会生成
resize_out.bin文件,它是nv12格式的二进制数据文件。 -
将
resize_out.bin拷回主机,用ffmpeg提供的ffplay工具进行播放,观察图像正确性。播放命令为:
ffplay -f rawvideo -pixel_format nv12 -video_size 256x256 -framerate 25 resize_out.bin
2.2.6 taOpenCV Sample
- 在 docker 中,进入
taopencv_sample目录,输入make开始编译,即可获得板端可执行程序taopencv_sample等。
make
- 通过
scp命令将想要运行的程序发送到板端的/usr/data/libcv目录下:
scp -r taopencv_sample root@192.168.56.171:/usr/data/libcv # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/libcv目录,执行命令:
./taopencv_sample sample_src/Lena.jpg 256 256
-
运行结束后当前目录会生成
output.jpg文件,它是jpeg格式的文件。 -
将
output.jpg拷回主机,可以直接播放。
2.2.7 40pin Sample
40pin 接口测试工具用于验证开发板上的各种接口功能,包括 SPI、I2C、serial 和 GPIO 等。
-
在 docker 中,进入
taco_40pin_sample目录,存在40pin_sample.py脚本。 -
通过
scp命令将想要运行的程序发送到板端的/usr/data/目录下:
scp -r 40pin_sample.py root@192.168.56.171:/usr/data/ # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/目录,执行相应的测试命令:
python3 40pin_sample.py -t spi # SPI 测试
python3 40pin_sample.py -t i2c # I2C 测试
python3 40pin_sample.py -t serial # 通用 serial 测试
python3 40pin_sample.py -t gpio # GPIO 测试
- 期待输出
下面将对其输出进行说明,SPI、I2C、serial 及 GPIO 。
- SPI 测试
从打印的 SPI 控制器中选择总线号和片选号作为输入选项,例如选择测试 spidev9.0,则 bus number 为 9, chip select 为 0,按回车键确认, 需要将 MISO 和 MOSI 互联:
===== Starting SPI Test =====
Available SPI controllers:
/dev/spidev0.0 /dev/spidev0.1
Please enter SPI bus number: 9
Please enter SPI chip select number: 0
程序正确运行起来后会持续打印 0x55 0xAA,如果打印的是 0x00 0x00,那么就说明 SPI 的回环测试失败。
Successfully opened SPI device: /dev/spidev9.0, Frequency: 12MHz
Starting communication test. Press CTRL+C to exit
Received data: 0x55 0xAA
Received data: 0x55 0xAA
Received data: 0x55 0xAA
- serial 测试
打印的串口设备(其中 /dev/ttyPS0 是系统调试口,不建议对它进行测试,除非你完全明白它的作用) 按回车键确认,并输入波特率参数。
===== Starting Serial Test =====
Available serial devices:
/dev/ttyPS0 /dev/ttyPS5
Please enter the serial device name to test: /dev/ttyPS5
Please enter baud rate (9600, 19200, 38400, 57600, 115200, 921600): 115200
Successfully opened serial port: Serial<id=0x7fff9168c190, open=True>(port='/dev/ttyPS5', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=1, xonxoff=False, rtscts)
程序正确运行起来后会持续打印 Sent: AA55 和 Recv: AA55:
tarting communication test. Press CTRL+C to exit
Sent: AA55
Received: AA55
Sent: AA55
Received: AA55
Sent: AA55
Received: AA55
- I2C 测试
从打印的 I2C 设备中选择一个设备作为输入选项, 按回车键确认。
===== Starting I2C Test =====
Please enter I2C bus number: 0
Scanning I2C bus 0 for devices...
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- 0c -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- 28 -- -- -- -- -- -- --
30: -- -- -- -- -- -- UU 37 -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
输入外设地址(16进制数),测试程序会从该外设上读取一个字节的数据。
Please enter I2C device address (hexadecimal, e.g., 51): 0x40
Reading data from device 0x40 on I2C bus 0...
Read value: 0x41 (decimal: 65)
- GPIO 测试
该工具用于对指定域(CPU/RTC/SAP)的 GPIO 进行手动高低电平控制。
IN2 对应 RTC 域 GPIO5, IN1 对应 RTC 域 GPIO6 ,OUT1 对应 RTC 域 GPIO128,OUT2 对应 CPU 域 GPIO98。
python 40pin_sample.py -t gpio
交互流程
===== Starting GPIO Manual Control Test =====
Please enter GPIO domain (cpu/rtc/sap): cpu # 输入域
Please enter base GPIO number (domain cpu): 98 # 输入基础GPIO号
GPIO manual control mode:
Commands: '1' to set high, '0' to set low, 'q' to quit
Enter command (1/0/q): 1 # 输入1拉高
GPIO205 set to 1, verified value: 1 # 验证状态为高
Enter command (1/0/q): 0 # 输入0拉低
GPIO205 set to 0, verified value: 0 # 验证状态为低
Enter command (1/0/q): q # 输入q退出
Exiting GPIO control
===== GPIO Test Completed =====
2.2.8 VB 跨模块流转 Sample
- 在 docker 中,进入
single_buffer_pipeline_sample目录,输入make开始编译,即可获得板端可执行程序single_buffer_pipeline。
cd ta-vsp/ta-samples/single_buffer_pipeline_sample
make
- 通过
scp命令将想要运行的程序发送到板端的/usr/data/目录下
scp single_buffer_pipeline root@192.168.56.171:/usr/data/ # IP 地址按照实际情况更改
- 登录到板端的
/usr/data/目录,执行命令
./single_buffer_pipeline
-
运行结束后当前目录会生成两个
nv12格式的二进制文件,result.yuv与resize_out.bin,前者是解码帧数据,后者是解码帧输入经过 tacv resize 后保存的数据 -
将
result.yuv与resize_out.bin拷贝到本机,用ffmpeg提供的ffplay工具进行播放,观察图像正确性。播放命令分别为
ffplay -f rawvideo -pixel_format nv12 -video_size 640x640 result.yuv
ffplay -f rawvideo -pixel_format nv12 -video_size 512x512 -framerate 25 resize_out.bin
2.2.9 yolov5 tracker Sample
yolov5_tracker_sample 相关编译,测试步骤,测试结果分析可参考文档 「TacoAI 应用开发入门」的第三章 的相关内容。