1e41f4b71Sopenharmony_ci# I3C 
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## 概述 <a name="1"></a>
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci### 功能简介<a name="2"></a>
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciI3C(Improved Inter Integrated Circuit)总线是由MIPI Alliance开发的一种简单、低成本的双向二线制同步串行总线。
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciI3C是两线双向串行总线,针对多个传感器从设备进行了优化,并且一次只能由一个I3C主设备控制。相比于I2C,I3C总线拥有更高的速度、更低的功耗,支持带内中断、从设备热接入以及切换当前主设备,同时向后兼容I2C从设备。I3C增加了带内中断(In-Bind Interrupt)功能,支持I3C设备进行热接入操作,弥补了I2C总线需要额外增加中断线来完成中断的不足。I3C总线上允许同时存在I2C设备、I3C从设备和I3C次级主设备。
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci### 基本概念<a name="3"></a>
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci- IBI(In-Band Interrupt):带内中断。
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci    在SCL线没有启动信号时,I3C从设备可以通过拉低SDA线使主设备发出SCL启动信号,从而发出带内中断请求。若有多个从设备同时发出中断请求,I3C主设备则通过从设备地址进行仲裁,低地址优先相应。
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci- DAA(Dynamic Address Assignment):动态地址分配。
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci    I3C支持对从设备地址进行动态分配从而避免地址冲突。在分配动态地址之前,连接到I3C总线上的每个I3C/I2C设备都应以两种方式之一来唯一标识:
20e41f4b71Sopenharmony_ci 
21e41f4b71Sopenharmony_ci    - 设备可能有一个符合I2C规范的静态地址,主机可以使用此静态地址。
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci    - 在任何情况下,I3C设备均应具有48位的临时ID。除非设备具有静态地址且主机使用静态地址,否则主机应使用此48位临时ID。
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci- CCC(Common Command Code):通用命令代码。
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci    所有I3C设备均支持CCC,可以直接将其传输到特定的I3C从设备,也可以同时传输到所有I3C从设备。
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci- BCR(Bus Characteristic Register):总线特性寄存器。
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci    每个连接到I3C总线的I3C设备都应具有相关的只读总线特性寄存器(BCR),该寄存器描述了I3C兼容设备在动态地址分配和通用命令代码中的作用和功能。
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci- DCR(Device Characteristic Register):设备特性寄存器。
34e41f4b71Sopenharmony_ci  
35e41f4b71Sopenharmony_ci    连接到I3C总线的每个I3C设备都应具有相关的只读设备特性寄存器(DCR),该寄存器描述了用于动态地址分配和通用命令代码的I3C兼容设备类型(例如加速度计、陀螺仪等)。
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci### 运作机制<a name="4"></a>
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci在HDF框架中,同类型控制器对象较多时(可能同时存在十几个同类型控制器),如果采用独立服务模式则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。I3C模块采用统一服务模式(如图1)。
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ciI3C模块各分层的作用为:
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci- 接口层:提供打开设备,写入数据,关闭设备的能力。
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci- 核心层:主要负责服务绑定、初始化以及释放管理器,并提供添加、删除以及获取控制器的能力。由于框架需要统一管理I3C总线上挂载的所有设备,因此还提供了添加、删除以及获取设备的能力,以及中断回调函数。
47e41f4b71Sopenharmony_ci
48e41f4b71Sopenharmony_ci- 适配层:由驱动适配者实现与硬件相关的具体功能,如控制器的初始化等。
49e41f4b71Sopenharmony_ci
50e41f4b71Sopenharmony_ci在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。
51e41f4b71Sopenharmony_ci
52e41f4b71Sopenharmony_ci**图 1** I3C统一服务模式结构图<a name="fig1"></a>  
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci![I3C统一服务模式结构图](figures/统一服务模式结构图.png)
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci### 约束与限制<a name="5"></a>
57e41f4b71Sopenharmony_ci
58e41f4b71Sopenharmony_ciI3C模块当前仅支持轻量和小型系统内核(LiteOS-A) 。
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci## 开发指导 <a name="6"></a>
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci### 场景介绍 <a name="7"></a>
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ciI3C可连接单个或多个I3C、I2C从器件,它主要用于:
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci- 与传感器通信,如陀螺仪、气压计或支持I3C协议的图像传感器等。
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci- 通过软件或硬件协议转换,与其他通信接口(如UART串口等)的设备进行通信。
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci当驱动开发者需要将I3C设备适配到OpenHarmony时,需要进行I3C驱动适配,下文将介绍如何进行I3C驱动适配。
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci### 接口说明 <a name="8"></a>
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci为了保证上层在调用I3C接口时能够正确的操作硬件,核心层在//drivers/hdf_core/framework/support/platform/include/i3c/i3c_core.h中定义了以下钩子函数。驱动适配者需要在适配层实现这些函数的具体功能,并与这些钩子函数挂接,从而完成接口层与核心层的交互。
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ciI3cMethod定义:
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci```c
79e41f4b71Sopenharmony_cistruct I3cMethod {
80e41f4b71Sopenharmony_ci    int32_t (*sendCccCmd)(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc);
81e41f4b71Sopenharmony_ci    int32_t (*transfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count);
82e41f4b71Sopenharmony_ci    int32_t (*i2cTransfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count);
83e41f4b71Sopenharmony_ci    int32_t (*setConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config);
84e41f4b71Sopenharmony_ci    int32_t (*getConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config);
85e41f4b71Sopenharmony_ci    int32_t (*requestIbi)(struct I3cDevice *dev);
86e41f4b71Sopenharmony_ci    void (*freeIbi)(struct I3cDevice *dev);
87e41f4b71Sopenharmony_ci};
88e41f4b71Sopenharmony_ci```
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci**表 1** I3cMethod结构体成员的钩子函数功能说明
91e41f4b71Sopenharmony_ci| 函数成员 | 入参 | 出参 | 返回值 | 功能 |
92e41f4b71Sopenharmony_ci| - | - | - | - | - |
93e41f4b71Sopenharmony_ci| sendCccCmd | **cntlr**:结构体指针,核心层I3C控制器<br />**ccc**:传入的通用命令代码结构体指针 | **ccc**:传出的通用命令代码结构体指针 | HDF_STATUS相关状态|发送CCC(Common command Code,即通用命令代码)|
94e41f4b71Sopenharmony_ci| Transfer | **cntlr**:结构体指针,核心层I3C控制器<br />**msgs**:结构体指针,用户消息<br />**count**:int16_t,消息数量 | **msgs**:结构体指针,用户消息 | HDF_STATUS相关状态 | 使用I3C模式传递用户消息 |
95e41f4b71Sopenharmony_ci|i2cTransfer | **cntlr**:结构体指针,核心层I3C控制器<br />**msgs**:结构体指针,用户消息<br />**count**:int16_t,消息数量 | **msgs**:结构体指针,用户消息 | HDF_STATUS相关状态 | 使用I2C模式传递用户消息 |
96e41f4b71Sopenharmony_ci| setConfig | **cntlr**:结构体指针,核心层I3C控制器<br />**config**:控制器配置参数| 无 | HDF_STATUS相关状态 | 设置I3C控制器配置参数 |
97e41f4b71Sopenharmony_ci| getConfig | **cntlr**:结构体指针,核心层I3C控制器 | **config**:控制器配置参数 | HDF_STATUS相关状态 | 获取I3C控制器配置参数 |
98e41f4b71Sopenharmony_ci| requestIbi | **device**:结构体指针,核心层I3C设备 | 无 | HDF_STATUS相关状态 | 为I3C设备请求IBI(In-Bind Interrupt,即带内中断) |
99e41f4b71Sopenharmony_ci| freeIbi | **device**:结构体指针,核心层I3C设备 | 无 | HDF_STATUS相关状态 | 释放IBI |
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci### 开发步骤 <a name="9"></a>
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ciI3C模块适配包含以下五个步骤:
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci- 实例化驱动入口
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci    - 实例化HdfDriverEntry结构体成员。
108e41f4b71Sopenharmony_ci
109e41f4b71Sopenharmony_ci    - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci- 配置属性文件
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ci    - 在device_info.hcs文件中添加deviceNode描述。
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci    - 【可选】添加i3c_config.hcs器件属性文件。
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci- 实例化I3C控制器对象
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci    - 初始化I3cCntlr成员。
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci    - 实例化I3cCntlr成员I3cMethod方法集合,其定义和成员函数说明见下文。
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci- 注册中断处理子程序
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ci    为控制器注册中断处理程序,实现设备热接入和IBI(带内中断)功能。
126e41f4b71Sopenharmony_ci
127e41f4b71Sopenharmony_ci- 驱动调试
128e41f4b71Sopenharmony_ci
129e41f4b71Sopenharmony_ci    【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的测试用例是否成功,数据能否传输等。
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci### 开发实例
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ci下方将以Hi3516DV300的虚拟驱动//drivers/hdf_core/framework/test/unittest/platform/virtual/i3c_virtual.c为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci1. 实例化驱动入口
136e41f4b71Sopenharmony_ci    驱动入口必须为HdfDriverEntry(在//drivers/hdf_core/framework/include/core/hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。
137e41f4b71Sopenharmony_ci
138e41f4b71Sopenharmony_ci    一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
139e41f4b71Sopenharmony_ci
140e41f4b71Sopenharmony_ci    I3C驱动入口参考:
141e41f4b71Sopenharmony_ci
142e41f4b71Sopenharmony_ci    > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>    
143e41f4b71Sopenharmony_ci    > I3C控制器会出现很多个控制器挂接的情况,因而在HDF框架中首先会为此类型的控制器创建一个管理器对象,并同时对外发布一个管理器服务来统一处理外部访问。这样,用户需要打开某个控制器时,会先获取到管理器服务,然后管理器服务根据用户指定参数查找到指定控制器。
144e41f4b71Sopenharmony_ci    > 
145e41f4b71Sopenharmony_ci    > I3C管理器服务的驱动由核心层实现,驱动适配者不需要关注这部分内容的实现,但在实现Init函数的时候需要调用核心层的I3cCntlrAdd函数,它会实现相应功能。
146e41f4b71Sopenharmony_ci    
147e41f4b71Sopenharmony_ci    ```c
148e41f4b71Sopenharmony_ci    static struct HdfDriverEntry g_virtualI3cDriverEntry = {
149e41f4b71Sopenharmony_ci        .moduleVersion = 1,
150e41f4b71Sopenharmony_ci        .Init = VirtualI3cInit,
151e41f4b71Sopenharmony_ci        .Release = VirtualI3cRelease,
152e41f4b71Sopenharmony_ci        .moduleName = "virtual_i3c_driver",        // 【必要且与hcs文件中的名字匹配】
153e41f4b71Sopenharmony_ci    };
154e41f4b71Sopenharmony_ci    HDF_INIT(g_virtualI3cDriverEntry);             // 调用HDF_INIT将驱动入口注册到HDF框架中
155e41f4b71Sopenharmony_ci    
156e41f4b71Sopenharmony_ci    // 核心层i3c_core.c管理器服务的驱动入口
157e41f4b71Sopenharmony_ci    struct HdfDriverEntry g_i3cManagerEntry = {
158e41f4b71Sopenharmony_ci        .moduleVersion = 1,
159e41f4b71Sopenharmony_ci        .Init     = I3cManagerInit,
160e41f4b71Sopenharmony_ci        .Release  = I3cManagerRelease,
161e41f4b71Sopenharmony_ci        .moduleName = "HDF_PLATFORM_I3C_MANAGER",  // 这与device_info.hcs文件中device0对应
162e41f4b71Sopenharmony_ci    };
163e41f4b71Sopenharmony_ci    HDF_INIT(g_i3cManagerEntry);
164e41f4b71Sopenharmony_ci    ```
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci2. 配置属性文件
167e41f4b71Sopenharmony_ci    完成驱动入口注册之后,下一步请在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode信息,并在i3c_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值对于驱动适配者的驱动实现以及核心层I3cCntlr相关成员的默认值或限制范围有密切关系。
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ci    统一服务模式的特点是device_info.hcs文件中第一个设备节点必须为I3C管理器,其各项参数必须如表2设置:
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci    **表 2** device_info.hcs节点参数说明
172e41f4b71Sopenharmony_ci   
173e41f4b71Sopenharmony_ci    | 成员名 | 值 |
174e41f4b71Sopenharmony_ci    | -------- | -------- |
175e41f4b71Sopenharmony_ci    | policy | 驱动服务发布的策略,I3C管理器具体配置为0,表示驱动不需要发布服务 |
176e41f4b71Sopenharmony_ci    | priority | 驱动启动优先级(0-200),值越大优先级越低。I3C管理器具体配置为52 |
177e41f4b71Sopenharmony_ci    | permission | 驱动创建设备节点权限,I3C管理器具体配置为0664 |
178e41f4b71Sopenharmony_ci    | moduleName | 驱动名称,I3C管理器固定为HDF_PLATFORM_I3C_MANAGER |
179e41f4b71Sopenharmony_ci    | serviceName | 驱动对外发布服务的名称,I3C管理器服务名设置为HDF_PLATFORM_I3C_MANAGER |
180e41f4b71Sopenharmony_ci    | deviceMatchAttr | 驱动私有数据匹配的关键字,I3C管理器没有使用,可忽略 |
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci    从第二个节点开始配置具体I3C控制器信息,此节点并不表示某一路I3C控制器,而是代表一个资源性质设备,用于描述一类I3C控制器的信息。本例只有一个I3C控制器,如有多个控制器,则需要在device_info.hcs文件增加deviceNode信息,以及在i3c_config文件中增加对应的器件属性。
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci    - device_info.hcs配置参考
185e41f4b71Sopenharmony_ci
186e41f4b71Sopenharmony_ci        ```c
187e41f4b71Sopenharmony_ci        root {
188e41f4b71Sopenharmony_ci            device_i3c :: device {
189e41f4b71Sopenharmony_ci                device0 :: deviceNode {
190e41f4b71Sopenharmony_ci                    policy = 0;
191e41f4b71Sopenharmony_ci                    priority = 52;
192e41f4b71Sopenharmony_ci                    permission = 0644;
193e41f4b71Sopenharmony_ci                    serviceName = "HDF_PLATFORM_I3C_MANAGER";
194e41f4b71Sopenharmony_ci                    moduleName = "HDF_PLATFORM_I3C_MANAGER";
195e41f4b71Sopenharmony_ci                }
196e41f4b71Sopenharmony_ci            }
197e41f4b71Sopenharmony_ci            i3c_virtual :: deviceNode {
198e41f4b71Sopenharmony_ci                policy = 0;                               // 等于0,不需要发布服务。
199e41f4b71Sopenharmony_ci                priority = 56;                            // 驱动启动优先级。
200e41f4b71Sopenharmony_ci                permission = 0644;                        // 驱动创建设备节点权限。
201e41f4b71Sopenharmony_ci                moduleName = "virtual_i3c_driver";        // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致。
202e41f4b71Sopenharmony_ci                serviceName = "VIRTUAL_I3C_DRIVER";       // 【必要】驱动对外发布服务的名称,必须唯一。
203e41f4b71Sopenharmony_ci                deviceMatchAttr = "virtual_i3c";          // 【必要】用于配置控制器私有数据,要与i3c_config.hcs中对应控制器保持一致。
204e41f4b71Sopenharmony_ci            }                                             // 具体的控制器信息在i3c_config.hcs中。
205e41f4b71Sopenharmony_ci        }
206e41f4b71Sopenharmony_ci        ```
207e41f4b71Sopenharmony_ci
208e41f4b71Sopenharmony_ci    - i3c_config.hcs 配置参考
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_ci        ```c
211e41f4b71Sopenharmony_ci        root {
212e41f4b71Sopenharmony_ci            platform {
213e41f4b71Sopenharmony_ci                i3c_config {
214e41f4b71Sopenharmony_ci                    match_attr = "virtual_i3c";  // 【必要】需要和device_info.hcs中的deviceMatchAttr值一致
215e41f4b71Sopenharmony_ci                    template i3c_controller {    // 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省。
216e41f4b71Sopenharmony_ci                        busId = 0;               // 【必要】i3c总线号
217e41f4b71Sopenharmony_ci                        busMode = 0x0;           // 总线模式,0x0:纯净;0x1:混合高速;0x2:混合受限;0x3:混合低速。
218e41f4b71Sopenharmony_ci                        regBasePhy = 0x120b0000; // 【必要】物理基地址
219e41f4b71Sopenharmony_ci                        regSize = 0xd1;          // 【必要】寄存器位宽
220e41f4b71Sopenharmony_ci                        IrqNum = 20;             // 【必要】中断号
221e41f4b71Sopenharmony_ci                        i3cMaxRate = 12900000;   // 【可选】i3c模式最大时钟速率
222e41f4b71Sopenharmony_ci                        i3cRate = 12500000;      // 【可选】i3c模式时钟速率
223e41f4b71Sopenharmony_ci                        i2cFmRate = 1000000;     // 【可选】i2c FM模式时钟速率
224e41f4b71Sopenharmony_ci                        i2cFmPlusRate = 400000;  // 【可选】i2c FM+模式时钟速率
225e41f4b71Sopenharmony_ci                    }
226e41f4b71Sopenharmony_ci                    controller_0 :: i3c_controller {
227e41f4b71Sopenharmony_ci                        busId = 18;
228e41f4b71Sopenharmony_ci                        IrqNum = 20;
229e41f4b71Sopenharmony_ci                    }
230e41f4b71Sopenharmony_ci                }
231e41f4b71Sopenharmony_ci            }
232e41f4b71Sopenharmony_ci        }
233e41f4b71Sopenharmony_ci        ```
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ci        需要注意的是,新增i3c_config.hcs配置文件后,必须在对应的hdf.hcs文件中包含i3c_config.hcs所在路径信息,否则配置文件无法生效。
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci3. 实例化I3C控制器对象
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci    配置属性文件完成后,要以核心层I3cCntlr对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化I3cCntlr成员I3cMethod(让用户可以通过接口来调用驱动底层函数)。
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci    此步骤需要通过实现HdfDriverEntry成员函数(Bind,Init,Release)来完成。
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ci    I3cCntlr成员钩子函数结构体I3cMethod的实例化,I3cLockMethod钩子函数结构体本例未实现,若要实例化,可参考I2C驱动开发。
244e41f4b71Sopenharmony_ci
245e41f4b71Sopenharmony_ci    - 自定义结构体参考
246e41f4b71Sopenharmony_ci
247e41f4b71Sopenharmony_ci        > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>          
248e41f4b71Sopenharmony_ci        > 从驱动的角度看,自定义结构体是参数和数据的载体,而且i3c_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,其中一些重要数值也会传递给核心层I3cCntlr对象,例如设备号、总线号等。
249e41f4b71Sopenharmony_ci
250e41f4b71Sopenharmony_ci        ```c
251e41f4b71Sopenharmony_ci        struct VirtualI3cCntlr {
252e41f4b71Sopenharmony_ci            struct I3cCntlr cntlr;           // 【必要】是核心层控制对象,具体描述见下面。
253e41f4b71Sopenharmony_ci            volatile unsigned char *regBase; // 【必要】寄存器基地址
254e41f4b71Sopenharmony_ci            uint32_t regBasePhy;             // 【必要】寄存器物理基地址
255e41f4b71Sopenharmony_ci            uint32_t regSize;                // 【必要】寄存器位宽
256e41f4b71Sopenharmony_ci            uint16_t busId;                  // 【必要】设备号
257e41f4b71Sopenharmony_ci            uint16_t busMode;
258e41f4b71Sopenharmony_ci            uint16_t IrqNum;
259e41f4b71Sopenharmony_ci            uint32_t i3cMaxRate;
260e41f4b71Sopenharmony_ci            uint32_t i3cRate;
261e41f4b71Sopenharmony_ci            uint32_t i2cFmRate;
262e41f4b71Sopenharmony_ci            uint32_t i2cFmPlusRate;
263e41f4b71Sopenharmony_ci        };
264e41f4b71Sopenharmony_ci        
265e41f4b71Sopenharmony_ci        // I3cCntlr是核心层控制器结构体,其中的成员在Init函数中被赋值。
266e41f4b71Sopenharmony_ci        struct I3cCntlr {
267e41f4b71Sopenharmony_ci            OsalSpinlock lock;
268e41f4b71Sopenharmony_ci            void *owner;
269e41f4b71Sopenharmony_ci            int16_t busId;
270e41f4b71Sopenharmony_ci            struct I3cConfig config;
271e41f4b71Sopenharmony_ci            uint16_t addrSlot[(I3C_ADDR_MAX + 1) / ADDRS_PER_UINT16];
272e41f4b71Sopenharmony_ci            struct I3cIbiInfo *ibiSlot[I3C_IBI_MAX];
273e41f4b71Sopenharmony_ci            const struct I3cMethod *ops;
274e41f4b71Sopenharmony_ci            const struct I3cLockMethod *lockOps;
275e41f4b71Sopenharmony_ci            void *priv;
276e41f4b71Sopenharmony_ci        };
277e41f4b71Sopenharmony_ci        ```
278e41f4b71Sopenharmony_ci
279e41f4b71Sopenharmony_ci    - Init函数开发参考
280e41f4b71Sopenharmony_ci
281e41f4b71Sopenharmony_ci        **入参:** 
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ci        HdfDeviceObject是整个驱动对外提供的接口参数,具备HCS配置文件的信息。
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci        **返回值:**
286e41f4b71Sopenharmony_ci
287e41f4b71Sopenharmony_ci        HDF_STATUS相关状态(表3为部分展示,如需使用其他状态,可参考//drivers/hdf_core/interfaces/inner_api/utils/hdf_base.h中HDF_STATUS定义)。
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ci        **表 3** HDF_STATUS相关状态说明
290e41f4b71Sopenharmony_ci
291e41f4b71Sopenharmony_ci        | 状态(值) | 问题描述 |
292e41f4b71Sopenharmony_ci        | -------- | -------- |
293e41f4b71Sopenharmony_ci        | HDF_ERR_INVALID_OBJECT | 控制器对象非法 |
294e41f4b71Sopenharmony_ci        | HDF_ERR_INVALID_PARAM | 参数非法 |
295e41f4b71Sopenharmony_ci        | HDF_ERR_MALLOC_FAIL | 内存分配失败 |
296e41f4b71Sopenharmony_ci        | HDF_ERR_IO | I/O错误 |
297e41f4b71Sopenharmony_ci        | HDF_SUCCESS | 传输成功 |
298e41f4b71Sopenharmony_ci        | HDF_FAILURE | 传输失败 |
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ci        **函数说明:**
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ci        初始化自定义结构体对象,初始化I3cCntlr成员,调用核心层I3cCntlrAdd函数。
303e41f4b71Sopenharmony_ci
304e41f4b71Sopenharmony_ci        ```c
305e41f4b71Sopenharmony_ci        static int32_t VirtualI3cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
306e41f4b71Sopenharmony_ci        {
307e41f4b71Sopenharmony_ci            int32_t ret;
308e41f4b71Sopenharmony_ci            struct VirtualI3cCntlr *virtual = NULL;                                // 【必要】自定义结构体对象
309e41f4b71Sopenharmony_ci            (void)device;
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ci            virtual = (struct VirtualI3cCntlr *)OsalMemCalloc(sizeof(*virtual));   // 【必要】内存分配
312e41f4b71Sopenharmony_ci            if (virtual == NULL) {
313e41f4b71Sopenharmony_ci                HDF_LOGE("%s: Malloc virtual fail!", __func__);
314e41f4b71Sopenharmony_ci                return HDF_ERR_MALLOC_FAIL;
315e41f4b71Sopenharmony_ci            }
316e41f4b71Sopenharmony_ci
317e41f4b71Sopenharmony_ci            ret = VirtualI3cReadDrs(virtual, node);                                // 【必要】将i3c_config文件的默认值填充到结构体中,函数定义见下方
318e41f4b71Sopenharmony_ci            if (ret != HDF_SUCCESS) {
319e41f4b71Sopenharmony_ci                HDF_LOGE("%s: Read drs fail! ret:%d", __func__, ret);
320e41f4b71Sopenharmony_ci                goto __ERR__;
321e41f4b71Sopenharmony_ci            }
322e41f4b71Sopenharmony_ci            ......
323e41f4b71Sopenharmony_ci            virtual->regBase = OsalIoRemap(virtual->regBasePhy, virtual->regSize); // 【必要】地址映射
324e41f4b71Sopenharmony_ci            ret = OsalRegisterIrq(hi35xx->softIrqNum, OSAL_IRQF_TRIGGER_NONE, I3cIbiHandle, "I3C", virtual); //【必要】注册中断程序
325e41f4b71Sopenharmony_ci            if (ret != HDF_SUCCESS) {
326e41f4b71Sopenharmony_ci                HDF_LOGE("%s: register irq failed!", __func__);
327e41f4b71Sopenharmony_ci                return ret;
328e41f4b71Sopenharmony_ci            }
329e41f4b71Sopenharmony_ci            ......
330e41f4b71Sopenharmony_ci            VirtualI3cCntlrInit(virtual);              // 【必要】I3C设备的初始化
331e41f4b71Sopenharmony_ci            virtual->cntlr.priv = (void *)node;        // 【必要】存储设备属性
332e41f4b71Sopenharmony_ci            virtual->cntlr.busId = virtual->busId;     // 【必要】初始化I3cCntlr成员
333e41f4b71Sopenharmony_ci            virtual->cntlr.ops = &g_method;            // 【必要】I3cMethod的实例化对象的挂载
334e41f4b71Sopenharmony_ci            (void)OsalSpinInit(&virtual->spin);
335e41f4b71Sopenharmony_ci            ret = I3cCntlrAdd(&virtual->cntlr);        // 【必要且重要】调用此函数将控制器添加至核心,返回成功信号后驱动才完全接入平台核心层。
336e41f4b71Sopenharmony_ci            if (ret != HDF_SUCCESS) {
337e41f4b71Sopenharmony_ci                HDF_LOGE("%s: add i3c controller failed! ret = %d", __func__, ret);
338e41f4b71Sopenharmony_ci                (void)OsalSpinDestroy(&virtual->spin);
339e41f4b71Sopenharmony_ci                goto __ERR__;
340e41f4b71Sopenharmony_ci            }
341e41f4b71Sopenharmony_ci
342e41f4b71Sopenharmony_ci            return HDF_SUCCESS;
343e41f4b71Sopenharmony_ci        __ERR__:                                       // 若控制器添加失败,需要执行去初始化相关函数。
344e41f4b71Sopenharmony_ci            if (virtual != NULL) {
345e41f4b71Sopenharmony_ci                OsalMemFree(virtual);
346e41f4b71Sopenharmony_ci                virtual = NULL;
347e41f4b71Sopenharmony_ci            }
348e41f4b71Sopenharmony_ci
349e41f4b71Sopenharmony_ci            return ret;
350e41f4b71Sopenharmony_ci        }
351e41f4b71Sopenharmony_ci
352e41f4b71Sopenharmony_ci        static int32_t VirtualI3cInit(struct HdfDeviceObject *device)
353e41f4b71Sopenharmony_ci        {
354e41f4b71Sopenharmony_ci            int32_t ret;
355e41f4b71Sopenharmony_ci            const struct DeviceResourceNode *childNode = NULL;
356e41f4b71Sopenharmony_ci
357e41f4b71Sopenharmony_ci            if (device == NULL || device->property == NULL) {
358e41f4b71Sopenharmony_ci                HDF_LOGE("%s: device or property is NULL", __func__);
359e41f4b71Sopenharmony_ci                return HDF_ERR_INVALID_OBJECT;
360e41f4b71Sopenharmony_ci            }
361e41f4b71Sopenharmony_ci
362e41f4b71Sopenharmony_ci            DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
363e41f4b71Sopenharmony_ci                ret = VirtualI3cParseAndInit(device, childNode);
364e41f4b71Sopenharmony_ci                if (ret != HDF_SUCCESS) {
365e41f4b71Sopenharmony_ci                    break;
366e41f4b71Sopenharmony_ci                }
367e41f4b71Sopenharmony_ci            }
368e41f4b71Sopenharmony_ci
369e41f4b71Sopenharmony_ci            return ret;
370e41f4b71Sopenharmony_ci        }
371e41f4b71Sopenharmony_ci
372e41f4b71Sopenharmony_ci        static int32_t VirtualI3cReadDrs(struct VirtualI3cCntlr *virtual, const struct DeviceResourceNode *node)
373e41f4b71Sopenharmony_ci        {
374e41f4b71Sopenharmony_ci            struct DeviceResourceIface *drsOps = NULL;
375e41f4b71Sopenharmony_ci
376e41f4b71Sopenharmony_ci            // 获取drsOps方法
377e41f4b71Sopenharmony_ci            drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
378e41f4b71Sopenharmony_ci            if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
379e41f4b71Sopenharmony_ci                HDF_LOGE("%s: Invalid drs ops fail!", __func__);
380e41f4b71Sopenharmony_ci                return HDF_FAILURE;
381e41f4b71Sopenharmony_ci            }
382e41f4b71Sopenharmony_ci            // 将配置参数依次读出,并填充至结构体中
383e41f4b71Sopenharmony_ci            if (drsOps->GetUint16(node, "busId", &virtual->busId, 0) != HDF_SUCCESS) {
384e41f4b71Sopenharmony_ci                HDF_LOGE("%s: Read busId fail!", __func__);
385e41f4b71Sopenharmony_ci                return HDF_ERR_IO;
386e41f4b71Sopenharmony_ci            }
387e41f4b71Sopenharmony_ci            if (drsOps->GetUint16(node, "busMode", &virtual->busMode, 0) != HDF_SUCCESS) {
388e41f4b71Sopenharmony_ci                HDF_LOGE("%s: Read busMode fail!", __func__);
389e41f4b71Sopenharmony_ci                return HDF_ERR_IO;
390e41f4b71Sopenharmony_ci            }
391e41f4b71Sopenharmony_ci            if (drsOps->GetUint16(node, "IrqNum", &virtual->IrqNum, 0) != HDF_SUCCESS) {
392e41f4b71Sopenharmony_ci                HDF_LOGE("%s: Read IrqNum fail!", __func__);
393e41f4b71Sopenharmony_ci                return HDF_ERR_IO;
394e41f4b71Sopenharmony_ci            }
395e41f4b71Sopenharmony_ci            ......
396e41f4b71Sopenharmony_ci            return HDF_SUCCESS;
397e41f4b71Sopenharmony_ci        }
398e41f4b71Sopenharmony_ci        ```
399e41f4b71Sopenharmony_ci
400e41f4b71Sopenharmony_ci    - Release函数开发参考
401e41f4b71Sopenharmony_ci
402e41f4b71Sopenharmony_ci        **入参:** 
403e41f4b71Sopenharmony_ci
404e41f4b71Sopenharmony_ci        HdfDeviceObject是整个驱动对外提供的接口参数,具备HCS配置文件的信息。
405e41f4b71Sopenharmony_ci        
406e41f4b71Sopenharmony_ci        **返回值:**
407e41f4b71Sopenharmony_ci
408e41f4b71Sopenharmony_ci        无。
409e41f4b71Sopenharmony_ci        
410e41f4b71Sopenharmony_ci        **函数说明:**
411e41f4b71Sopenharmony_ci
412e41f4b71Sopenharmony_ci        释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。
413e41f4b71Sopenharmony_ci
414e41f4b71Sopenharmony_ci        > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>          
415e41f4b71Sopenharmony_ci        > 所有强制转换获取相应对象的操作**前提**是在Init函数中具备对应赋值的操作。
416e41f4b71Sopenharmony_ci
417e41f4b71Sopenharmony_ci        ```c
418e41f4b71Sopenharmony_ci        static void VirtualI3cRemoveByNode(const struct DeviceResourceNode *node)
419e41f4b71Sopenharmony_ci        {
420e41f4b71Sopenharmony_ci            int32_t ret;
421e41f4b71Sopenharmony_ci            int16_t busId;
422e41f4b71Sopenharmony_ci            struct I3cCntlr *cntlr = NULL;
423e41f4b71Sopenharmony_ci            struct VirtualI3cCntlr *virtual = NULL;
424e41f4b71Sopenharmony_ci            struct DeviceResourceIface *drsOps = NULL;
425e41f4b71Sopenharmony_ci
426e41f4b71Sopenharmony_ci            drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
427e41f4b71Sopenharmony_ci            if (drsOps == NULL || drsOps->GetUint32 == NULL) {
428e41f4b71Sopenharmony_ci                HDF_LOGE("%s: invalid drs ops fail!", __func__);
429e41f4b71Sopenharmony_ci                return;
430e41f4b71Sopenharmony_ci            }
431e41f4b71Sopenharmony_ci
432e41f4b71Sopenharmony_ci            ret = drsOps->GetUint16(node, "busId", (uint16_t *)&busId, 0);
433e41f4b71Sopenharmony_ci            if (ret != HDF_SUCCESS) {
434e41f4b71Sopenharmony_ci                HDF_LOGE("%s: read busId fail!", __func__);
435e41f4b71Sopenharmony_ci                return;
436e41f4b71Sopenharmony_ci            }
437e41f4b71Sopenharmony_ci            ......
438e41f4b71Sopenharmony_ci            // 可以调用I3cCntlrGet函数通过设备的cntlrNum获取I3cCntlr对象,以及调用I3cCntlrRemove函数来释放I3cCntlr对象的内容。
439e41f4b71Sopenharmony_ci            cntlr = I3cCntlrGet(busId);
440e41f4b71Sopenharmony_ci            if (cntlr != NULL && cntlr->priv == node) {
441e41f4b71Sopenharmony_ci                I3cCntlrPut(cntlr);
442e41f4b71Sopenharmony_ci                I3cCntlrRemove(cntlr);                     // 【必要】主要是从管理器驱动那边移除I3cCntlr对象
443e41f4b71Sopenharmony_ci                virtual = (struct VirtualI3cCntlr *)cntlr; // 【必要】通过强制转换获取自定义的对象并进行release操作
444e41f4b71Sopenharmony_ci                (void)OsalSpinDestroy(&virtual->spin);
445e41f4b71Sopenharmony_ci                OsalMemFree(virtual);
446e41f4b71Sopenharmony_ci            }
447e41f4b71Sopenharmony_ci            return;
448e41f4b71Sopenharmony_ci        }
449e41f4b71Sopenharmony_ci
450e41f4b71Sopenharmony_ci        static void VirtualI3cRelease(struct HdfDeviceObject *device)
451e41f4b71Sopenharmony_ci        {
452e41f4b71Sopenharmony_ci            const struct DeviceResourceNode *childNode = NULL;
453e41f4b71Sopenharmony_ci        
454e41f4b71Sopenharmony_ci            HDF_LOGI("%s: enter", __func__);
455e41f4b71Sopenharmony_ci        
456e41f4b71Sopenharmony_ci            if (device == NULL || device->property == NULL) {
457e41f4b71Sopenharmony_ci                HDF_LOGE("%s: device or property is NULL", __func__);
458e41f4b71Sopenharmony_ci                return;
459e41f4b71Sopenharmony_ci            }
460e41f4b71Sopenharmony_ci            ......
461e41f4b71Sopenharmony_ci            // 遍历、解析i3c_config.hcs中的所有配置节点,并分别进行release操作
462e41f4b71Sopenharmony_ci            DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
463e41f4b71Sopenharmony_ci                VirtualI3cRemoveByNode(childNode); //函数定义如上
464e41f4b71Sopenharmony_ci            }
465e41f4b71Sopenharmony_ci        }
466e41f4b71Sopenharmony_ci        ```
467e41f4b71Sopenharmony_ci
468e41f4b71Sopenharmony_ci4. 注册中断处理子程序
469e41f4b71Sopenharmony_ci
470e41f4b71Sopenharmony_ci    在中断处理程序中通过判断中断产生的地址,实现热接入、IBI等操作。
471e41f4b71Sopenharmony_ci
472e41f4b71Sopenharmony_ci    ```c
473e41f4b71Sopenharmony_ci    static int32_t VirtualI3cReservedAddrWorker(struct VirtualI3cCntlr *virtual, uint16_t addr)
474e41f4b71Sopenharmony_ci    {
475e41f4b71Sopenharmony_ci        (void)virtual;
476e41f4b71Sopenharmony_ci        switch (addr) {
477e41f4b71Sopenharmony_ci            case I3C_HOT_JOIN_ADDR:
478e41f4b71Sopenharmony_ci                 VirtualI3cHotJoin(virtual);
479e41f4b71Sopenharmony_ci                break;
480e41f4b71Sopenharmony_ci            case I3C_RESERVED_ADDR_7H3E:
481e41f4b71Sopenharmony_ci            case I3C_RESERVED_ADDR_7H5E:
482e41f4b71Sopenharmony_ci            case I3C_RESERVED_ADDR_7H6E:
483e41f4b71Sopenharmony_ci            case I3C_RESERVED_ADDR_7H76:
484e41f4b71Sopenharmony_ci            case I3C_RESERVED_ADDR_7H7A:
485e41f4b71Sopenharmony_ci            case I3C_RESERVED_ADDR_7H7C:
486e41f4b71Sopenharmony_ci            case I3C_RESERVED_ADDR_7H7F:
487e41f4b71Sopenharmony_ci            // 广播地址单比特错误的所有情形
488e41f4b71Sopenharmony_ci            HDF_LOGW("%s: broadcast Address single bit error!", __func__);
489e41f4b71Sopenharmony_ci                break;
490e41f4b71Sopenharmony_ci            default:
491e41f4b71Sopenharmony_ci                HDF_LOGD("%s: Reserved address which is not supported!", __func__);
492e41f4b71Sopenharmony_ci                break;
493e41f4b71Sopenharmony_ci        }
494e41f4b71Sopenharmony_ci
495e41f4b71Sopenharmony_ci        return HDF_SUCCESS;
496e41f4b71Sopenharmony_ci    }
497e41f4b71Sopenharmony_ci
498e41f4b71Sopenharmony_ci    static int32_t I3cIbiHandle(uint32_t irq, void *data)
499e41f4b71Sopenharmony_ci    {
500e41f4b71Sopenharmony_ci        struct VirtualI3cCntlr *virtual = NULL;
501e41f4b71Sopenharmony_ci        struct I3cDevice *device = NULL;
502e41f4b71Sopenharmony_ci        uint16_t ibiAddr;
503e41f4b71Sopenharmony_ci        char *testStr = "Hello I3C!";
504e41f4b71Sopenharmony_ci
505e41f4b71Sopenharmony_ci        (void)irq;
506e41f4b71Sopenharmony_ci        if (data == NULL) {
507e41f4b71Sopenharmony_ci            HDF_LOGW("%s: data is NULL!", __func__);
508e41f4b71Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
509e41f4b71Sopenharmony_ci        }
510e41f4b71Sopenharmony_ci        virtual = (struct VirtualI3cCntlr *)data;
511e41f4b71Sopenharmony_ci        // 【必要】获取产生中断的地址,使用CHECK_RESERVED_ADDR宏判断该地址是否为I3C保留地址。
512e41f4b71Sopenharmony_ci        ibiAddr = VirtualI3cGetIbiAddr();
513e41f4b71Sopenharmony_ci        if (CHECK_RESERVED_ADDR(ibiAddr) == I3C_ADDR_RESERVED) {
514e41f4b71Sopenharmony_ci            HDF_LOGD("%s: Calling VirtualI3cResAddrWorker...", __func__);
515e41f4b71Sopenharmony_ci            return VirtualI3cReservedAddrWorker(virtual, ibiAddr);
516e41f4b71Sopenharmony_ci        } else {
517e41f4b71Sopenharmony_ci            HDF_LOGD("%s: Calling I3cCntlrIbiCallback...", __func__);
518e41f4b71Sopenharmony_ci            device = GetDeviceByAddr(&virtual->cntlr, ibiAddr);
519e41f4b71Sopenharmony_ci            if (device == NULL) {
520e41f4b71Sopenharmony_ci                HDF_LOGE("func:%s device is NULL!",__func__);
521e41f4b71Sopenharmony_ci                return HDF_ERR_MALLOC_FAIL;
522e41f4b71Sopenharmony_ci            }
523e41f4b71Sopenharmony_ci            if (device->ibi->payload > VIRTUAL_I3C_TEST_STR_LEN) {
524e41f4b71Sopenharmony_ci                // 将字符串"Hello I3C!"放入IBI缓冲区内
525e41f4b71Sopenharmony_ci                *device->ibi->data = *testStr;
526e41f4b71Sopenharmony_ci            }
527e41f4b71Sopenharmony_ci            // 根据产生IBI的I3C设备调用IBI回调函数
528e41f4b71Sopenharmony_ci            return I3cCntlrIbiCallback(device);
529e41f4b71Sopenharmony_ci        }
530e41f4b71Sopenharmony_ci
531e41f4b71Sopenharmony_ci        return HDF_SUCCESS;
532e41f4b71Sopenharmony_ci    }
533e41f4b71Sopenharmony_ci    ```
534e41f4b71Sopenharmony_ci
535e41f4b71Sopenharmony_ci5. 驱动调试
536e41f4b71Sopenharmony_ci
537e41f4b71Sopenharmony_ci    【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的测试用例是否成功,数据能否传输等。
538