OpenHarmony(鸿蒙南向开发)——标准系统方案之瑞芯微RK3566移植案例(下)

OpenHarmony Camera HDF驱动框架概述

OpenHarmony Camera驱动模型结构

  • HDI Implementation:对上实现HDI接口,向下调用框架层的接口,完成HDI接口任务的转发。
  • Buffer Manager:屏蔽不同内存管理的差异,为子系统提供统一的操作接口,同时提供buffer轮转的功能。
  • Pipeline Core:解析HCS配置完成pipeline的搭建,调度pipeline中的各个node完成流的处理
  • Device Manager:通过调用底层硬件适配层接口,实现查询控制底层设备、枚举监听底层设备的功能
  • Platform Adaption:屏蔽硬件差异,为Device Manager提供统一的操作底层硬件的能力

CameraService 进程

CameraService源码目录为:foundation/multimedia/camera_standard,camera app通过camera service与hal层进行交互

├── bundle.json
├── figures
├── frameworks                            camera frameworks部分,支持js和native转换
│   ├── js
│   └── native
├── hisysevent.yaml
├── interfaces                            CameraService接口
│   ├── inner_api
│   └── kits
├── LICENSE
├── OAT.xml
├── README.md
├── README_zh.md
├── sa_profile                            CameraService进程加载配置文件
│   ├── 3008.xml
│   └── BUILD.gn
└── services                            CameraService启动相关
    ├── camera_service
    └── etc

CameraService启动入口在foundation/multimedia/camera_standard/services/etc/camera_service.cfg进行启动配置

"services" : [{
        "name" : "camera_service",
        "path" : ["/system/bin/sa_main", "/system/profile/camera_service.xml"],
        "uid" : "cameraserver",
        "gid" : ["system", "shell"],
        "secon" : "u:r:camera_service:s0"
    }
]

Camera驱动框架介绍

Camera驱动整体架构

camera驱动源码分布

Camera 驱动框架所在的仓为:drivers_peripheral,源码目录为:“drivers/peripheral/camera”。

├── bundle.json
├── figures
│   ├── Camera模块驱动模型.png
│   └── logic-view-of-modules-related-to-this-repository_zh.png
├── hal
│   ├── adapter                    #平台适配层,适配平台
│   ├── buffer_manager
│   ├── BUILD.gn                    #Camera驱动框架构建入口
│   ├── camera.gni                #定义组件所使用的全局变量
│   ├── device_manager
│   ├── hdi_impl
│   ├── include
│   ├── init                        #demo sample
│   ├── pipeline_core
│   ├── test                        #测试代码
│   └── utils
├── hal_c                        #为海思平台提供专用C接口
│   ├── BUILD.gn
│   ├── camera.gni
│   ├── hdi_cif
│   └── include
├── interfaces                    #HDI接口
│   ├── hdi_ipc
│   ├── hdi_passthrough
│   ├── include
│   └── metadata
└── README_zh.md
Camera Host HDF驱动

配置文件

Camera Host HDF配置相关在“vendor/kaihong/khdvk_3566b/hdf_config/uhdf/device_info.hcs”

    hdi_server :: host {
        hostName = "camera_host";
        priority = 50;
        caps = ["DAC_OVERRIDE", "DAC_READ_SEARCH"];
        camera_device :: device {
             device0 :: deviceNode {
                 policy = 2;
                 priority = 100;
                 moduleName = "libcamera_hdi_impl.z.so";
                 serviceName = "camera_service";
             }
         }
        ...
    }    

其中主要参数说明如下:

  • hostName = “camera_host”:camera host节点,该节点为一个独立进程,如果需要独立进程,新增属于自己的host节点
  • policy = 2:服务发布策略,Camera使用HDI服务,需设置为2
  • moduleName:camera host驱动实现库名
  • serviceName:服务名称,请保持全局唯一性,后面HDF Manager会根据这个名称拉起camera hdf

camera host服务启动 camera host 服务由hdf_devhost启动,配置文件存放于vendor/etc/init/hdf_devhost.cfg

    {
        "name" : "camera_host",
        "path" : ["/vendor/bin/hdf_devhost", "8", "camera_host"],
        "uid" : "camera_host",
        "gid" : ["camera_host"],
        "caps" : ["DAC_OVERRIDE", "DAC_READ_SEARCH"],
        "secon" : "u:r:camera_host:s0"
    }

Camera host驱动实现 代码路径:drivers/peripheral/camera/interfaces/hdi_ipc/server/src/camera_host_driver.cpp

驱动入口结构体,后面将该结构体注册进HDF框架中

struct HdfDriverEntry g_cameraHostDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "camera_service",
    .Bind = HdfCameraHostDriverBind,
    .Init = HdfCameraHostDriverInit,
    .Release = HdfCameraHostDriverRelease,
};

消息发布服务

static int32_t CameraServiceDispatch(struct HdfDeviceIoClient *client, int cmdId,
    struct HdfSBuf *data, struct HdfSBuf *reply)
{
    HdfCameraService *hdfCameraService = CONTAINER_OF(client->device->service, HdfCameraService, ioservice);
    return CameraHostServiceOnRemoteRequest(hdfCameraService->instance, cmdId, data, reply);
}

