Hi3516CV610 获取设备 Unique ID 实战
Hi3516CV610 获取设备 Unique ID 实战
背景说明
本文基于下面这套实际环境整理:
- 芯片平台:Hi3516CV610
- SDK 版本:Hi3516CV610_SDK_V1.0.2.1
- 工程类型:MPP Sample 工程
- 示例模块:
daemon目录下的测试程序 - 验证方式:通过
make test交叉编译、上传到板端并远程执行
如果你的环境与本文接近,尤其是同一大版本 SDK,那么接口名称、头文件位置和链接依赖通常都可以直接参考。
如果你使用的是其它芯片型号,或者是不同大版本的 SDK,那么也建议先按本文介绍的方法去定位头文件、结构体定义和链接库,而不是直接照抄代码。
做设备注册、设备绑定、云端鉴权这类功能时,第一步通常不是写网络请求,而是先回答一个更基础的问题:
这台设备,到底用什么来唯一标识?
在 Hi3516CV610 这类 SDK 项目里,很多人第一反应是去业务代码里找 uuid、serial、device_id,但实际排查后会发现,这类唯一标识往往不是业务层自己生成的,而是厂商 SDK 直接提供。
这篇文章就结合一次真实排查过程,讲清楚下面几件事:
- 如何在 Hi3516CV610 SDK 中定位设备唯一标识接口
ss_mpi_sys_get_unique_id()到底是什么- 为什么代码能编过、链接却失败
- 如何把
unique id真正跑通并打印出来
先说结论:
在这套 SDK 里,可以通过 ss_mpi_sys_get_unique_id() 获取设备唯一标识,但它返回的不是标准 RFC 4122 格式的 UUID 字符串,而是 SDK 定义的 ot_unique_id 数组。因此更准确的说法应当是 Unique ID,而不是严格意义上的 UUID。
一、先别写代码,先定位接口
如果你接手的是一个现成工程,最稳妥的做法不是直接猜 API,而是先在 SDK 头文件里查“唯一标识”相关接口。
这次排查里,最终定位到的声明在:
声明如下:
td_s32 ss_mpi_sys_get_unique_id(ot_unique_id *unique_id);
看到这行之后,至少能确定三件事:
- 这是系统级 MPI 接口,不是业务层自己封装的函数
- 返回值是
td_s32,也就是标准 SDK 风格的状态码 - 输出参数是
ot_unique_id *,说明结果不是直接返回字符串
继续往下查 ot_unique_id 的定义,可以在:
对应定义是:
typedef struct {
td_u32 id[OT_UNIQUE_ID_NUM];
} ot_unique_id;
数组长度常量在:
定义为:
#define OT_UNIQUE_ID_NUM 6
这一步很重要,因为它直接决定了你后面的打印方式。
很多人这里会犯一个错误:
一看到 get_unique_id 就默认它返回的是标准 UUID 字符串,结果后面输出格式、存储格式、上传格式全都设计错了。
二、最小可运行代码怎么写
如果目标只是先把设备 unique id 跑出来,最小示例完全不需要混进复杂业务流程。
一个足够干净的写法如下:
#include <iostream>
#include "ss_mpi_sys.h"
int main()
{
ot_unique_id unique_id = {};
td_s32 ret = ss_mpi_sys_get_unique_id(&unique_id);
if (ret != TD_SUCCESS) {
std::cerr << "读取 unique id 失败: 0x" << std::hex << ret << std::dec << std::endl;
return 1;
}
std::cout << "unique id:";
for (td_u32 i = 0; i < OT_UNIQUE_ID_NUM; ++i) {
std::cout << std::hex << unique_id.id[i];
}
std::cout << std::dec << std::endl;
return 0;
}
这个版本里,有几个细节值得注意:
ot_unique_id unique_id = {};用来保证结构体先清零- 失败时把返回码按十六进制打印,方便和 SDK 错误码体系对照
unique_id.id[i]是一个td_u32数组,所以最直接的打印方式就是循环输出十六进制值
如果你只是验证接口是否可用,这一版就够了。
三、为什么单文件编译通过,但 make 还是失败
这是这次踩坑里最典型的一步。
把上面的代码写进测试程序之后,单文件语法检查通常是能过的。因为这一步只验证两件事:
- 头文件能不能找到
- 类型和函数声明能不能识别
但真正执行 make test 时,问题会出在链接阶段:
undefined reference to `ss_mpi_sys_get_unique_id`
这类报错说明什么?
说明编译器已经相信“这个函数确实存在”,但链接器在最终拼二进制时,没找到真正实现它的静态库或动态库。
换句话说:
头文件找到了,库没链上。
四、实现不在源码里,而在厂商库里
继续往下排查,会发现项目源码里根本搜不到 ss_mpi_sys_get_unique_id 的函数体。
这并不奇怪,因为它属于厂商 SDK 提供的 MPI 接口,实现通常放在预编译库中。
实际排查后,可以确认这个符号来自:
这也是为什么很多人会误以为“工程里没有这个函数”,实际上不是没有,而是你只能看到声明,看不到实现。
五、真正的坑不止一个库
很多人修到这里,会直接在链接命令里补一个 libss_mpi.a,然后继续编译。
结果第二轮常见会遇到新的错误,比如:
memcpy_s未定义memset_s未定义strncpy_s未定义snprintf_s未定义
这说明 libss_mpi.a 本身还依赖别的库。
在这套 SDK 里,最稳妥的做法不是只手工补一个 libss_mpi.a,而是直接复用 SDK 已经整理好的整组 MPI 依赖。
当前项目的依赖集合定义在:
测试目标最终采用的方式是:
- 复用
$(MPI_LIBS) - 额外补
libsecurec.a
对应位置在:
这种写法的好处非常明确:
- 你不用自己猜
libss_mpi.a后面还依赖哪些 MPP 库 securec的安全函数依赖也一并解决- 测试目标和 SDK 原本的构建方式更一致,后续维护成本更低
六、项目里是怎么接进去的
当前示例程序放在:
这个测试程序现在做了两件事:
- 读取并打印
unique id - 读取并打印 CPU 温度
其中 unique id 的关键逻辑就是:
ot_unique_id unique_id = {};
td_s32 ret = ss_mpi_sys_get_unique_id(&unique_id);
if (ret != TD_SUCCESS) {
std::cerr << "读取 unique id 失败: 0x" << std::hex << ret << std::dec << std::endl;
return 1;
}
std::cout << "unique id:";
for (td_u32 i = 0; i < OT_UNIQUE_ID_NUM; ++i) {
std::cout << std::hex << unique_id.id[i];
}
std::cout << std::dec << std::endl;
这段逻辑没有做任何复杂封装,目的就是先把接口确认跑通。
七、如何验证真的成功了
在这个项目里,最直接的验证方式就是进入 daemon 目录执行:
make test
这个命令不是单纯本地编译,它会:
- 编译测试程序
- 链接生成测试二进制
- 上传到板端
- 远端执行测试程序
实际运行结果类似这样:
unique id: 37020a14-21c9071c-46e544d9-fa7ea8c0-3c701-7
当前 CPU 温度: 43 C
这里还要再提醒一次:
这个输出虽然看起来像某种分段 ID,但它不等同于标准 UUID 文本格式。它本质上仍然是厂商 SDK 返回的一组设备唯一标识数据。
八、如果你要把它用于设备注册
当你已经拿到 unique id 之后,后面的典型用途通常有三种:
- 作为设备注册接口的唯一设备标识
- 作为设备端启动日志的一部分,方便产测和售后定位
- 和温度、版本号、网络信息一起组成设备自检输出
如果是上报到服务端,我建议额外做一步格式标准化,例如:
- 每段统一按固定宽度十六进制输出
- 增加分隔符
- 明确大小写风格
这样服务端更容易做存储、检索和比对。
九、这类问题真正该学会的,不是 API 名字
很多人看完类似文章,最想记住的是:
“Hi3516CV610 获取唯一标识用 ss_mpi_sys_get_unique_id()。”
这当然没错,但更重要的其实是这套排查思路:
- 先在 SDK 头文件里定位声明
- 再查输出参数的数据结构
- 不要把
Unique ID想当然当成标准 UUID - 编译过了不代表结束,链接阶段才是真正的依赖检查
- 厂商 SDK 接口通常不在源码里,而在预编译库里
- 能复用 SDK 的库集合时,不要自己零散手补依赖
你真正掌握的是这套方法,下次碰到 chip id、custom code、serial、otp 之类系统级接口时,排查效率会快很多。
十、总结
在 Hi3516CV610 这套 SDK 中,获取设备唯一标识的关键并不在“调用一个函数”本身,而在于把下面三件事做对:
- 找到正确的系统接口
ss_mpi_sys_get_unique_id() - 理解返回值不是字符串,而是
ot_unique_id数组 - 在工程构建里把
MPI_LIBS和libsecurec.a这类依赖链完整补齐
如果你现在只是想先验证设备是否能读出唯一标识,那最小测试程序已经足够。
如果你下一步要做设备注册、设备首次激活或者产测工具,把这个 unique id 做成统一格式再上报,会比直接裸打印更稳。
如果后续你还想继续展开,一个自然的下一篇可以是:
《Hi3516CV610 如何把 Unique ID 上报到设备注册接口》。
- 分享
- 举报
暂无数据-
浏览量:1005次2026-04-16 10:50:10
-
浏览量:8851次2024-03-17 11:48:56
-
浏览量:8784次2024-03-04 16:10:47
-
浏览量:7545次2024-02-24 09:57:43
-
浏览量:8531次2024-04-30 21:01:38
-
浏览量:7611次2024-03-16 11:19:01
-
浏览量:8404次2024-03-18 11:50:01
-
浏览量:8908次2024-04-30 22:13:25
-
浏览量:2190次2025-02-09 15:30:36
-
2026-03-05 18:00:16
-
浏览量:6570次2024-06-14 15:31:06
-
浏览量:768次2026-06-15 14:03:54
-
浏览量:4085次2024-08-22 21:17:40
-
浏览量:1475次2026-03-23 17:08:37
-
浏览量:4246次2024-03-19 11:42:03
-
浏览量:3511次2024-06-01 14:33:25
-
浏览量:5317次2025-04-19 17:47:49
-
浏览量:3256次2024-03-26 10:43:16
-
浏览量:2315次2024-12-10 13:54:25
-
1篇
- [寒假大作战]2.yolov8模型训练和转换
- Hi3516CV610 超高清智慧视觉SoC
- 使用Docker搭建Linux开发环境
- G610Q-IPC-38E型模组开发—产品简介
- 【寒假大作战】2——渐入佳境(Hongou PI PICO开发环境的搭建)
- 易百纳新品上市!海思Hi3516CV610主控平台,高性能IPC解决方案
- Hi3516CV610 SDK 安装及升级
- 【海思】Hi3516CV610-00s如何适配一款新的sensor--GC4683_20260305
- HI3516CV610开发笔记(二)SDK安装及编译
- 基于社区HongOUPI_PICO OpenHarmony 系统(一、使用说明)
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
仙女养的猪
微信支付举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明

微信扫码分享
QQ好友