【OpenHarmony】外部设备管理器架构
外部设备管理器(External Device Manager)架构
1. 模块概述
源码:https://gitee.com/openharmony/drivers_external_device_manager
1.1 功能与目标
外部设备管理器(External Device Manager)是OpenHarmony系统中用于管理可插拔外部设备的核心组件。主要功能包括:
- 设备生命周期管理:实现外部设备的注册、查询、绑定和解绑定
- 驱动包管理:支持扩展驱动包的安装、更新、卸载和运行
- 总线扩展支持:提供USB等总线的扩展插件机制
- 设备驱动匹配:自动匹配设备与驱动包
- DDK接口开放:为驱动开发者提供USB、HID、SCSI等DDK接口
设计目标:
- 为设备厂商提供低成本的扩展外部设备驱动开发方案
- 实现即插即用的用户体验
- 支持非标准协议的可插拔设备驱动接入
- 提供安全、高效的驱动包生命周期管理
1.2 系统位置
本模块位于OpenHarmony驱动子系统(HDF)中,作为核心系统服务运行:
- 子系统:HDF(Hardware Driver Framework)
- 部件名称:external_device_manager
- 系统能力:
- SystemCapability.Driver.ExternalDevice
- SystemCapability.Driver.USB.Extension
- SystemCapability.Driver.DDK.Extension
- 服务ID:5110(系统服务)
模块在系统中的位置:
1.3 设计思路与模式
设计思路:
- 分层架构:采用经典的分层设计,从应用接口层到驱动访问层逐层解耦
- 插件化扩展:总线扩展采用插件机制,支持动态加载不同总线类型
- 事件驱动:设备热插拔通过事件订阅机制通知上层
- 能力化驱动:驱动包基于Ability框架,实现标准化管理
设计模式:
- 单例模式:核心管理类(ExtDeviceManager、DriverPkgManager、BusExtensionCore)采用单例模式
- 工厂模式:设备信息和驱动信息的创建使用工厂方法
- 观察者模式:设备变化回调、驱动变化回调采用观察者模式
- 策略模式:不同总线类型的匹配策略通过IBusExtension接口实现
- 代理模式:客户端通过DriverExtMgrClient代理访问系统服务
1.4 系统框图
2. 模块结构
2.1 源文件与头文件
2.1.1 核心服务模块
服务主入口:
services/native/driver_extension_manager/src/driver_ext_mgr.cpp
services/native/driver_extension_manager/include/driver_ext_mgr.h
设备管理模块:
services/native/driver_extension_manager/src/device_manager/etx_device_mgr.cpp
services/native/driver_extension_manager/src/device_manager/device.cpp
services/native/driver_extension_manager/include/device_manager/etx_device_mgr.h
services/native/driver_extension_manager/include/device_manager/device.h
驱动包管理模块:
services/native/driver_extension_manager/src/drivers_pkg_manager/driver_pkg_manager.cpp
services/native/driver_extension_manager/include/drivers_pkg_manager/driver_pkg_manager.h
services/native/driver_extension_manager/include/drivers_pkg_manager/pkg_database.h
驱动能力控制器:
services/native/driver_extension_manager/src/device_manager/driver_extension_controller.cpp
services/native/driver_extension_manager/include/device_manager/driver_extension_controller.h
总线扩展核心:
services/native/driver_extension_manager/src/bus_extension/core/bus_extension_core.cpp
services/native/driver_extension_manager/include/bus_extension/core/bus_extension_core.h
USB总线扩展插件:
services/native/driver_extension_manager/src/bus_extension/usb/usb_bus_extension.cpp
services/native/driver_extension_manager/include/bus_extension/usb/usb_bus_extension.h
services/native/driver_extension_manager/include/bus_extension/usb/usb_device_info.h
2.1.2 客户端接口模块
内部接口:
interfaces/innerkits/driver_ext_mgr_client.h
interfaces/innerkits/driver_ext_mgr_types.h
frameworks/native/driver_ext_mgr_client.cpp
IDL接口定义:
interfaces/innerkits/IDriverExtMgr.idl
interfaces/innerkits/IDriverExtMgrCallback.idl
2.1.3 DDK接口模块
USB DDK:
interfaces/ddk/usb/usb_ddk_api.h
interfaces/ddk/usb/usb_ddk_types.h
frameworks/ddk/usb/usb_ddk_api.cpp
基础DDK:
interfaces/ddk/base/ddk_api.h
interfaces/ddk/base/ddk_types.h
frameworks/ddk/base/ddk_api.cpp
其他DDK:
- HID DDK:
interfaces/ddk/hid/
- SCSI DDK:
interfaces/ddk/scsi/
- USB Serial DDK:
interfaces/ddk/usb_serial/
2.1.4 工具类模块
公共工具:
utils/include/edm_errors.h
- 错误码定义utils/include/ext_object.h
- 基础对象定义utils/include/ibus_extension.h
- 总线扩展接口utils/include/hilog_wrapper.h
- 日志封装
2.2 核心类结构
2.2.1 DriverExtMgr类
功能:系统服务主类,负责整体协调和对外接口提供
class DriverExtMgr : public SystemAbility, public DriverExtMgrStub {
public:// 系统能力生命周期void OnStart() override;void OnStop() override;void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId);// 设备操作接口ErrCode QueryDevice(int32_t &errorCode, uint32_t busType,std::vector<std::shared_ptr<DeviceData>> &devices);ErrCode BindDevice(int32_t &errorCode, uint64_t deviceId,const sptr<IDriverExtMgrCallback> &connectCallback);ErrCode UnBindDevice(int32_t &errorCode, uint64_t deviceId);// 设备和驱动信息查询ErrCode QueryDeviceInfo(int32_t &errorCode,std::vector<std::shared_ptr<DeviceInfoData>> &deviceInfos,bool isByDeviceId, const uint64_t deviceId);ErrCode QueryDriverInfo(int32_t &errorCode,std::vector<std::shared_ptr<DriverInfoData>> &driverInfos,bool isByDriverUid, const std::string &driverUid);private:std::mutex connectCallbackMutex;std::map<uint64_t, std::vector<sptr<IDriverExtMgrCallback>>> connectCallbackMap;EventConfig eventConfig_;
};
关键成员:
connectCallbackMap
: 设备连接回调映射表eventConfig_
: 事件配置管理器
2.2.2 ExtDeviceManager类
功能:设备管理器,负责设备注册、查询、绑定、解绑定
class ExtDeviceManager final {DECLARE_SINGLE_INSTANCE_BASE(ExtDeviceManager);public:// 初始化int32_t Init();// 设备注册与注销int32_t RegisterDevice(shared_ptr<DeviceInfo> devInfo);int32_t UnRegisterDevice(const shared_ptr<DeviceInfo> devInfo);// 设备查询vector<shared_ptr<DeviceInfo>> QueryDevice(const BusType busType);vector<shared_ptr<Device>> QueryAllDevices();vector<shared_ptr<Device>> QueryDevicesById(const uint64_t deviceId);// 设备连接与断开int32_t ConnectDevice(uint64_t deviceId, uint32_t callingTokenId,const sptr<IDriverExtMgrCallback> &connectCallback);int32_t DisConnectDevice(uint64_t deviceId, uint32_t callingTokenId);// 驱动匹配void MatchDriverInfos(std::unordered_set<uint64_t> deviceIds);void SetDriverChangeCallback(shared_ptr<IDriverChangeCallback> &callback);private:// 设备映射表:总线类型 -> 设备ID -> Device对象unordered_map<BusType, unordered_map<uint64_t, shared_ptr<Device>>> deviceMap_;// 驱动匹配表:驱动UID -> 设备ID集合unordered_map<string, unordered_set<uint64_t>> bundleMatchMap_;mutex deviceMapMutex_;mutex bundleMatchMapMutex_;
};
关键数据结构:
deviceMap_
: 按总线类型和设备ID组织的设备对象映射bundleMatchMap_
: 驱动包与设备的匹配关系表
2.2.3 Device类
功能:设备对象,表示一个具体的外部设备
class Device : public std::enable_shared_from_this<Device> {
public:explicit Device(std::shared_ptr<DeviceInfo> info);// 连接与断开int32_t Connect();int32_t Connect(const sptr<IDriverExtMgrCallback> &connectCallback,uint32_t callingTokenId);int32_t Disconnect(const bool isFromBind);// 驱动信息管理bool HasDriver() const;std::shared_ptr<DriverInfo> GetDriverInfo() const;void AddBundleInfo(const std::string &bundleInfo,const std::shared_ptr<DriverInfo> &driverInfo);void RemoveBundleInfo();// 远程对象管理sptr<IRemoteObject> GetDrvExtRemote();void UpdateDrvExtRemote(const sptr<IRemoteObject> &remote);private:std::shared_ptr<DeviceInfo> info_; // 设备信息std::shared_ptr<DriverInfo> driverInfo_; // 匹配的驱动信息std::string bundleInfo_; // Bundle信息sptr<IRemoteObject> drvExtRemote_; // 驱动Extension远程对象std::set<sptr<IDriverExtMgrCallback>> callbacks_; // 回调集合std::unordered_map<uint32_t, CallerInfo> boundCallerInfos_; // 调用者信息
};
2.2.4 DriverPkgManager类
功能:驱动包管理器,负责驱动包的安装、更新、查询和匹配
class DriverPkgManager {DECLARE_SINGLE_INSTANCE_BASE(DriverPkgManager);public:// 初始化int32_t Init();int32_t Init(shared_future<int32_t> bmsFuture,shared_future<int32_t> accountFuture,shared_future<int32_t> commEventFuture);// 驱动查询与匹配shared_ptr<DriverInfo> QueryMatchDriver(shared_ptr<DeviceInfo> devInfo,const std::string &type = "");int32_t QueryDriverInfo(vector<shared_ptr<DriverInfo>> &driverInfos,bool isByDriverUid, const std::string &driverUid);// 驱动包更新回调int32_t RegisterOnBundleUpdate(PCALLBACKFUN pFun);int32_t RegisterBundleCallback(std::shared_ptr<IBundleUpdateCallback> callback);private:shared_ptr<BundleMonitor> bundleMonitor_;sptr<DrvBundleStateCallback> bundleStateCallback_;
};
2.2.5 BusExtensionCore类
功能:总线扩展核心,管理各种总线类型的扩展插件
class BusExtensionCore {DECLARE_SINGLE_INSTANCE_BASE(BusExtensionCore);public:// 初始化int32_t Init(std::shared_ptr<IDevChangeCallback> callback);// 总线扩展注册int32_t Register(BusType busType, std::shared_ptr<IBusExtension> busExtension);// 获取总线扩展std::shared_ptr<IBusExtension> GetBusExtensionByName(std::string busName);static BusType GetBusTypeByName(const std::string &busName);// 加载总线扩展库void LoadBusExtensionLibs();// 驱动变化回调std::shared_ptr<IDriverChangeCallback> AcquireDriverChangeCallback(BusType busType);private:std::unordered_map<BusType, std::shared_ptr<IBusExtension>> busExtensions_;static std::unordered_map<std::string, BusType> busTypeMap_;
};
2.2.6 IBusExtension接口
功能:总线扩展接口,定义各总线类型插件需实现的方法
class IBusExtension {
public:virtual ~IBusExtension() = default;// 解析驱动信息virtual shared_ptr<DriverInfoExt> ParseDriverInfo(const map<string, string> &metadata) = 0;// 创建驱动信息扩展对象virtual shared_ptr<DriverInfoExt> GetNewDriverInfoExtObject() = 0;// 匹配驱动virtual bool MatchDriver(const DriverInfo &driver,const DeviceInfo &device, const std::string &type = "") = 0;// 设置设备变化回调virtual int32_t SetDevChangeCallback(shared_ptr<IDevChangeCallback> callback) = 0;// 获取总线类型virtual BusType GetBusType() = 0;// 获取驱动变化回调virtual shared_ptr<IDriverChangeCallback> AcquireDriverChangeCallback() = 0;
};
2.2.7 UsbBusExtension类
功能:USB总线扩展实现
class UsbBusExtension : public IBusExtension {
public:UsbBusExtension();~UsbBusExtension();// 实现IBusExtension接口int32_t SetDevChangeCallback(shared_ptr<IDevChangeCallback> callback) override;bool MatchDriver(const DriverInfo &driver, const DeviceInfo &device,const std::string &type = "") override;shared_ptr<DriverInfoExt> ParseDriverInfo(const map<string, string> &metadata) override;BusType GetBusType() override;// USB特定接口void SetUsbInferface(sptr<IUsbInterface> iusb);void SetUsbDdk(sptr<IUsbDdk> iUsbDdk);private:sptr<UsbDevSubscriber> subScriber_; // USB设备订阅器sptr<IUsbDdk> iUsbDdk_; // USB DDK接口sptr<IUsbInterface> usbInterface_; // USB HDI接口
};
2.2.8 DriverExtensionController类
功能:驱动扩展能力控制器,管理驱动Extension的生命周期
class DriverExtensionController {DECLARE_SINGLE_INSTANCE_BASE(DriverExtensionController);public:// 启动和停止扩展int32_t StartDriverExtension(const std::string& bundleName,const std::string& abilityName);int32_t StopDriverExtension(const std::string& bundleName,const std::string& abilityName, int32_t userId = -1);// 连接和断开扩展int32_t ConnectDriverExtension(const std::string& bundleName,const std::string& abilityName,std::shared_ptr<IDriverExtensionConnectCallback> callback,uint32_t deviceId = 0);int32_t DisconnectDriverExtension(const std::string& bundleName,const std::string& abilityName,std::shared_ptr<IDriverExtensionConnectCallback> callback,uint32_t deviceId = 0);
};
2.3 基础数据结构
2.3.1 DeviceInfo类
class DeviceInfo {
public:DeviceInfo(uint32_t busDeviceId, BusType busType, const std::string &description);BusType GetBusType() const;uint64_t GetDeviceId() const;uint32_t GetBusDevId() const;const std::string& GetDeviceDescription() const;private:union DevInfo {uint64_t deviceId;struct {BusType busType;uint32_t busDeviceId;} devBusInfo;} devInfo_;std::string description_;
};
2.3.2 DriverInfo类
class DriverInfo : public DriverInfoExt {
public:DriverInfo(const std::string &bundleName, const std::string &driverName,const std::string &driverUid = "", const int32_t userId = -1);// Getter方法std::string GetBusName() const;BusType GetBusType() const;std::string GetDriverUid() const;std::string GetBundleName() const;std::string GetDriverName() const;bool GetLaunchOnBind() const;private:std::string bus_;BusType busType_;std::string driverUid_;int32_t userId_;std::string bundleName_;std::string driverName_;std::string version_;std::string description_;bool launchOnBind_;std::shared_ptr<DriverInfoExt> driverInfoExt_;
};
2.3.3 错误码定义
enum UsbErrCode : int32_t {EDM_OK = 0,EDM_NOK,EDM_ERR_GET_SYSTEM_ABILITY_MANAGER_FAILED,EDM_ERR_GET_SERVICE_FAILED,EDM_ERR_CONNECTION_FAILED,EDM_ERR_NOT_SUPPORT,EDM_ERR_INVALID_PARAM,EDM_ERR_INVALID_OBJECT,EDM_EER_MALLOC_FAIL,EDM_ERR_TIMEOUT,EDM_ERR_DEVICE_BUSY,EDM_ERR_IO,EDM_ERR_NO_PERM,EDM_ERR_OUT_OF_RANGE,EDM_ERR_JSON_PARSE_FAIL,EDM_ERR_JSON_OBJ_ERR,EDM_ERR_USB_ERR,EDM_ERR_NOT_SYSTEM_APP,EDM_ERR_SERVICE_NOT_ALLOW_ACCESS,EDM_ERR_SERVICE_NOT_BOUND,
};
2.4 类图
2.5 模块内部依赖框图
3. 模块间交互
3.1 与应用层交互
交互方式:
- JS API层:通过NAPI(Native API)提供JavaScript接口
- 跨进程通信:使用OpenHarmony IPC机制(基于Binder)
- 回调机制:通过IDriverExtMgrCallback接口异步通知应用
主要接口:
-
查询设备:
// JS侧调用 deviceManager.queryDevices(BusType.USB)// C++侧处理流程: NAPI -> IPC -> DriverExtMgr::QueryDevice()-> ExtDeviceManager::QueryDevice()-> 返回设备列表
-
绑定设备:
// JS侧调用 deviceManager.bindDevice(deviceId, callback)// C++侧处理流程: NAPI -> IPC -> DriverExtMgr::BindDevice()-> ExtDeviceManager::ConnectDevice()-> Device::Connect()-> DriverExtensionController::ConnectDriverExtension()-> Ability Framework启动驱动Extension-> 回调通知: IDriverExtMgrCallback::OnConnect()
3.2 与Bundle子系统交互
交互描述:
- 监听驱动包的安装、更新、卸载事件
- 查询已安装的驱动包信息
- 解析驱动包的metadata元数据
实现机制:
DriverPkgManager├── BundleMonitor (包监控器)│ └── 订阅CommonEvent事件│ - COMMON_EVENT_PACKAGE_ADDED│ - COMMON_EVENT_PACKAGE_CHANGED│ - COMMON_EVENT_PACKAGE_REMOVED│└── DrvBundleStateCallback└── 实现BundleStatusCallback接口- OnBundleAdded()- OnBundleUpdated()- OnBundleRemoved()
数据流:
3.3 与HDF驱动框架交互
交互描述:
- 通过HDI接口访问USB/HID等硬件设备
- 订阅设备热插拔事件
- 提供DDK接口给驱动扩展包使用
USB总线交互示例:
UsbBusExtension├── 依赖IUsbInterface (USB HDI v1.0)│ ├── GetDevices() - 获取USB设备列表│ ├── GetPorts() - 获取USB端口状态│ └── SubscribeDeviceEvent() - 订阅设备事件│└── 依赖IUsbDdk (USB DDK v1.1)├── Init() - 初始化DDK├── GetDeviceDescriptor() - 获取设备描述符├── ClaimInterface() - 声明接口└── SendPipeRequest() - 发送管道请求
设备热插拔流程:
3.4 与Ability Framework交互
交互描述:
- 启动和停止Driver Extension Ability
- 连接和断开Driver Extension服务
- 管理Extension生命周期
Driver Extension能力管理:
DriverExtensionController↓ (使用Ability Manager)
AbilityManagerClient↓ (IPC调用)
Ability Manager Service↓ (启动Extension)
Driver Extension Ability├── OnCreate() - 创建├── OnConnect() - 连接├── OnDisconnect() - 断开└── OnDestroy() - 销毁
连接流程:
3.5 与账户子系统交互
交互描述:
- 监听用户账户切换事件
- 根据用户账户管理驱动包权限
- 多用户场景下的驱动包隔离
实现:
DriverOsAccountSubscriber↓ (订阅账户事件)
OS Account Manager↓ (账户切换通知)
DriverPkgManager↓ (清理旧用户驱动)
ExtDeviceManager::ClearMatchedDrivers(userId)↓ (加载新用户驱动)
重新匹配驱动
3.6 外部依赖框图
说明:
- BMS: Bundle Manager Service (包管理服务)
- AMS: Ability Manager Service (能力管理服务)
- CES: Common Event Service (公共事件服务)
- OAM: OS Account Manager (账户管理服务)
- USB HDI: USB Hardware Device Interface
- HDF: Hardware Driver Foundation
4. 状态机转换图
4.1 设备状态机模型
设备对象(Device)在其生命周期中会经历多种状态转换:
状态定义:
- 未注册(Unregistered): 设备尚未在系统中注册
- 已注册(Registered): 设备已注册但未匹配驱动
- 已匹配(Matched): 设备已匹配到驱动但未连接
- 连接中(Connecting): 正在建立与驱动Extension的连接
- 已连接(Connected): 已成功连接到驱动Extension
- 断开中(Disconnecting): 正在断开连接
- 已注销(Unregistered): 设备已从系统中注销
4.2 设备状态机树图
4.3 设备状态转换图
4.4 状态机切换规则
4.4.1 状态转换条件
当前状态 | 触发事件 | 转换条件 | 目标状态 |
---|---|---|---|
未注册 | RegisterDevice() | 设备插入事件 | 已注册 |
已注册 | MatchDriverInfos() | 找到匹配的驱动包 | 已匹配 |
已匹配 | Connect() | 应用调用绑定接口 | 连接中 |
连接中 | OnConnectDone() | Extension连接成功 | 已连接 |
连接中 | OnConnectDone() (失败) | Extension连接失败 | 已匹配 |
已连接 | Disconnect() | 应用调用解绑接口 | 断开中 |
断开中 | OnDisconnectDone() | Extension断开完成 | 已匹配 |
任意状态 | UnRegisterDevice() | 设备拔出事件 | 已注销 |
已匹配 | RemoveDriverInfo() | 驱动包卸载 | 已注册 |
4.4.2 事件触发机制
外部事件:
- 设备插入/拔出:由USB总线扩展监听底层事件触发
- 驱动包安装/卸载:由Bundle子系统通知触发
- 应用绑定/解绑:由应用通过API调用触发
内部事件:
- 驱动匹配完成:内部匹配算法执行后触发
- Extension连接回调:Ability Framework回调触发
- 超时事件:定时器触发
事件处理流程:
// 设备插入事件处理
void OnDeviceAdd(shared_ptr<DeviceInfo> devInfo) {// 1. 注册设备ExtDeviceManager::RegisterDevice(devInfo);// 2. 触发驱动匹配auto driverInfo = DriverPkgManager::QueryMatchDriver(devInfo);if (driverInfo != nullptr) {// 3. 状态转换: 已注册 -> 已匹配device->AddBundleInfo(bundleInfo, driverInfo);}
}// 应用绑定事件处理
int32_t ConnectDevice(uint64_t deviceId, Callback callback) {auto device = QueryDeviceByDeviceID(deviceId);if (!device->HasDriver()) {return EDM_ERR_NO_DRIVER_MATCHED;}// 状态转换: 已匹配 -> 连接中return device->Connect(callback);
}// Extension连接成功回调
void OnConnectDone(IRemoteObject *remote, int resultCode) {if (resultCode == SUCCESS) {// 状态转换: 连接中 -> 已连接device->UpdateDrvExtRemote(remote);// 通知应用callback->OnConnect(deviceId, remote, errMsg);} else {// 状态转换: 连接中 -> 已匹配device->ClearDrvExtRemote();callback->OnConnect(deviceId, nullptr, errMsg);}
}
4.5 驱动包状态机
驱动包(Driver Package)也有自己的生命周期状态:
状态定义:
- 未安装(NotInstalled): 驱动包尚未安装
- 已安装(Installed): 驱动包已安装
- 已加载(Loaded): 驱动包信息已加载到内存
- 运行中(Running): 驱动Extension正在运行
- 更新中(Updating): 驱动包正在更新
- 卸载中(Uninstalling): 驱动包正在卸载
驱动包状态转换图:
5. 接口设计
5.1 公共接口
5.1.1 DriverExtMgrClient客户端接口
头文件:interfaces/innerkits/driver_ext_mgr_client.h
接口列表:
class DriverExtMgrClient {
public:// 查询设备接口UsbErrCode QueryDevice(uint32_t busType,std::vector<std::shared_ptr<DeviceData>> &devices);// 绑定设备接口UsbErrCode BindDevice(uint64_t deviceId,const sptr<IDriverExtMgrCallback> &connectCallback);// 解绑设备接口UsbErrCode UnBindDevice(uint64_t deviceId);// 通过设备ID绑定驱动UsbErrCode BindDriverWithDeviceId(uint64_t deviceId,const sptr<IDriverExtMgrCallback> &connectCallback);// 通过设备ID解绑驱动UsbErrCode UnbindDriverWithDeviceId(uint64_t deviceId);// 查询设备信息UsbErrCode QueryDeviceInfo(std::vector<std::shared_ptr<DeviceInfoData>> &deviceInfos);// 根据设备ID查询设备信息UsbErrCode QueryDeviceInfo(const uint64_t deviceId,std::vector<std::shared_ptr<DeviceInfoData>> &deviceInfos);// 查询驱动信息UsbErrCode QueryDriverInfo(std::vector<std::shared_ptr<DriverInfoData>> &driverInfos);// 根据驱动UID查询驱动信息UsbErrCode QueryDriverInfo(const std::string &driverUid,std::vector<std::shared_ptr<DriverInfoData>> &driverInfos);// 通知USB外设故障UsbErrCode NotifyUsbPeripheralFault(const std::string &domain,const std::string &faultName);
};
接口详细说明:
-
QueryDevice - 查询设备
- 功能:根据总线类型查询当前系统中的外部设备列表
- 参数:
busType
: 总线类型(1-USB, 其他类型待扩展)devices
: [输出] 设备数据列表
- 返回值:错误码(0表示成功)
- 异常处理:连接服务失败返回EDM_ERR_GET_SERVICE_FAILED
-
BindDevice - 绑定设备
- 功能:绑定指定设备并获取驱动Extension对象
- 参数:
deviceId
: 设备ID(由查询接口获得)connectCallback
: 连接回调接口
- 返回值:错误码
- 异常处理:
- 设备不存在返回EDM_ERR_INVALID_OBJECT
- 无匹配驱动返回EDM_ERR_NOT_SUPPORT
- 权限不足返回EDM_ERR_NO_PERM
- 异步通知:通过回调接口OnConnect通知连接结果
-
UnBindDevice - 解绑设备
- 功能:解绑已绑定的设备,释放资源
- 参数:
deviceId
: 设备ID
- 返回值:错误码
- 异常处理:设备未绑定返回EDM_ERR_SERVICE_NOT_BOUND
-
QueryDeviceInfo - 查询设备信息
- 功能:查询设备详细信息,包括匹配的驱动信息
- 参数:
deviceInfos
: [输出] 设备信息列表deviceId
: [可选] 指定设备ID查询单个设备
- 返回值:错误码
- 说明:返回信息包括设备ID、是否匹配驱动、驱动UID等
-
QueryDriverInfo - 查询驱动信息
- 功能:查询已安装的驱动包信息
- 参数:
driverInfos
: [输出] 驱动信息列表driverUid
: [可选] 指定驱动UID查询单个驱动
- 返回值:错误码
- 说明:返回信息包括驱动名称、版本、描述、支持的设备等
5.1.2 IDriverExtMgrCallback回调接口
IDL定义:interfaces/innerkits/IDriverExtMgrCallback.idl
class IDriverExtMgrCallback {
public:// 连接成功回调virtual void OnConnect(uint64_t deviceId,const sptr<IRemoteObject> &drvExtObj,const ErrMsg &errMsg) = 0;// 断开连接回调virtual void OnDisconnect(uint64_t deviceId,const ErrMsg &errMsg) = 0;// 解绑回调virtual void OnUnBind(uint64_t deviceId,const ErrMsg &errMsg) = 0;
};
回调说明:
-
OnConnect - 连接成功回调
- 触发时机:设备绑定成功或失败时触发
- 参数:
deviceId
: 设备IDdrvExtObj
: 驱动Extension远程对象(成功时非空)errMsg
: 错误信息(包含错误码和描述)
- 用途:应用通过此回调获取驱动Extension对象,进行后续通信
-
OnDisconnect - 断开连接回调
- 触发时机:设备断开连接时触发
- 参数:设备ID和错误信息
- 用途:通知应用设备已断开
-
OnUnBind - 解绑回调
- 触发时机:设备解绑完成时触发
- 参数:设备ID和错误信息
- 用途:通知应用解绑操作已完成
5.2 DDK接口
5.2.1 USB DDK接口
头文件:interfaces/ddk/usb/usb_ddk_api.h
权限要求:ohos.permission.ACCESS_DDK_USB
接口列表:
// 初始化DDK
int32_t OH_Usb_Init(void);// 释放DDK资源
void OH_Usb_Release(void);
int32_t OH_Usb_ReleaseResource(void);// 获取设备描述符
int32_t OH_Usb_GetDeviceDescriptor(uint64_t deviceId,struct UsbDeviceDescriptor *desc
);// 获取配置描述符
int32_t OH_Usb_GetConfigDescriptor(uint64_t deviceId,uint8_t configIndex,struct UsbDdkConfigDescriptor ** const config
);// 释放配置描述符
void OH_Usb_FreeConfigDescriptor(struct UsbDdkConfigDescriptor * const config
);// 声明USB接口
int32_t OH_Usb_ClaimInterface(uint64_t deviceId,uint8_t interfaceIndex,uint64_t *interfaceHandle
);// 释放USB接口
int32_t OH_Usb_ReleaseInterface(uint64_t interfaceHandle);// 选择接口设置
int32_t OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle,uint8_t settingIndex
);// 控制传输(读)
int32_t OH_Usb_SendControlReadRequest(uint64_t interfaceHandle,const struct UsbControlRequestSetup *setup,uint32_t timeout,uint8_t *data,uint32_t *dataLen
);// 控制传输(写)
int32_t OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle,const struct UsbControlRequestSetup *setup,uint32_t timeout,const uint8_t *data,uint32_t dataLen
);// 管道传输(批量/中断传输)
int32_t OH_Usb_SendPipeRequest(const struct UsbRequestPipe *pipe,UsbDeviceMemMap *devMmap
);// 创建设备内存映射
int32_t OH_Usb_CreateDeviceMemMap(uint64_t deviceId,size_t size,UsbDeviceMemMap **devMmap
);// 销毁设备内存映射
void OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap *devMmap);// 获取USB设备列表
int32_t OH_Usb_GetDevices(struct Usb_DeviceArray *devices);
接口使用示例:
// 1. 初始化USB DDK
int32_t ret = OH_Usb_Init();
if (ret != 0) {// 处理错误return ret;
}// 2. 获取设备描述符
struct UsbDeviceDescriptor desc;
ret = OH_Usb_GetDeviceDescriptor(deviceId, &desc);
if (ret == 0) {printf("VendorID: 0x%04x, ProductID: 0x%04x\n",desc.idVendor, desc.idProduct);
}// 3. 获取配置描述符
struct UsbDdkConfigDescriptor *config;
ret = OH_Usb_GetConfigDescriptor(deviceId, 0, &config);
if (ret == 0) {// 解析配置描述符// ...// 释放描述符OH_Usb_FreeConfigDescriptor(config);
}// 4. 声明接口
uint64_t interfaceHandle;
ret = OH_Usb_ClaimInterface(deviceId, 0, &interfaceHandle);
if (ret == 0) {// 使用接口进行数据传输// ...// 释放接口OH_Usb_ReleaseInterface(interfaceHandle);
}// 5. 释放DDK资源
OH_Usb_Release();
5.2.2 HID DDK接口
头文件:interfaces/ddk/hid/hid_ddk_api.h
权限要求:ohos.permission.ACCESS_DDK_HID
接口列表(简要):
- HID设备报告发送/接收
- HID输入事件注入
- HID设备信息查询
5.2.3 SCSI DDK接口
头文件:interfaces/ddk/scsi/scsi_peripheral_api.h
接口列表(简要):
- SCSI命令发送
- SCSI设备信息查询
- SCSI块设备访问
5.3 数据交换协议
5.3.1 IPC数据序列化
设备数据序列化:
// DeviceData序列化
bool DeviceData::Marshalling(Parcel &parcel) const {WRITE_PARCEL_RETURN(parcel, Uint32, static_cast<uint32_t>(busType));WRITE_PARCEL_RETURN(parcel, Uint64, deviceId);WRITE_PARCEL_RETURN(parcel, String, descripton);return true;
}// DeviceData反序列化
DeviceData* DeviceData::Unmarshalling(Parcel &data) {auto object = new DeviceData();object->busType = static_cast<BusType>(data.ReadUint32());object->deviceId = data.ReadUint64();object->descripton = data.ReadString();return object;
}
驱动信息序列化:
// DriverInfoData序列化
bool DriverInfoData::Marshalling(Parcel &parcel) const {WRITE_PARCEL_RETURN(parcel, Uint32, static_cast<uint32_t>(busType));WRITE_PARCEL_RETURN(parcel, String, driverUid);WRITE_PARCEL_RETURN(parcel, String, driverName);WRITE_PARCEL_RETURN(parcel, String, bundleSize);WRITE_PARCEL_RETURN(parcel, String, version);WRITE_PARCEL_RETURN(parcel, String, description);return true;
}
5.3.2 内部模块调用方式
设备注册流程:
// USB设备插入 -> 注册设备
void UsbDevSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data) {// 1. 解析USB设备信息auto usbDevInfo = ParseUsbDeviceInfo(data);// 2. 创建DeviceInfo对象auto devInfo = std::make_shared<DeviceInfo>(usbDevInfo->busDeviceId,BusType::BUS_TYPE_USB,usbDevInfo->description);// 3. 调用设备变化回调if (devChangeCallback_) {devChangeCallback_->OnDeviceAdd(devInfo);}
}// 设备管理器处理
void ExtDeviceManager::OnDeviceAdd(shared_ptr<DeviceInfo> devInfo) {// 1. 注册设备RegisterDevice(devInfo);// 2. 查询匹配的驱动auto driverInfo = DriverPkgManager::GetInstance().QueryMatchDriver(devInfo);// 3. 更新设备驱动信息if (driverInfo != nullptr) {auto device = QueryDeviceByDeviceID(devInfo->GetDeviceId());device->AddBundleInfo(bundleInfo, driverInfo);}
}
设备绑定流程:
// 应用调用绑定接口
ErrCode DriverExtMgr::BindDevice(int32_t &errorCode,uint64_t deviceId,const sptr<IDriverExtMgrCallback> &connectCallback
) {// 1. 获取调用者TokenIDuint32_t callingTokenId = IPCSkeleton::GetCallingTokenID();// 2. 调用设备管理器连接设备errorCode = ExtDeviceManager::GetInstance().ConnectDevice(deviceId, callingTokenId, connectCallback);return ERR_OK;
}// 设备管理器处理
int32_t ExtDeviceManager::ConnectDevice(uint64_t deviceId,uint32_t callingTokenId,const sptr<IDriverExtMgrCallback> &connectCallback
) {// 1. 查询设备对象auto device = QueryDeviceByDeviceID(deviceId);if (device == nullptr) {return EDM_ERR_INVALID_OBJECT;}// 2. 检查是否有匹配的驱动if (!device->HasDriver()) {return EDM_ERR_NOT_SUPPORT;}// 3. 连接设备return device->Connect(connectCallback, callingTokenId);
}// 设备对象处理
int32_t Device::Connect(const sptr<IDriverExtMgrCallback> &connectCallback,uint32_t callingTokenId
) {// 1. 注册回调RegisterDrvExtMgrCallback(connectCallback);// 2. 创建连接通知器AddDrvExtConnNotify();// 3. 调用驱动能力控制器连接Extensionstd::string bundleName = GetBundleName(bundleInfo_);std::string abilityName = GetAbilityName(bundleInfo_);return DriverExtensionController::GetInstance().ConnectDriverExtension(bundleName,abilityName,connectNofitier_,info_->GetBusDevId());
}
5.4 接口调用时序图
5.4.1 设备查询时序图
5.4.2 设备绑定时序图
5.4.3 设备热插拔事件时序图
6. 总结与扩展
6.1 架构优势
- 模块化设计:各模块职责清晰,低耦合高内聚
- 可扩展性:总线扩展插件化,易于支持新总线类型
- 安全性:基于Ability框架,具备完善的权限管理
- 用户体验:即插即用,自动匹配驱动
6.2 性能优化
- 单例模式:核心管理类采用单例,减少对象创建开销
- 异步处理:设备连接、驱动加载采用异步机制,不阻塞主线程
- 按需加载:总线扩展库按需动态加载
- 资源回收:定时器自动卸载空闲服务,节省系统资源
6.3 扩展方向
- 新总线类型支持:可扩展支持蓝牙、网络设备等
- 设备权限细化:支持更精细的设备访问权限控制
- 设备共享机制:支持多应用共享访问同一设备
- 驱动热更新:支持驱动包在线更新而无需重启
6.4 关键技术点
- IPC通信:基于OpenHarmony IPC机制的跨进程通信
- DDK接口:为驱动开发者提供的硬件访问接口
- Ability框架:驱动Extension基于Ability框架实现
- 事件驱动:设备热插拔、驱动包变化采用事件驱动机制
- 状态机管理:设备和驱动包的生命周期采用状态机模型
附录
A. 目录结构
/drivers/external_device_manager
├── frameworks # 框架层实现
│ ├── ddk # DDK接口实现
│ ├── js # JS API实现
│ └── native # Native客户端实现
├── interfaces # 对外接口定义
│ ├── ddk # DDK接口头文件
│ └── innerkits # 内部接口头文件
├── services # 系统服务实现
│ └── native
│ ├── driver_extension # 驱动Extension定义
│ └── driver_extension_manager # 核心服务实现
│ ├── include
│ │ ├── bus_extension # 总线扩展
│ │ ├── device_manager # 设备管理
│ │ └── drivers_pkg_manager # 驱动包管理
│ └── src # 源代码实现
├── utils # 工具类
├── test # 测试代码
└── sa_profile # 系统服务配置
B. 编译构建
# 编译32位ARM系统
./build.sh --product-name rk3568 --ccache --build-target external_device_manager# 编译64位ARM系统
./build.sh --product-name rk3568 --ccache --target-cpu arm64 --build-target external_device_manager