参数说明:

client:HdfDeviceIoClient设备句柄
cmdId:请求消息命令字
data:其他服务或者IO请求数据
reply:存储返回消息内容数据

绑定服务:初始化设备服务对象和资源对象

int HdfCameraHostDriverBind(HdfDeviceObject *deviceObject)
{
    ...
    hdfCameraService->ioservice.Dispatch = CameraServiceDispatch;
    hdfCameraService->ioservice.Open = nullptr;
    hdfCameraService->ioservice.Release = nullptr;
    hdfCameraService->instance = CameraHostStubInstance();

    deviceObject->service = &hdfCameraService->ioservice;
    return HDF_SUCCESS;
}

相关说明:

hdfCameraService->ioservice.Dispatch:注册消息分发服务接口
hdfCameraService->instance:创建camerahost实例

驱动初始化函数: 探测并初始化驱动程序

int HdfCameraHostDriverInit(struct HdfDeviceObject *deviceObject)
{
    return HDF_SUCCESS;
}

驱动资源释放函数 : 如已经绑定的设备服务对象

void HdfCameraHostDriverRelease(HdfDeviceObject *deviceObject)
{
    if (deviceObject == nullptr || deviceObject->service == nullptr) {
        HDF_LOGE("%{public}s deviceObject or deviceObject->service  is NULL!", __FUNCTION__);
        return;
    }
    HdfCameraService *hdfCameraService = CONTAINER_OF(deviceObject->service, HdfCameraService, ioservice);
    if (hdfCameraService == nullptr) {
        HDF_LOGE("%{public}s hdfCameraService is NULL!", __FUNCTION__);
        return;
    }
    OsalMemFree(hdfCameraService);
}

设备创建不成功,关闭服务,释放相关资源

DeviceManager

创建SensorManager、FlashManager、ISPManager管理相应的设备。

SensorManager sensor Manager结构如下
class SensorManager : public IManager {
public:
    SensorManager();
    explicit SensorManager(ManagerId managerId);
    virtual ~SensorManager();
    RetCode CreateController(ControllerId controllerId, std::string hardwareName);
    RetCode DestroyController(ControllerId controllerId, std::string hardwareName);
    std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);

    void Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode Start(std::string hardwareName, int buffCont, DeviceFormat& format);
    RetCode Stop(std::string hardwareName);
    RetCode PowerUp(std::string hardwareName);
    RetCode PowerDown(std::string hardwareName);
    std::shared_ptr<ISensor> GetSensor(std::string sensorName);

    RetCode SendFrameBuffer(std::shared_ptr<FrameSpec> buffer, std::string hardwareName);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName);
    void SetNodeCallBack(const NodeBufferCb cb, std::string hardwareName);
    void SetMetaDataCallBack(const MetaDataCb cb, std::string hardwareName);

private:
    bool CheckCameraIdList(std::string hardwareName);
    std::vector<std::shared_ptr<SensorController>> sensorList_;
};
} 

PowerUp为上电接口,OpenCamera时调用此接口进行设备上电操作

PowerDown为下电接口,CloseCamera时调用此接口进行设备下电操作

Configures为Metadata下发接口,如需设置metadata参数到硬件设备,可实现此接口进行解析及下发

Start为硬件模块使能接口,pipeline中的各个node进行使能的时候,会去调用,可根据需要定义实现,比如sensor的起流操作就可放在此处进行实现,Stop和Start为相反操作,可实现停流操作

SendFrameBuffer为每一帧buffer下发接口,所有和驱动进行buffer交互的操作,都是通过此接口进行的

SetNodeCallBack为pipeline,通过此接口将buffer回调函数设置到devicemanager

SetMetaDataCallBack为metadata回调接口,通过此接口将从底层获取的metadata数据上报给上层

BufferCallback上传每一帧已填充数据buffer的接口,通过此接口将buffer上报给pipeline

SetAbilityMetaDataTag设置需要从底层获取哪些类型的metadata数据,因为框架支持单独获取某一类型或多类型的硬件设备信息,所以可以通过此接口,获取想要的metadata数据

Camera Sensor Controller结构如下:

class SensorController : public IController {
public:
    SensorController();
    explicit SensorController(std::string hardwareName);
    virtual ~SensorController();
    RetCode Init();
    RetCode PowerUp();
    RetCode PowerDown();
    RetCode Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode Start(int buffCont, DeviceFormat& format);
    RetCode Stop();
    ...
    void SetMetaDataCallBack(MetaDataCb cb) override;
    void BufferCallback(std::shared_ptr<FrameSpec> buffer);

    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag);
    RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta);
    RetCode Flush(int32_t streamId);
    ...

};

PowerUp下发命令给v4l2 dev去操作实际设备进行上电操作 PowerDown下发命令给v4l2 dev去操作实际设备进行下电操作 同理其他操作参考SensorManager. ####FlashManager Flash Manger结构如下:

