入职第一周:open Harmony框架源码分析

OH项目整体框架

  • 应用层(applicatons/)
    sample应该是应用样例,里面有cameraApp文件夹,相机应用
  • 框架层(foundation/)
  • 基础服务层(base)
  • 系统能力层(systemabilitymgr)
  • 运行时(arkcompiler/)
  • 驱动框架(drivers/+hdf)
  • 内核层(kernel/)
  • 板级适配(device/board/xhilink/xhd100)
  • 产品配置(vendor/xhilink/xhd100)

开发板

┌──────────── XH-D100 开发板(整块电路板)──────────────┐

│ │

│ ┌──────────┐ ┌──────┐ ┌──────┐ ┌──────┐ │

│ │ RK3568 │ │ RK809 │ │AP6256 │ │RTL8168 │ │

│ │ 主控SoC │──→│PMIC │ │WiFi │ │以太网 │ │

│ │ (大脑) │ │ 音频 │ │蓝牙 │ │ │ │

│ └──────────┘ └──────┘ └──────┘ └──────┘ │

│ │

│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │

│ │DDR4 │ │eMMC │ │ MIPI屏 │ │USB口 │ │千兆网口│ │

│ │4GB │ │64GB │ │ │ │ │ │×2 │ │

│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │

│ │

│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │

│ │ 扬声器 │ │ 麦克风 │ │ 摄像头 │ │RS485 │ │CAN口 │ │

│ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │

└────────────────────────────────────────────────────────┘

** 局部功能分析**

相机应用

cameraApp/

├── src/main/

│ ├── cpp/ # C++ 源码(业务逻辑 + UI)

│ │ ├── camera_ability.h # Ability 生命周期声明

│ │ ├── camera_ability.cpp # Ability 生命周期实现

│ │ ├── camera_ability_slice.h # 主界面 AbilitySlice(UI + 交互)

│ │ ├── camera_ability_slice.cpp

│ │ ├── camera_manager.h # 相机硬件管理封装

│ │ ├── camera_manager.cpp

│ │ ├── event_listener.h # 通用点击/长按事件监听器

│ │ └── ui_config.h # UI 布局常量配置

│ ├── resources/base/media/ # UI 资源图片

│ │ ├── camera.png

│ │ ├── ic_back.png

│ │ ├── ic_camera_photo.png

│ │ ├── ic_camera_record.png

│ │ └── ... (共 12 个图标)

│ └── config.json # 应用配置清单

camera_manager

相机硬件管理

TestFrameStateCallback回调类,重写onfinish()虚函数,实例被SampleCameraStateMng拥有

工作机制

相机硬件完成一帧拍摄

Camera 框架检测到帧完成

调用 FrameStateCallback::OnFrameFinished() ← 虚函数分发

执行 TestFrameStateCallback::OnFrameFinished() ← 你重写的实现

在这里保存照片文件、更新状态等

主要类分工

类名 职责
SampleCameraManager 顶层管理器,对外提供创建/预览/拍照/录像/暂停/停止接口
SampleCameraStateMng 相机状态回调管理,处理相机创建、预览、录像、拍照的实际执行
TestFrameStateCallback 帧回调处理,处理拍照完成事件

SampleCameraManager类

顶层管理类,操作封装暴露接口给ui层调用

SampleCameraManager::SampleCameraCreate()

获取cameraKit的单例->获取所有相机ID列表->检查列表是否为空->取第一个相机ID并校验->创建相机状态管理器->用该ID创建相机实例->创建保存目录

返回0成功,返回1失败。

我看这一部分逻辑他是直接取用获取列表ID的头一个进行判空操作,可能没有多摄像头或者切换摄像头的说法,只有后置摄像头。

SampleCameraManager::SampleCameraStart(Surface *surface)

启动相机预览,应该和以前摄像头操作一样从缓冲区拉取视频帧或者被动回调显示摄像头即时操作仅猜测,

TriggerLoopingCapture找到发现是虚函数,改写的位置在找,压根就没实现就只是一个虚函数。。。

UI 层 SampleCameraManager SampleCameraStateMng 相机框架

