2、SDK目录结构深度解析:SDK包根目录、osdrv、mpp、sample、tools等核心目录功能详解

拿到海思SDK开发包的第一件事是什么?

我个人的习惯是——先别急着编译,别急着看文档。先打开目录,从上到下扫一遍。就像你拿到一本新书,先翻翻目录,心里有个大概的框架。海思SDK的目录结构设计得其实挺清晰的,但如果你不了解每个目录的定位,很容易在后续开发中走弯路。

今天我们就来拆解一下SDK包的核心目录。我会结合我在项目中的实际经验,告诉你每个目录到底是干什么的,哪些目录你天天要打交道,哪些目录你可能一年都进不去一次。

2.1 SDK包根目录:项目的总入口

解压完SDK包,你首先看到的就是根目录。里面通常会有几个关键文件:

  • README:快速入门指南,告诉你SDK版本、支持的芯片型号、编译环境要求。
  • Makefile:顶层编译脚本,一键编译整个SDK。
  • scripts/:一些辅助脚本,比如环境检查、配置生成等。

嗯,这里要注意一点。很多新手上来就执行 make,结果编译报错。为什么?因为根目录的Makefile通常只是入口,它会把编译任务分发给各个子目录。你需要先配置好交叉编译工具链,设置好环境变量。

我的经验:拿到SDK后,先看README。别跳过这一步。我曾经在一个项目里,因为没看README,直接编译,结果折腾了半天才发现SDK版本和芯片型号不匹配。浪费了整整一个下午。

2.2 osdrv目录:操作系统的灵魂

osdrv 是 Operating System Driver 的缩写。说白了,这个目录就是负责让Linux内核跑起来,并且让硬件正常工作。

打开 osdrv,你会看到:

  • kernel/:Linux内核源码。海思基于某个LTS版本做了定制,添加了海思芯片的驱动支持。
  • uboot/:U-Boot启动引导程序。负责初始化硬件、加载内核。
  • rootfs/:根文件系统。包含了基本的Linux命令、库文件、配置文件。
  • pub/:编译输出的镜像文件,比如 uImagerootfs.squashfs 等。

你想想看,整个嵌入式系统的启动流程是这样的:上电 -> U-Boot -> 加载内核 -> 挂载根文件系统 -> 启动应用程序。而 osdrv 目录,就是负责前三步的。

避坑指南:我曾经在修改内核配置时,直接改了 kernel/arch/arm/configs/ 下的默认配置文件。结果编译出来的内核在板子上起不来。后来才发现,海思的配置项有很多隐藏依赖,不能随便改。建议用 make menuconfig 来配置,保存时注意备份。

2.3 mpp目录:多媒体处理的核心

mpp 是 Media Process Platform 的缩写。这是海思SDK里最核心的目录,也是你开发中最常打交道的地方。

为什么说它核心?因为海思芯片的强项就是视频编解码、图像处理、音频处理。而 mpp 目录就是这些能力的软件封装。

打开 mpp,你会看到:

  • include/:头文件。定义了所有MPP接口的数据结构、函数声明。
  • lib/:编译好的库文件。比如 libmpi.so(多媒体处理接口库)、libhdmi.so(HDMI输出库)。
  • component/:组件源码。比如 venc(视频编码)、vdec(视频解码)、vpss(视频处理子系统)。
  • extdrv/:外部驱动。比如 gpio-i2cpwm 等。

我个人习惯,在开始写应用层代码之前,先把 include/ 下的头文件翻一遍。尤其是 hi_comm_*.h 系列,里面定义了所有模块的数据结构。你想想看,如果你连 VENC_CHN_ATTR_S 结构体长什么样都不知道,你怎么配置编码通道?

小技巧:MPP的接口设计是分层级的。从 HI_MPI_*HI_MPI_*_*,命名很规范。比如视频编码,先创建通道 HI_MPI_VENC_CreateChn,再启动接收 HI_MPI_VENC_StartRecvPic。记住这个规律,查文档会快很多。

2.4 sample目录:拿来即用的参考代码

sample 目录,说白了就是官方给你写的示例代码。这是学习MPP接口最快的方式。

打开 sample,你会看到:

  • venc/:视频编码示例。演示如何从摄像头采集数据,编码成H.264/H.265。
  • vdec/:视频解码示例。演示如何解码视频文件并显示。
  • vo/:视频输出示例。演示如何将视频数据显示到HDMI或LCD。
  • audio/:音频示例。演示音频采集、编码、播放。
  • common/:公共代码。比如 sample_comm.h,里面封装了一些常用的函数。

我建议你怎么用这些示例?别直接复制粘贴。先读懂它的流程。比如 sample_venc,它的流程是:初始化系统 -> 创建VI(视频输入)通道 -> 创建VENC(视频编码)通道 -> 绑定VI和VENC -> 启动编码 -> 获取码流数据。这个流程,你搞懂了,视频编码这块就通了八成。

注意:示例代码为了演示简洁,通常没有做完善的错误处理。你在实际项目中,一定要检查每个MPI接口的返回值。我曾经在一个项目中,因为没检查 HI_MPI_SYS_Init 的返回值,结果系统初始化失败,后续所有操作都报错,排查了半天才发现是内存不足。

2.5 tools目录:开发调试的瑞士军刀

tools 目录,里面装的是各种开发调试工具。平时你可能用不上,但遇到问题的时候,它们能救命。

打开 tools,你会看到:

  • pc/:PC端工具。比如 HiTool(烧录工具)、HiReg(寄存器读写工具)。
  • linux/:Linux端工具。比如 proc 目录下的调试脚本,可以查看MPP模块的运行状态。
  • image/:镜像制作工具。比如 mkfs.jffs2mkfs.squashfs

嗯,这里我要重点说一下 HiReg 这个工具。它可以在PC上通过网络远程读写板子的寄存器。调试驱动的时候特别好用。比如你怀疑某个GPIO的电平不对,直接用 HiReg 读一下对应的寄存器,马上就知道结果,不用反复编译烧录。

我的经验:在调试视频输出时,画面一直花屏。用 HiReg 读了一下VO模块的寄存器,发现时钟配置不对。对照数据手册修正后,画面就正常了。如果没有这个工具,我可能得花一整天来排查。

2.6 其他重要目录

除了上面几个核心目录,SDK包里还有一些目录也值得了解:

目录名 功能说明 我的建议
doc/ 开发文档,包括API参考、硬件设计指南 必看。尤其是《MPP API参考》和《硬件设计指南》
osal/ 操作系统抽象层,屏蔽不同OS的差异 一般不用动,除非你要移植到其他OS
third-party/ 第三方库,比如ffmpeg、opencv的适配 按需使用,注意版本兼容性
build/ 编译脚本和配置文件 不要随意修改,除非你清楚自己在做什么

2.7 总结:如何高效使用SDK目录

说了这么多,最后给你一个实操建议。拿到SDK后,按这个顺序来:

  1. 先看 doc/:了解芯片能力、接口定义。
  2. 再跑 sample/:把示例编译运行一遍,验证开发环境。
  3. 然后读 mpp/include/:熟悉数据结构。
  4. 最后写自己的代码:基于 sample/ 修改,逐步实现功能。

遇到问题怎么办?先查 doc/,再试 tools/,最后看 osdrv/ 里的驱动源码。这个排查路径,我用了好几年,效率很高。

好了,目录结构就讲到这里。下一章,我们会深入 mpp 目录,看看视频编码通道到底是怎么配置的。到时候我会拿一个实际项目中的配置参数来讲解,保证你听完就能上手。