class FlashManager : public IManager {
public:
    FlashManager();
    explicit FlashManager(ManagerId managerId);
    virtual ~FlashManager();
    RetCode CreateController(ControllerId controllerId, std::string hardwareName);
    std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);
    RetCode PowerUp(std::string hardwareName);
    RetCode PowerDown(std::string hardwareName);
    void Configure(std::shared_ptr<CameraMetadata> meta);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName)
    {
        (void)abilityMetaDataTag;
        (void)hardwareName;
        return;
    }
    RetCode SetFlashlight(FlashMode flashMode, bool enable, std::string hardwareName);
private:
    bool CheckCameraIdList(std::string hardwareName);
    std::vector<std::shared_ptr<FlashController>> flashList_;
}

Flash controller结构如下:

class FlashController : public IController {
public:
    FlashController();
    explicit FlashController(std::string hardwareName);
    virtual ~FlashController();
    RetCode Init();
    RetCode PowerUp();
    RetCode PowerDown();
    RetCode Configure(std::shared_ptr<CameraMetadata> meta)
    {
        (void)meta;
        return RC_OK;
    }
    RetCode SetFlashlight(FlashMode flashMode, bool enable);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag);
    RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta);
private:
    std::mutex startVolock_;
    bool startVoState_ = false;
}
ISPManager ISP Manager结构如下
class IspManager : public IManager {
public:
    IspManager();
    explicit IspManager(ManagerId managerId);
    virtual ~IspManager();
    RetCode CreateController(ControllerId controllerId, std::string hardwareName);
    std::shared_ptr<IController> GetController(ControllerId controllerId, std::string hardwareName);
    void Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode Start(std::string hardwareName);
    RetCode Stop(std::string hardwareName);
    RetCode PowerUp(std::string hardwareName);
    RetCode PowerDown(std::string hardwareName);
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag, std::string hardwareName)
    {
        (void)abilityMetaDataTag;
        (void)hardwareName;
        return;
    }
private:
    bool CheckCameraIdList(std::string hardwareName);
    std::vector<std::shared_ptr<IspController>> ispList_;
};

ISP controller结构如下

class IspController : public IController {
public:
    IspController();
    explicit IspController(std::string hardwareName);
    virtual ~IspController();
    RetCode Init();
    RetCode Configure(std::shared_ptr<CameraMetadata> meta);
    RetCode PowerUp();
    RetCode PowerDown();
    RetCode Stop();
    RetCode Start();
    void SetAbilityMetaDataTag(std::vector<int32_t> abilityMetaDataTag)
    {
        (void)abilityMetaDataTag;
        return;
    }
    RetCode GetAbilityMetaData(std::shared_ptr<CameraMetadata> meta)
    {
        (void)meta;
        return RC_OK;
    }
private:
    std::mutex startIsplock_;
    bool startIspState_ = false;
}

PlatForm Adapter

这部分通过V4l2框架对video设备进行管理,包括对相应设备的打开、启动/关闭数据流、设置/获取图像格式等等

源代码 V4l2 Adapter 源码位于driver/peripheral/camera/hal/adapter/platform/v4l2/src/driver_adapter 部分关键函数如下:
class HosV4L2Dev {
public:
    ...
    RetCode start(const std::string& cameraID);

    RetCode stop(const std::string& cameraID);
    RetCode CreatBuffer(const std::string& cameraID, const std::shared_ptr<FrameSpec>&
### 下载适用于瑞芯微RK3566的内核 对于获取适用于瑞芯微RK3566平台的Linux内核源码,官方GitHub仓库提供了最新的稳定版本和支持。访问地址如下: - 访问瑞芯微官方GitHub页面:[https://github.com/rockchip-linux](https://github.com/rockchip-linux) 具体操作流程如下所示: #### 获取内核源码 通过命令行工具Git克隆指定分支中的RK3566相关内核源码库: ```bash git clone https://github.com/rockchip-linux/kernel.git -b rockchip-rk356x-v5.10.y rk3566_kernel_source ``` 此命令会创建名为`rk3566_kernel_source`的新目录来保存所下载的内容。 #### 配置开发环境 确保已安装必要的编译依赖项,如GCC、Make等构建工具以及交叉编译器链。针对ARM架构的目标设备,推荐使用GNU Arm Embedded Toolchain作为交叉编译解决方案[^1]。 #### 编译配置文件准备 进入刚刚克隆下来的源代码根目录并执行以下指令初始化默认配置: ```bash cd rk3566_kernel_source make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rk3568-evb_defconfig ``` 这里选择了适合RK356X系列芯片组评估板的标准配置模板;如果目标硬件有所不同,则需调整为相应的defconfig选项。 完成上述步骤之后即可开始正式编译过程,在实际应用过程中可能还需要进一步修改`.config`文件以适应特定需求或启用额外驱动模块支持(例如VI5301传感器的支持可以通过编辑misc路径下的kconfig文件实现[source "drivers/input/misc/vi530x/Kconfig"](endif之前添加))。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值