│ │ │ │

│ SampleCameraStart(surface) │ │ │

│─────────────────────────────────>│ │ │

│ │ StartPreview(surface) │ │

│ │───────────────────────────>│ │

│ │ │ new FrameConfig(PREVIEW) │

│ │ │ fc->AddSurface(surface) │

│ │ │ TriggerLoopingCapture(fc) │

│ │ │──────────────────────────>│

│ │ │ │

│ │ │ ← 持续写入帧到 Surface →│

│ ← UISurfaceView 自动从 Surface 读取并显示 ──────────────────────────────────────────────│

产品配置(vendor/xhilink/xhd100)

本项目适配rk3568(DAYU200),这个配置文件应该是厂商配置

目录 内容 性质
config.json 产品定义:选哪些子系统/组件 厂商定制
bluetooth/ 蓝牙固件(BCM4345C5.hcd)+ 驱动源码 硬件适配
hals/audio/ 音频策略配置、ALSA 适配 硬件适配
hdf_config/khdf/ HDF 驱动配置(音频/摄像头/传感器/WiFi/振动器等) 硬件适配
hdf_config/uhdf/ 用户态驱动配置(摄像头/编解码/USB) 硬件适配
etc/param/ 硬件/产品参数 厂商定制
power_config/ 电源模式/唤醒配置 厂商定制
preinstall-config/ 预装/卸载应用列表 厂商定制
security_config/ 安全配置(高权限进程/重启保护) 厂商定制
window_config/ 窗口/显示管理配置 厂商定制
resourceschedule/ 资源调度/性能配置 厂商定制
image_conf/ 系统镜像打包配置 厂商定制
default_app_config/ 默认应用配置 厂商定制

板级适配(device/board/xhilink/xhd100)

audio_drivers/ -音频驱动

codec/ → RK809 编解码芯片驱动(A/D、D/A 转换)

-rk809_codec

--rk809_codec_impl 核心数据结构

struct Rk809ChipData {

struct CodecData codec; // HDF Codec 框架数据

struct DaiData dai; // HDF DAI 框架数据

struct HdfDeviceObject *hdev; // HDF 设备对象

struct platform_device *pdev; // Linux platform 设备

struct regmap *regmap; // 寄存器映射(I2C/SPI 访问芯片寄存器)

};

参数枚举

RK809SampleRateTimes-采样率倍频系数

枚举值 含义
RK809_SRT_00 = 0x00 采样率倍频系数 0
RK809_SRT_01 = 0x01 采样率倍频系数 1
RK809_SRT_02 = 0x02 采样率倍频系数 2
RK809_SRT_03 = 0x03 采样率倍频系数 3

RK809PLLInputCLKPreDIV-PLL输入时钟预分频

枚举值 分频比
RK809_PREMODE_1 = 0x03 1 分频
RK809_PREMODE_2 = 0x06 2 分频
RK809_PREMODE_3 = 0x0C 4 分频
RK809_PREMODE_4 = 0x18 8 分频

RK809_VDW -音频数据位宽

枚举值 位宽
RK809_VDW_16BITS = 0x0F 16 bit(0x0F = 15,实际位宽 = 寄存器值 + 1)
RK809_VDW_24BITS = 0x17 24 bit(0x17 = 23)

Updata_Dest-寄存器更新目标

枚举值 含义
UPDATE_LREG = 0 更新左声道寄存器
UPDATE_RREG = 1 更新右声道寄存器

DAI参数结构RK809DaiParamsVal

保存DAI(数字音频接口)的运行时参数

struct RK809DaiParamsVal {

uint32_t frequencyVal; // 采样频率

uint32_t DataWidthVal; // 数据位宽

};

录音路径(ADC工作):

麦克风 -> ADC ->SoC

(声波)->(模拟电信号)->(数字0/1)->处理/存储

播放路径(DAC工作):

复制代码
                 DAC               扬声器   

SoC------>(数字0/1)--------->模拟电信号--------->声波

SoC VS Codec VS Dai

┌──────── RK3568 (SoC) ────────┐ ┌──── RK809 (Codec芯片) ────┐

