未验证 提交 a69078e6 编写于 作者: O openharmony_ci 提交者: Gitee

!3940 【OpenHarmony开源贡献者计划2022】MMC,MIPICSI,MIPIDSI相关格式及表达问题

Merge pull request !3940 from king_he/mipicsi-1
......@@ -3,11 +3,11 @@
## 概述<a name="section1_MIPI_CSIDes"></a>
- CSI(Camera Serial Interface)是由MIPI联盟下Camera工作组指定的接口标准。CSI-2是MIPI CSI第二版,主要由应用层、协议层、物理层组成,最大支持4通道数据传输、单线传输速度高达1Gb/s。
CSI(Camera Serial Interface)是由MIPI联盟下Camera工作组指定的接口标准。CSI-2是MIPI CSI第二版,主要由应用层、协议层、物理层组成,最大支持4通道数据传输、单线传输速度高达1Gb/s。
- 物理层支持HS(High Speed)和LP(Low Power)两种工作模式。HS模式下采用低压差分信号,功耗较大,但数据传输速率可以很高(数据速率为80M~1Gbps);LP模式下采用单端信号,数据速率很低(<10Mbps),但是相应的功耗也很低。两种模式的结合保证了MIPI总线在需要传输大量数据(如图像)时可以高速传输,而在不需要传输大数据量时又能够减少功耗。
物理层支持HS(High Speed)和LP(Low Speed)两种工作模式。HS模式下采用低压差分信号,功耗较大,但数据传输速率可以很高(数据速率为80M~1Gbps);LP模式下采用单端信号,数据速率很低(<10Mbps),但是相应的功耗也很低。两种模式的结合保证了MIPI总线在需要传输大量数据(如图像)时可以高速传输,而在不需要传输大数据量时又能够减少功耗。
- 图1显示了简化的CSI接口。D-PHY采用1对源同步的差分时钟和1~4对差分数据线来进行数据传输。数据传输采用DDR方式,即在时钟的上下边沿都有数据传输。
图1显示了简化的CSI接口。D-PHY采用1对源同步的差分时钟和1~4对差分数据线来进行数据传输。数据传输采用DDR方式,即在时钟的上下边沿都有数据传输。
**图 1** CSI发送、接收接口<a name="fig1_MIPI_CSIDes"></a>
![](figures/CSI发送-接收接口.png)
......@@ -567,7 +567,7 @@ void PalMipiCsiTestSample(void)
/* lane模式参数为0 */
mode = LANE_DIVIDE_MODE_0;
/* 设置MIPI RX的 Lane分布 */
/* 设置MIPI RX的Lane分布 */
ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
......
......@@ -2,7 +2,7 @@
## 概述 <a name="section1_MIPI_CSIDevelop"></a>
CSI(Camera Serial Interface)是由MIPI(Mobile Industry Processor Interface )联盟下Camera工作组指定的接口标准。在HDF框架中,MIPI CSI的接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,MIPI CSI的接口关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。
CSI(Camera Serial Interface)是由MIPI(Mobile Industry Processor Interface)联盟下Camera工作组指定的接口标准。在HDF框架中,MIPI CSI的接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,MIPI CSI的接口关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。
图 1 无服务模式结构图
......@@ -10,7 +10,7 @@ CSI(Camera Serial Interface)是由MIPI(Mobile Industry Processor Interface
## 接口说明 <a name="section2_MIPI_CSIDevelop"></a>
MipiCsiCntlrMethod定义
MipiCsiCntlrMethod定义
```c
struct MipiCsiCntlrMethod {
......@@ -35,12 +35,12 @@ struct MipiCsiCntlrMethod {
| setPhyCmvmode | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**devno**:uint8_t,设备编号;<br>**cmvMode**:枚举类型,共模电压模式参数 | 无 | HDF_STATUS相关状态 | 设置共模电压模式 |
| setExtDataType | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**dataType**:结构体指针,定义YUV和原始数据格式以及位深度 | 无 | HDF_STATUS相关状态 | 设置YUV和RAW数据格式和位深 |
| setHsMode | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**laneDivideMode**:枚举类型,lane模式参数 | 无 | HDF_STATUS相关状态 | 设置MIPI RX的Lane分布 |
| enableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 使能mipi的时钟 |
| disableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 关闭mipi的时钟 |
| enableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 使能MIPI的时钟 |
| disableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 关闭MIPI的时钟 |
| resetRx | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 复位MIPI RX |
| unresetRx | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 撤销复位MIPI RX |
| enableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 使能mipi上的Sensor时钟 |
| disableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 关闭mipi上的Sensor时钟 |
| enableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 使能MIPI上的Sensor时钟 |
| disableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 关闭MIPI上的Sensor时钟 |
| resetSensor | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 复位Sensor |
| unresetSensor | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 撤销复位Sensor |
......@@ -60,7 +60,7 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
3. **实例化MIPICSI控制器对象:**
- 初始化MipiCsiCntlr成员。
- 实例化MipiCsiCntlr成员MipiCsiCntlrMethod。
>![](../public_sys-resources/icon-note.gif) **说明:**
>![](../public_sys-resources/icon-note.gif) **说明:**<br>
>实例化MipiCsiCntlr成员MipiCsiCntlrMethod,其定义和成员说明见[接口说明](#section2_MIPI_CSIDevelop)。
4. **驱动调试:**
......@@ -90,8 +90,8 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
policy = 0;
priority = 160;
permission = 0644;
moduleName = "HDF_MIPI_RX"; //【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致;
serviceName = "HDF_MIPI_RX"; //【必要且唯一】驱动对外发布服务的名称
moduleName = "HDF_MIPI_RX"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致;
serviceName = "HDF_MIPI_RX"; // 【必要且唯一】驱动对外发布服务的名称
}
}
}
......@@ -108,11 +108,11 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
```c
struct HdfDriverEntry g_mipiCsiDriverEntry = {
.moduleVersion = 1,
.Init = Hi35xxMipiCsiInit, //见Init参考
.Release = Hi35xxMipiCsiRelease, //见Release参考
.moduleName = "HDF_MIPI_RX", //【必要】需要与device_info.hcs 中保持一致。
.Init = Hi35xxMipiCsiInit, // 见Init参考
.Release = Hi35xxMipiCsiRelease, // 见Release参考
.moduleName = "HDF_MIPI_RX", // 【必要】需要与device_info.hcs 中保持一致。
};
HDF_INIT(g_mipiCsiDriverEntry); //调用HDF_INIT将驱动入口注册到HDF框架中
HDF_INIT(g_mipiCsiDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
```
3. 完成驱动入口注册之后,最后一步就是以核心层MipiCsiCntlr对象的初始化为核心,实现HdfDriverEntry成员函数(Bind,Init,Release)。MipiCsiCntlr对象的初始化包括厂商自定义结构体(用于传递参数和数据)和实例化MipiCsiCntlr成员MipiCsiCntlrMethod(让用户可以通过接口来调用驱动底层函数)。
......@@ -151,7 +151,7 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
};
} ComboDevAttr;
//MipiCsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
// MipiCsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
struct MipiCsiCntlr {
/** 当驱动程序绑定到HDF框架时,将发送此控制器提供的服务 */
struct IDeviceIoService service;
......@@ -196,10 +196,10 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
- **Init函数参考**
**入参:**
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备hcs配置文件的信息
**返回值:**
HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)
HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)
| 状态(值) | 问题描述 |
......@@ -221,21 +221,21 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
int32_t ret;
HDF_LOGI("%s: enter!", __func__);
g_mipiCsi.priv = NULL; //g_mipiTx是定义的全局变量
//static struct MipiCsiCntlr g_mipiCsi = {
//.devNo = 0
g_mipiCsi.priv = NULL; // g_mipiTx是定义的全局变量
// static struct MipiCsiCntlr g_mipiCsi = {
// .devNo = 0
//};
g_mipiCsi.ops = &g_method; //MipiCsiCntlrMethod的实例化对象的挂载
#ifdef CONFIG_HI_PROC_SHOW_SUPPORT
g_mipiCsi.debugs = &g_debugMethod;
#endif
ret = MipiCsiRegisterCntlr(&g_mipiCsi, device); //【必要】调用核心层函数和g_mipiTx初始化核心层全局变量
ret = MipiCsiRegisterCntlr(&g_mipiCsi, device); // 【必要】调用核心层函数和g_mipiTx初始化核心层全局变量
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiCsiRegisterCntlr] failed!", __func__);
return ret;
}
ret = MipiRxDrvInit(); //【必要】厂商对设备的初始化,形式不限
ret = MipiRxDrvInit(); // 【必要】厂商对设备的初始化,形式不限
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiRxDrvInit] failed.", __func__);
return ret;
......@@ -254,19 +254,19 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
return ret;
}
//mipi_dsi_core.c核心层
// mipi_dsi_core.c核心层
int32_t MipiCsiRegisterCntlr(struct MipiCsiCntlr *cntlr, struct HdfDeviceObject *device)
{
...
//定义的全局变量:static struct MipiCsiHandle g_mipiCsihandle[MAX_CNTLR_CNT];
// 定义的全局变量:static struct MipiCsiHandle g_mipiCsihandle[MAX_CNTLR_CNT];
if (g_mipiCsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiCsihandle[cntlr->devNo].lock);
(void)OsalMutexInit(&(cntlr->lock));
g_mipiCsihandle[cntlr->devNo].cntlr = cntlr; //初始化MipiCsiHandle成员
g_mipiCsihandle[cntlr->devNo].cntlr = cntlr; // 初始化MipiCsiHandle成员
g_mipiCsihandle[cntlr->devNo].priv = NULL;
cntlr->device = device; //使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
device->service = &(cntlr->service); //使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
cntlr->device = device; // 使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
device->service = &(cntlr->service); // 使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
cntlr->priv = NULL;
HDF_LOGI("%s: success.", __func__);
......@@ -294,16 +294,16 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
{
struct MipiCsiCntlr *cntlr = NULL;
...
cntlr = MipiCsiCntlrFromDevice(device); //这里有HdfDeviceObject到MipiCsiCntlr的强制转化
//return (device == NULL) ? NULL : (struct MipiCsiCntlr *)device->service;
cntlr = MipiCsiCntlrFromDevice(device); // 这里有HdfDeviceObject到MipiCsiCntlr的强制转化
// return (device == NULL) ? NULL : (struct MipiCsiCntlr *)device->service;
...
OsalSpinDestroy(&cntlr->ctxLock);
#ifdef MIPICSI_VFS_SUPPORT
MipiCsiDevModuleExit(cntlr->devNo);
#endif
MipiRxDrvExit(); //【必要】对厂商设备所占资源的释放
MipiCsiUnregisterCntlr(&g_mipiCsi); //空函数
MipiRxDrvExit(); // 【必要】对厂商设备所占资源的释放
MipiCsiUnregisterCntlr(&g_mipiCsi); // 空函数
g_mipiCsi.priv = NULL;
HDF_LOGI("%s: unload mipi csi driver success!", __func__);
......
......@@ -3,11 +3,11 @@
## 概述
- DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface (MIPI) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设(通常是LCD或者类似的显示设备),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。
DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface (MIPI) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设(通常是LCD或者类似的显示设备),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。
- MIPI DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。
MIPI DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。
- 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。
图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。
**图1** DSI发送、接收接口
......@@ -25,7 +25,7 @@
| 设置MIPI&nbsp;DSI进入Low&nbsp;power模式/High&nbsp;speed模式 | -&nbsp;MipiDsiSetLpMode:设置MIPI&nbsp;DSI进入Low&nbsp;power模式<br/>-&nbsp;MipiDsiSetHsMode:设置MIPI&nbsp;DSI进入High&nbsp;speed模式 |
| MIPI&nbsp;DSI发送/回读指令 | -&nbsp;MipiDsiTx:MIPI&nbsp;DSI发送相应指令的接口<br/>-&nbsp;MipiDsiRx:MIPI&nbsp;DSI按期望长度回读的接口 |
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>
> 本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。
......
......@@ -22,10 +22,10 @@ struct MipiDsiCntlrMethod { // 核心层结构体的成员函数
int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
void (*toHs)(struct MipiDsiCntlr *cntlr);
void (*toLp)(struct MipiDsiCntlr *cntlr);
void (*enterUlps)(struct MipiDsiCntlr *cntlr);//【可选】进入超低功耗模式
void (*exitUlps)(struct MipiDsiCntlr *cntlr); //【可选】退出超低功耗模式
void (*enterUlps)(struct MipiDsiCntlr *cntlr);// 【可选】进入超低功耗模式
void (*exitUlps)(struct MipiDsiCntlr *cntlr); // 【可选】退出超低功耗模式
int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);//【可选】使能/去使能功耗控制
int32_t (*attach)(struct MipiDsiCntlr *cntlr);//【可选】将一个DSI设备连接上host
int32_t (*attach)(struct MipiDsiCntlr *cntlr);// 【可选】将一个DSI设备连接上host
};
```
......@@ -33,11 +33,11 @@ struct MipiDsiCntlrMethod { // 核心层结构体的成员函数
| 成员函数 | 入参 | 出参 | 返回状态 | 功能 |
| -------- | -------- | -------- | -------- | -------- |
| setCntlrCfg | cntlr:结构体指针,MipiDsi控制器&nbsp; | 无 | HDF_STATUS相关状态 | 设置控制器参数 |
| setCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:结构体指针,指令传入值; | 无 | HDF_STATUS相关状态 | 向显示设备发送指令 |
| getCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:传入的命令描述结构体指针;<br>readLen:读取的数据大小; | out:结构体指针,用于存储读取的数据。 | HDF_STATUS相关状态 | 通过发送指令读取数据 |
| toHs | cntlr:&nbsp;结构体指针,MipiDsi控制器&nbsp;; | 无 | HDF_STATUS相关状态 | 设置为高速模式 |
| toLp | cntlr:&nbsp;结构体指针,MipiDsi控制器&nbsp;; | 无 | HDF_STATUS相关状态 | 设置为低电模式 |
| setCntlrCfg | cntlr:结构体指针,MipiDsi控制器 | 无 | HDF_STATUS相关状态 | 设置控制器参数 |
| setCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:结构体指针,指令传入值 | 无 | HDF_STATUS相关状态 | 向显示设备发送指令 |
| getCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:传入的命令描述结构体指针<br>readLen:读取的数据大小 | out:结构体指针,用于存储读取的数据 | HDF_STATUS相关状态 | 通过发送指令读取数据 |
| toHs | cntlr:结构体指针,MipiDsi控制器 | 无 | HDF_STATUS相关状态 | 设置为高速模式 |
| toLp | cntlr:结构体指针,MipiDsi控制器 | 无 | HDF_STATUS相关状态 | 设置为低电模式 |
## 开发步骤
......@@ -55,7 +55,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
3. **实例化MIPIDSI控制器对象:**
- 初始化MipiDsiCntlr成员。
- 实例化MipiDsiCntlr成员MipiDsiCntlrMethod。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>
> 实例化MipiDsiCntlr成员MipiDsiCntlrMethod,其定义和成员说明见[接口说明](#接口说明)。
4. **驱动调试:**
......@@ -66,7 +66,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
下方将以mipi_tx_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。
1. 一般来说,驱动开发首先需要在 xx_config.hcs 中配置器件属性,并在device_info.hcs文件中添加deviceNode描述。器件属性值与核心层MipiDsiCntlr 成员的默认值或限制范围有密切关系,deviceNode信息与驱动入口注册相关。
1. 一般来说,驱动开发首先需要在xx_config.hcs中配置器件属性,并在device_info.hcs文件中添加deviceNode描述。器件属性值与核心层MipiDsiCntlr成员的默认值或限制范围有密切关系,deviceNode信息与驱动入口注册相关。
但本例中MIPI控制器无需配置额外属性,如有厂商需要,则需要在device_info文件的deviceNode增加deviceMatchAttr信息,以及增加mipidsi_config文件。
......@@ -84,7 +84,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
policy = 0;
priority = 150;
permission = 0644;
moduleName = "HDF_MIPI_TX"; //【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致;
moduleName = "HDF_MIPI_TX"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致
serviceName = "HDF_MIPI_TX"; // 【必要且唯一】驱动对外发布服务的名称
}
}
......@@ -96,20 +96,20 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
2. 完成器件属性文件的配置之后,下一步请实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HdfDriverEntry结构体的函数指针成员会被厂商操作函数填充,HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组,方便调用。
一般在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
- MIPI DSI驱动入口参考
- MIPI DSI驱动入口参考
```
struct HdfDriverEntry g_mipiTxDriverEntry = {
.moduleVersion = 1,
.Init = Hi35xxMipiTxInit, //见Init参考
.Release = Hi35xxMipiTxRelease,//见Release参考
.moduleName = "HDF_MIPI_TX", //【必要】需要与device_info.hcs 中保持一致。
.Init = Hi35xxMipiTxInit, // 见Init参考
.Release = Hi35xxMipiTxRelease,// 见Release参考
.moduleName = "HDF_MIPI_TX", // 【必要】需要与device_info.hcs 中保持一致。
};
HDF_INIT(g_mipiTxDriverEntry); //调用HDF_INIT将驱动入口注册到HDF框架中
HDF_INIT(g_mipiTxDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
```
3. 完成驱动入口注册之后,最后一步就是以核心层MipiDsiCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化MipiDsiCntlr成员MipiDsiCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
- 自定义结构体参考
- 自定义结构体参考
从驱动的角度看,自定义结构体是参数和数据的载体,一般来说,config文件中的数值也会用来初始化结构体成员,但本例的mipidsi无器件属性文件,故基本成员结构与MipiDsiCntlr无太大差异。
......@@ -120,10 +120,10 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
short laneId[LANE_MAX_NUM]; // lane号
OutPutModeTag outputMode; // 输出模式选择:刷新模式,命令行模式和视频流模式
VideoModeTag videoMode; // 显示设备的同步模式
OutputFormatTag outputFormat; // 输出DSI图像数据格式:RGB or YUV
OutputFormatTag outputFormat; // 输出DSI图像数据格式:RGB或YUV
SyncInfoTag syncInfo; // 时序相关的设置
unsigned int phyDataRate; // mbps
unsigned int pixelClk; // KHz
unsigned int phyDataRate; // 数率:mbps
unsigned int pixelClk; // 时钟:KHz
} ComboDevCfgTag;
// MipiDsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
......@@ -153,7 +153,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
入参:
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。
HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值:
......@@ -178,29 +178,29 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
{
int32_t ret;
g_mipiTx.priv = NULL; //g_mipiTx是定义的全局变量
//static struct MipiDsiCntlr g_mipiTx {
g_mipiTx.priv = NULL; // g_mipiTx是定义的全局变量
// static struct MipiDsiCntlr g_mipiTx {
// .devNo=0
//};
g_mipiTx.ops = &g_method;//MipiDsiCntlrMethod的实例化对象的挂载
ret = MipiDsiRegisterCntlr(&g_mipiTx, device);//【必要】调用核心层函数和g_mipiTx初始化核心层全局变量
g_mipiTx.ops = &g_method;// MipiDsiCntlrMethod的实例化对象的挂载
ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// 【必要】调用核心层函数和g_mipiTx初始化核心层全局变量
...
return MipiTxDrvInit(0); //【必要】厂商对设备的初始化,形式不限
return MipiTxDrvInit(0); // 【必要】厂商对设备的初始化,形式不限
}
//mipi_dsi_core.c核心层
// mipi_dsi_core.c核心层
int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device)
{
...
//定义的全局变量:static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT];
// 定义的全局变量:static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT];
if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock);
(void)OsalMutexInit(&(cntlr->lock));
g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;//初始化MipiDsiHandle成员
g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// 初始化MipiDsiHandle成员
g_mipiDsihandle[cntlr->devNo].priv = NULL;
cntlr->device = device; //使HdfDeviceObject与MipiDsiHandle可以相互转化的前提
device->service = &(cntlr->service); //使HdfDeviceObject与MipiDsiHandle可以相互转化的前提
cntlr->device = device; // 使HdfDeviceObject与MipiDsiHandle可以相互转化的前提
device->service = &(cntlr->service); // 使HdfDeviceObject与MipiDsiHandle可以相互转化的前提
cntlr->priv = NULL;
...
return HDF_SUCCESS;
......@@ -213,7 +213,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
入参:
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。
HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值:
......@@ -221,7 +221,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
函数说明:
该函数需要在驱动入口结构体中赋值给 Release 接口, 当 HDF 框架调用 Init 函数初始化驱动失败时,可以调用 Release 释放驱动资源, 该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。
该函数需要在驱动入口结构体中赋值给Release接口,当DF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源,该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。
```
......@@ -229,11 +229,11 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
{
struct MipiDsiCntlr *cntlr = NULL;
...
cntlr = MipiDsiCntlrFromDevice(device);//这里有HdfDeviceObject到MipiDsiCntlr的强制转化
//return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
cntlr = MipiDsiCntlrFromDevice(device);// 这里有HdfDeviceObject到MipiDsiCntlr的强制转化
// return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
...
MipiTxDrvExit(); //【必要】对厂商设备所占资源的释放
MipiDsiUnregisterCntlr(&g_mipiTx); //空函数
MipiTxDrvExit(); // 【必要】对厂商设备所占资源的释放
MipiDsiUnregisterCntlr(&g_mipiTx); // 空函数
g_mipiTx.priv = NULL;
HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
}
......
......@@ -3,7 +3,7 @@
## 概述
MMC(MultiMedia Card),即多媒体卡,在HDF框架中,MMC的接口适配模式采用独立服务模式,在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。
MMC(MultiMedia Card)即多媒体卡。在HDF框架中,MMC的接口适配模式采用独立服务模式。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。
**图1** MMC独立服务模式结构图
......@@ -39,21 +39,21 @@ struct MmcCntlrOps {
| 成员函数 | 入参 | 返回值 | 功能 |
| -------- | -------- | -------- | -------- |
| doRequest | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;cmd:&nbsp;结构体指针,传入命令值 | HDF_STATUS相关状态 | request相应处理 |
| setClock | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;clock:&nbsp;时钟传入值 | HDF_STATUS相关状态 | 设置时钟频率 |
| setPowerMode | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;mode:&nbsp;枚举值(见MmcPowerMode定义),功耗模式 | HDF_STATUS相关状态 | 设置功耗模式 |
| setBusWidth | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;width:&nbsp;枚举值(见MmcBusWidth定义),总线带宽 | HDF_STATUS相关状态 | 设置总线带宽 |
| setBusTiming | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;timing:&nbsp;枚举值(见MmcBusTiming定义),总线时序 | HDF_STATUS相关状态 | 设置总线时序 |
| setSdioIrq | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;enable:&nbsp;布尔值,控制中断 | HDF_STATUS相关状态 | 使能/去使能SDIO中断 |
| hardwareReset | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | HDF_STATUS相关状态 | 复位硬件 |
| systemInit | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | HDF_STATUS相关状态 | 系统初始化 |
| setEnhanceSrobe | cntlr:&nbsp;核心层结构体指针,mmc控制器&nbsp;;enable:&nbsp;布尔值,设置功能 | HDF_STATUS相关状态 | 设置增强选通 |
| switchVoltage | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;volt:&nbsp;枚举值,电压值(3.3,1.8,1.2V); | HDF_STATUS相关状态 | 设置电压值 |
| devReadOnly | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | 布尔值 | 检验设备是否只读 |
| cardPluged | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | 布尔值 | 检验设备是否拔出 |
| devBusy | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | 布尔值 | 检验设备是否忙碌 |
| tune | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;cmdCode:&nbsp;uint32_t,命令代码; | HDF_STATUS相关状态 | 调谐 |
| rescanSdioDev | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | HDF_STATUS相关状态 | 扫描并添加SDIO设备 |
| doRequest | cntlr:核心层结构体指针,MMC控制器<br>cmd:结构体指针,传入命令值 | HDF_STATUS相关状态 | request相应处理 |
| setClock | cntlr:核心层结构体指针,MMC控制器<br>clock:时钟传入值 | HDF_STATUS相关状态 | 设置时钟频率 |
| setPowerMode | cntlr:核心层结构体指针,MMC控制器<br>mode:枚举值(见MmcPowerMode定义),功耗模式 | HDF_STATUS相关状态 | 设置功耗模式 |
| setBusWidth | cntlr:核心层结构体指针,MMC控制器<br>width:枚举值(见MmcBusWidth定义),总线带宽 | HDF_STATUS相关状态 | 设置总线带宽 |
| setBusTiming | cntlr:核心层结构体指针,MMC控制器<br>timing:枚举值(见MmcBusTiming定义),总线时序 | HDF_STATUS相关状态 | 设置总线时序 |
| setSdioIrq | cntlr:核心层结构体指针,MMC控制器<br>enable:布尔值,控制中断 | HDF_STATUS相关状态 | 使能/去使能SDIO中断 |
| hardwareReset | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 复位硬件 |
| systemInit | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 系统初始化 |
| setEnhanceSrobe | cntlr:核心层结构体指针,MMC控制器<br>enable:布尔值,设置功能 | HDF_STATUS相关状态 | 设置增强选通 |
| switchVoltage | cntlr:核心层结构体指针,MMC控制器<br>volt:枚举值,电压值(3.3,1.8,1.2V) | HDF_STATUS相关状态 | 设置电压值 |
| devReadOnly | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否只读 |
| cardPluged | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否拔出 |
| devBusy | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否忙碌 |
| tune | cntlr:核心层结构体指针,MMC控制器<br>cmdCode:uint32_t,命令代码 | HDF_STATUS相关状态 | 调谐 |
| rescanSdioDev | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 扫描并添加SDIO设备 |
## 开发步骤
......@@ -71,7 +71,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
3. **实例化MMC控制器对象:**
- 初始化MmcCntlr成员。
- 实例化MmcCntlr成员MmcCntlrOps。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>
> 实例化MmcCntlr成员MmcCntlrOps,其定义和成员说明见[接口说明](#接口说明)。
4. **驱动调试:**
......@@ -91,17 +91,17 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
```
struct HdfDriverEntry g_mmcDriverEntry = {
.moduleVersion = 1,
.Bind = HimciMmcBind, //见Bind参考
.Init = HimciMmcInit, //见Init参考
.Release = HimciMmcRelease, //见Release参考
.moduleName = "hi3516_mmc_driver",//【必要且与HCS文件中里面的moduleName匹配】
.Bind = HimciMmcBind, // 见Bind参考
.Init = HimciMmcInit, // 见Init参考
.Release = HimciMmcRelease, // 见Release参考
.moduleName = "hi3516_mmc_driver",// 【必要且与HCS文件中里面的moduleName匹配】
};
HDF_INIT(g_mmcDriverEntry); //调用HDF_INIT将驱动入口注册到HDF框架中
HDF_INIT(g_mmcDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
```
2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在mmc_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层MmcCntlr成员的默认值或限制范围有密切关系。
如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在mmc_config文件中增加对应的器件属性**。**
- device_info.hcs 配置参考
- device_info.hcs 配置参考
```
......@@ -116,9 +116,9 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
policy = 2;
priority = 10;
permission = 0644;
moduleName = "hi3516_mmc_driver"; //【必要】用于指定驱动名称,需要与驱动Entry中的moduleName一致;
serviceName = "HDF_PLATFORM_MMC_0"; //【必要】驱动对外发布服务的名称,必须唯一
deviceMatchAttr = "hi3516_mmc_emmc";//【必要】用于配置控制器私有数据,要与 mmc_config.hcs 中对应控制器保持一致
moduleName = "hi3516_mmc_driver"; // 【必要】用于指定驱动名称,需要与驱动Entry中的moduleName一致;
serviceName = "HDF_PLATFORM_MMC_0"; // 【必要】驱动对外发布服务的名称,必须唯一
deviceMatchAttr = "hi3516_mmc_emmc";// 【必要】用于配置控制器私有数据,要与 mmc_config.hcs 中对应控制器保持一致
}
device1 :: deviceNode {
policy = 1;
......@@ -126,7 +126,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
permission = 0644;
moduleName = "hi3516_mmc_driver";
serviceName = "HDF_PLATFORM_MMC_1";
deviceMatchAttr = "hi3516_mmc_sd"; //SD类型
deviceMatchAttr = "hi3516_mmc_sd"; // SD类型
}
device2 :: deviceNode {
policy = 1;
......@@ -134,7 +134,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
permission = 0644;
moduleName = "hi3516_mmc_driver";
serviceName = "HDF_PLATFORM_MMC_2";
deviceMatchAttr = "hi3516_mmc_sdio";//SDIO类型
deviceMatchAttr = "hi3516_mmc_sdio";// SDIO类型
}
}
}
......@@ -142,32 +142,32 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
}
```
- mmc_config.hcs 配置参考。
- mmc_config.hcs配置参考
```
root {
platform {
mmc_config {
template mmc_controller {//模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省
template mmc_controller {// 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省
match_attr = "";
voltDef = 0; // 3.3V
freqMin = 50000; //【必要】最小频率值
freqMax = 100000000; //【必要】最大频率值
freqDef = 400000; //【必要】默认频率值
maxBlkNum = 2048; //【必要】最大的block号
maxBlkSize = 512; //【必要】最大的block个数
ocrDef = 0x300000; //【必要】工作电压设置相关
caps2 = 0; //【必要】属性寄存器相关,见mmc_caps.h 中 MmcCaps2 定义
regSize = 0x118; //【必要】寄存器位宽
hostId = 0; //【必要】主机号
regBasePhy = 0x10020000;//【必要】寄存器物理基地址
irqNum = 63; //【必要】中断号
devType = 2; //【必要】模式选择:emmc, SD, SDIO ,COMBO
caps = 0x0001e045; //【必要】属性寄存器相关,见mmc_caps.h 中 MmcCaps 定义
freqMin = 50000; // 【必要】最小频率值
freqMax = 100000000; // 【必要】最大频率值
freqDef = 400000; // 【必要】默认频率值
maxBlkNum = 2048; // 【必要】最大的block号
maxBlkSize = 512; // 【必要】最大的block个数
ocrDef = 0x300000; // 【必要】工作电压设置相关
caps2 = 0; // 【必要】属性寄存器相关,见mmc_caps.h中MmcCaps2定义
regSize = 0x118; // 【必要】寄存器位宽
hostId = 0; // 【必要】主机号
regBasePhy = 0x10020000;// 【必要】寄存器物理基地址
irqNum = 63; // 【必要】中断号
devType = 2; // 【必要】模式选择:emmc, SD, SDIO ,COMBO
caps = 0x0001e045; // 【必要】属性寄存器相关,见mmc_caps.h 中 MmcCaps 定义
}
controller_0x10100000 :: mmc_controller {
match_attr = "hi3516_mmc_emmc";//【必要】需要和device_info.hcs中的deviceMatchAttr值一致
match_attr = "hi3516_mmc_emmc";// 【必要】需要和device_info.hcs中的deviceMatchAttr值一致
hostId = 0;
regBasePhy = 0x10100000;
irqNum = 96;
......@@ -180,7 +180,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
hostId = 1;
regBasePhy = 0x100f0000;
irqNum = 62;
devType = 1; // sd类型
devType = 1; // SD类型
caps = 0xd001e005;
}
controller_0x10020000 :: mmc_controller {
......@@ -188,7 +188,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
hostId = 2;
regBasePhy = 0x10020000;
irqNum = 63;
devType = 2; // sdio类型
devType = 2; // SDIO类型
caps = 0x0001e04d;
}
}
......@@ -197,16 +197,16 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
```
3. 完成驱动入口注册之后,最后一步就是以核心层MmcCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化MmcCntlr成员MmcCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
- 自定义结构体参考
- 自定义结构体参考
从驱动的角度看,自定义结构体是参数和数据的载体,而且mmc_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员 ,一些重要数值也会传递给核心层对象。
```
struct HimciHost {
struct MmcCntlr *mmc;//【必要】核心层结构体
struct MmcCmd *cmd; //【必要】核心层结构体,传递命令的,相关命令见枚举量 MmcCmdCode
//【可选】根据厂商驱动需要添加
struct MmcCntlr *mmc;// 【必要】核心层结构体
struct MmcCmd *cmd; // 【必要】核心层结构体,传递命令的,相关命令见枚举量 MmcCmdCode
// 【可选】根据厂商驱动需要添加
void *base;
enum HimciPowerStatus powerStatus;
uint8_t *alignedBuff;
......@@ -223,7 +223,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
bool waitForEvent;
HIMCI_EVENT himciEvent;
};
//MmcCntlr是核心层控制器结构体,其中的成员在bind函数中会被赋值
// MmcCntlr是核心层控制器结构体,其中的成员在bind函数中会被赋值
struct MmcCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *hdfDevObj;
......@@ -278,11 +278,11 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
入参**:**
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。
HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值:
HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)。
HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)。
| 状态(值) | 问题描述 |
| -------- | -------- |
......@@ -307,20 +307,20 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));
host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost));
host->mmc = cntlr; //【必要】使HimciHost与MmcCntlr可以相互转化的前提
cntlr->priv = (void *)host; //【必要】使HimciHost与MmcCntlr可以相互转化的前提
cntlr->ops = &g_himciHostOps; //【必要】MmcCntlrOps的实例化对象的挂载
cntlr->hdfDevObj = obj; //【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提
obj->service = &cntlr->service; //【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提
ret = MmcCntlrParse(cntlr, obj); //【必要】 初始化 cntlr. 失败就 goto _ERR;
host->mmc = cntlr; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提
cntlr->priv = (void *)host; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提
cntlr->ops = &g_himciHostOps; // 【必要】MmcCntlrOps的实例化对象的挂载
cntlr->hdfDevObj = obj; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提
obj->service = &cntlr->service; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提
ret = MmcCntlrParse(cntlr, obj); // 【必要】 初始化 cntlr,失败就goto _ERR;
...
ret = HimciHostParse(host, obj); //【必要】 初始化 host对象的相关属性,失败就 goto _ERR;
ret = HimciHostParse(host, obj); // 【必要】 初始化host对象的相关属性,失败就goto _ERR;
...
ret = HimciHostInit(host, cntlr);//厂商自定义的初始化,失败就 goto _ERR;
ret = HimciHostInit(host, cntlr);// 厂商自定义的初始化,失败就 goto _ERR;
...
ret = MmcCntlrAdd(cntlr); //调用核心层函数 失败就 goto _ERR;
ret = MmcCntlrAdd(cntlr); // 调用核心层函数 失败就goto _ERR;
...
(void)MmcCntlrAddDetectMsgToQueue(cntlr);//将卡检测消息添加到队列中。
(void)MmcCntlrAddDetectMsgToQueue(cntlr);// 将卡检测消息添加到队列中。
HDF_LOGD("HimciMmcBind: success.");
return HDF_SUCCESS;
_ERR:
......@@ -334,7 +334,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
入参:
HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。
HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值:
......@@ -364,7 +364,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
入参:
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值:
......@@ -380,8 +380,8 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
{
struct MmcCntlr *cntlr = NULL;
...
cntlr = (struct MmcCntlr *)obj->service;//这里有HdfDeviceObject到MmcCntlr的强制转化,通过service成员,赋值见Bind函数
cntlr = (struct MmcCntlr *)obj->service;// 这里有HdfDeviceObject到MmcCntlr的强制转化,通过service成员,赋值见Bind函数
...
HimciDeleteHost((struct HimciHost *)cntlr->priv);//厂商自定义的内存释放函数,这里有MmcCntlr到HimciHost的强制转化
HimciDeleteHost((struct HimciHost *)cntlr->priv);// 厂商自定义的内存释放函数,这里有MmcCntlr到HimciHost的强制转化
}
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册