│ │ │ │

│ I2S 控制器 (DAI 主端) ←──── I2S总线 ────→ I2S 控制器 (DAI 从端)│

│ │ │ ADC (模拟→数字) │

│ CPU 处理音频数据 │ │ DAC (数字→模拟) │

│ │ │ 模拟增益/音量 │

└───────────────────────────────┘ └────────────────────────────┘

驱动接口函数

codec侧(编解码芯片控制)

函数 功能
GetCodecDevice() 获取 RK809 芯片数据单例
Rk809DeviceInit() 芯片初始化(配置寄存器默认值)
Rk809DeviceRegRead() 读芯片寄存器(底层)
Rk809DeviceRegWrite() 写芯片寄存器(底层)
RK809CodecReadReg() Codec 框架层读寄存器
Rk809CodecWriteReg() Codec 框架层写寄存器
Rk809RegBitsUpdate() 更新寄存器指定位域(按位修改,不影响其他位)

Rk809DeviceInit()函数里面有个CodecDeviceInitRegConfig函数比较关键,这个函数会从获取初始参数存入到配置表initCfg,再逐行写入到寄存器完成初始化配置,每写一次会休息一下,配置表参数存放在vendor下面的hcs文件中

函数中有参数没用到我看他是只写出来不用,忽略警告用

DAI侧(数字音频接口控制)

函数 功能
Rk809DaiDeviceInit() DAI 初始化
Rk809DaiStartup() DAI 启动
Rk809DaiHwParams() 配置硬件参数(采样率、位宽等)
Rk809NormalTrigger() 触发控制(启动/停止/暂停/恢复)
RK809CodecDaiReadReg() DAI 寄存器读
RK809CodecDaiWriteReg() DAI 寄存器写

DAI侧相对于codec侧初始化的相关函数只写了判定,这个要等到上层HwParams调用才能判定,位宽多少,采样率多少要运行时判定

函数返回值可能是负数,但位宽一定是正数,所以设置变量的时候函数返回值是int32_t类型而位宽是uint32_t

最核心的其实是Rk809DaiHwParams和Rk809DaiHwParamsUpdate,Rk809DaiHwParams解析位宽选定参数组装DAI参数,用Rk809DaiHwParamsUpdate更新硬件寄存器。执行不同的操作时使用对应的配置表并操作寄存器

配置表 寄存器操作 用途
g_rk817RenderStartRegConfig DAC 使能 + I2S RX 启动 开始播放
g_rk817RenderStopRegConfig DAC 禁用 + I2S RX 停止 停止播放
g_rk817CaptureStartRegConfig ADC 使能 + I2S TX 启动 开始录音
g_rk817CaptureStopRegConfig ADC 禁用 + I2S TX 停止 停止录音

dai/ → RK3568 数字音频接口驱动(I2S/PCM)厂商提供的。

dsp/ → DSP 数字信号处理驱动

soc/ → DMA 直接内存访问驱动(音频数据搬运)

headset_monitor/ → 模拟耳机检测(ADC/GPIO 方式)

camera/ -摄像头驱动

子目录 功能
device_manager/ 传感器管理:IMX600(索尼传感器)、RKISPv5(瑞芯微 ISP)
driver_adapter/ V4L2 设备操作适配层
pipeline_core/ 图像处理管线节点:缩放、编解码、EXIF、人脸检测
demo/ 摄像头使用示例

kernel/ -内核构建

内容 说明
linux-5.10/ + linux-6.6/ 支持两个内核版本
configs/product_defconfig 内核编译配置(启用/禁用内核特性)
files/arch/arm64/boot/dts/rockchip/ 设备树文件(硬件描述)
files/drivers/net/can/ CAN 总线驱动(瑞芯微定制)
files/drivers/net/ethernet/realtek/ Realtek R8168 以太网驱动
patches/ 内核补丁(如 00_xhd100_kernel.patch 是 xhd100 专用补丁)
touchscreen/ 触摸屏驱动(GT911)
build_kernel.sh 内核编译脚本
logo.bmp 开机 Logo