diff --git a/zh-cn/device-dev/driver/Readme-CN.md b/zh-cn/device-dev/driver/Readme-CN.md
index 257ae75de412f89746fb2218c21dfdd4148bedb8..faecd64a7e4174d4bdd8d3a5a824df25a8d54636 100755
--- a/zh-cn/device-dev/driver/Readme-CN.md
+++ b/zh-cn/device-dev/driver/Readme-CN.md
@@ -32,6 +32,7 @@
- [I3C](driver-platform-i3c-des.md)
- [MIPI-CSI](driver-platform-mipicsi-des.md)
- [MIPI-DSI](driver-platform-mipidsi-des.md)
+ - [PIN](driver-platform-pin-des.md)
- [PWM](driver-platform-pwm-des.md)
- [REGULATOR](driver-platform-regulator-des.md)
- [RTC](driver-platform-rtc-des.md)
diff --git a/zh-cn/device-dev/driver/driver-platform-pin-des.md b/zh-cn/device-dev/driver/driver-platform-pin-des.md
new file mode 100644
index 0000000000000000000000000000000000000000..88d20ee83e22e1fdc5e9802c717a4d0bf7abf6bc
--- /dev/null
+++ b/zh-cn/device-dev/driver/driver-platform-pin-des.md
@@ -0,0 +1,416 @@
+# PIN
+
+- [概述](#section1)
+ - [功能简介](#section2)
+ - [基本概念](#section3)
+ - [运作机制](#section4)
+ - [约束与限制](#section5)
+- [使用指导](#section6)
+ - [场景介绍](#section7)
+ - [接口说明](#section8)
+ - [开发步骤](#section9)
+ - [使用实例](#section10)
+
+## 概述
+
+### 功能简介
+
+- PIN即管脚控制器,用于统一管理各SoC厂商管脚资源,对外提供管脚复用功能:包括管脚推拉方式、管脚推拉强度以及管脚功能。
+- PIN接口定义了操作PIN管脚的通用方法集合,包括:
+ - 获取/释放管脚描述句柄: 传入管脚名与链表中每个控制器下管脚名进行匹配,匹配则会获取一个管脚描述句柄,操作完PIN管脚后释放该管脚描述句柄。
+ - 设置/获取管脚推拉方式:推拉方式可以是上拉、下拉以及悬空。
+ - 设置/获取管脚推拉强度:用户可根据实际设置管脚推拉强度大小。
+ - 设置/获取管脚功能:通过管脚功能名设置/获取管脚功能,实现管脚复用。
+
+### 基本概念
+PIN是一个软件层面的概念,目的是为了统一各SoC厂商PIN管脚管理,对外提供管脚复用功能,配置PIN管脚的电气特性。
+
+- SoC(System on Chip)
+
+ 系统级芯片,也有称作片上系统,通常是面向特定用途将微处理器、模拟IP核、数字IP核和存储器集成在单一芯片的标准产品。
+
+- 管脚复用
+
+ 由于芯片自身的引脚数量有限,无法满足日益增多的外接需求。此时可以通过软件层面的寄存器设置,让引脚工作在不同的状态,从而实现相同引脚完成不同功能的目的。
+
+### 运作机制
+
+在HDF框架中,PIN模块暂不支持用户态,所以不需要发布服务,接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,其关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。
+
+PIN模块各分层作用:接口层提供获取PIN管脚、设置PIN管脚推拉方式、获取PIN管脚推拉方式、设置PIN管脚推拉强度、获取PIN管脚推拉强度、设置PIN管脚功能、获取PIN管脚功能、释放PIN管脚的接口。核心层主要提供PIN管脚资源匹配,PIN管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。适配层主要是将钩子函数的功能实例化,实现具体的功能。
+
+**图 1** PIN无服务模式
+![](figures/无服务模式结构图.png "PIN无服务模式")
+
+### 约束与限制
+
+ PIN模块目前仅支持轻量和小型系统内核(LiteOS)。
+
+ ## 使用指导
+
+ ### 场景介绍
+
+ PIN模块仅是一个软件层面的概念,主要工作是管脚资源管理。使用复用管脚时,通过设置管脚功能、设置管脚推拉方式、设置管脚推拉强度来适配指定场景的需求。
+
+### 接口说明
+
+PIN模块提供的主要接口如[表1](#table1)所示,更多关于接口的介绍请参考对应的API接口文档。
+
+**表 1** PIN驱动API接口功能介绍
+
+
+| **接口名** | **描述** |
+| ------------------------------------------------------------ | ---------------- |
+| DevHandle PinGet(const char *pinName); | 获取管脚描述句柄 |
+| void PinPut(DevHandle handle); | 释放管脚描述句柄 |
+| int32_t PinSetPull(DevHandle handle, enum PinPullType pullType); | 设置管脚推拉方式 |
+| int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType); | 获取管脚推拉方式 |
+| int32_t PinSetStrength(DevHandle handle, uint32_t strength); | 设置管脚推拉强度 |
+| int32_t PinGetStrength(DevHandle handle, uint32_t *strength); | 获取管脚推拉强度 |
+| int32_t PinSetFunc(DevHandle handle, const char *funcName); | 设置管脚功能 |
+| int32_t PinGetFunc(DevHandle handle, const char **funcName); | 获取管脚功能 |
+
+>![](../public_sys-resources/icon-note.gif) **说明:**
+>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。
+
+### 开发步骤
+
+使用PIN设备的一般流程如[图2](#fig2)所示。
+
+ **图 2** PIN使用流程图
+![](figures/PIN使用流程图.png "PIN使用流程图")
+
+#### 获取PIN管脚描述句柄
+
+在使用PIN进行管脚操作时,首先要调用PinGet获取管脚描述句柄,该函数会返回匹配传入管脚名的管脚描述句柄。
+
+```
+DevHandle PinGet(const char *pinName);
+```
+
+**表 2** PinGet参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | ----------------------- |
+| pinName | 管脚名 |
+| **返回值** | **返回值描述** |
+| NULL | 获取PIN管脚描述句柄失败 |
+| handle | PIN管脚描述句柄 |
+
+假设PIN需要操作的管脚名为P18,获取其管脚描述句柄的示例如下:
+
+```
+DevHandle handle = NULL; /* PIN管脚描述句柄 */
+char pinName = "P18"; /* PIN管脚号 */
+handle = PinGet(pinName);
+if (handle == NULL) {
+ HDF_LOGE("PinGet: get handle failed!\n");
+ return;
+}
+```
+
+#### PIN设置管脚推拉方式
+
+PIN设置管脚推拉方式的函数如下所示:
+
+```
+int32_t PinSetPull(DevHandle handle, enum PinPullType pullType);
+```
+
+**表 3** 参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | ----------------------- |
+| handle | PIN管脚描述句柄 |
+| pullType | PIN管脚推拉方式 |
+| **返回值** | **返回值描述** |
+| 0 | PIN设置管脚推拉方式成功 |
+| 负数 | PIN设置管脚推拉方式失败 |
+
+假设PIN要设置的管脚推拉方式为上拉,其实例如下:
+
+```
+int32_t ret;
+enum PinPullType pullTypeNum;
+/* PIN设置管脚推拉方式 */
+pullTypeNum = 1;
+ret = PinSetPull(handle, pullTypeNum);
+if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinSetPull: failed, ret %d\n", ret);
+ return ret;
+}
+```
+
+#### PIN获取管脚推拉方式
+
+PIN获取管脚推拉方式的函数如下所示:
+
+```
+int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType);
+```
+
+**表 4** PinGetPull参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | ------------------------- |
+| handle | PIN管脚描述句柄 |
+| pullType | 接收PIN管脚推拉方式的指针 |
+| **返回值** | **返回值描述** |
+| 0 | PIN获取管脚推拉方式成功 |
+| 负数 | PIN获取管脚推拉方式失败 |
+
+PIN获取管脚推拉方式的实例如下:
+
+```
+int32_t ret;
+enum PinPullType pullTypeNum;
+/* PIN获取管脚推拉方式 */
+ret = PinGetPull(handle, &pullTypeNum);
+if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinGetPull: failed, ret %d\n", ret);
+ return ret;
+}
+```
+
+#### PIN设置管脚推拉强度
+
+PIN设置管脚推拉强度函数如下所示:
+
+```
+int32_t PinSetStrength(DevHandle handle, uint32_t strength);
+```
+
+**表 5** PinSetStrength参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | ----------------------- |
+| handle | 管脚描述句柄 |
+| strength | PIN管脚推拉强度 |
+| **返回值** | **返回值描述** |
+| 0 | PIN设置管脚推拉强度成功 |
+| 负数 | PIN设置管脚推拉强度失败 |
+
+假设PIN要设置的管脚推拉强度为2,其实例如下:
+
+```
+int32_t ret;
+uint32_t strengthNum;
+/* PIN设置管脚推拉强度 */
+strengthNum = 2;
+ret = PinSetStrength(handle, strengthNum);
+if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinSetStrength: failed, ret %d\n", ret);
+ return ret;
+}
+```
+
+#### PIN获取管脚推拉强度
+
+PIN设置管脚推拉强度后,可以通过PIN获取管脚推拉强度接口来查看PIN管脚推拉强度,PIN获取管脚推拉强度的函数如下所示:
+
+```
+int32_t PinGetStrength(DevHandle handle, uint32_t *strength);
+```
+
+**表 6** PinGetStrength参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | ------------------------- |
+| handle | 管脚描述句柄 |
+| strength | 接收PIN管脚推拉强度的指针 |
+| **返回值** | **返回值描述** |
+| 0 | PIN获取管脚推拉强度成功 |
+| 负数 | PIN获取管脚推拉强度失败 |
+
+PIN获取管脚推拉强度的实例如下:
+
+```
+int32_t ret;
+uint32_t strengthNum;
+/* PIN获取管脚推拉强度 */
+ret = PinGetStrength(handle, &strengthNum);
+if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinGetStrength: failed, ret %d\n", ret);
+ return ret;
+}
+```
+
+#### PIN设置管脚功能
+
+管脚功能特指的是管脚复用的功能,每个管脚功能都不相同,管脚功能名详细可以参考[PIN配置hcs文件](https://gitee.com/openharmony/device_soc_hisilicon/blob/master/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs)。
+
+PIN设置管脚功能函数如下所示:
+
+```
+int32_t PinSetFunc(DevHandle handle, const char *funcName);
+```
+
+**表 7** PinSetFunc参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | ------------------- |
+| handle | 管脚描述句柄 |
+| funcName | PIN管脚功能名 |
+| **返回值** | **返回值描述** |
+| 0 | PIN设置管脚功能成功 |
+| 负数 | PIN设置管脚功能失败 |
+
+假设PIN需要设置的管脚功能为LSADC_CH1(ADC通道1),其实例如下:
+
+```
+int32_t ret;
+char funcName = "LSADC_CH1";
+/* PIN设置管脚功能 */
+ret = PinSetFunc(handle, funcName);
+if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinSetFunc: failed, ret %d\n", ret);
+ return ret;
+}
+```
+
+#### PIN获取管脚功能
+
+PIN设置管脚功能后,可以通过PIN获取管脚功能接口来查看PIN管脚功能,PIN获取管脚功能的函数如下所示:
+
+```
+int32_t PinGetFunc(DevHandle handle, const char **funcName);
+```
+
+**表 8** PinGetFunc参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | --------------------- |
+| handle | 管脚描述句柄 |
+| funcName | 接收PIN管脚功能名指针 |
+| **返回值** | **返回值描述** |
+| 0 | PIN获取管脚功能成功 |
+| 负数 | PIN获取管脚功能失败 |
+
+PIN获取管脚功能的实例如下:
+
+```
+int32_t ret;
+char *funcName;
+/* PIN获取管脚功能 */
+ret = PinGetFunc(handle,&funcName);
+if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinGetFunc: failed, ret %d\n", ret);
+ return ret;
+}
+```
+
+#### 释放PIN管脚描述句柄
+
+PIN不再进行任何操作后,需要释放PIN管脚描述管脚句柄,函数如下所示:
+
+```
+void PinPut(DevHandle handle);
+```
+
+**表 9** PinPut参数和返回值描述
+
+
+
+| 参数 | 参数描述 |
+| ---------- | -------------- |
+| handle | 管脚描述句柄 |
+| **返回值** | **返回值描述** |
+| NA | 无返回值 |
+
+PIN销毁管脚描述句柄实例如下:
+
+```
+PinPut(handle);
+```
+
+## 使用实例
+
+使用PIN设置管脚相关属性完整使用可以参考如下示例代码,示例代码步骤主要如下:
+1. 传入要设置的管脚名,获取PIN管脚描述句柄。
+2. 通过PIN管脚描述句柄以及推拉方式pullTypeNum设置管脚推拉方式,如果操作失败则释放PIN管脚描述句柄。
+3. 通过PIN管脚描述句柄,并用pullTypeNum承接获取的管脚推拉方式,如果操作失败则释放PIN管脚描述句柄。
+4. 通过PIN管脚描述句柄以及推拉强度strengthNum设置管脚推拉强度,如果操作失败则释放PIN管脚描述句柄。
+5. 通过PIN管脚描述句柄,并用strengthNum承接获取的管脚推拉强度,如果操作失败则释放PIN管脚描述句柄。
+5. 通过PIN管脚描述句柄以及管脚功能名funName设置管脚功能,如果操作失败则释放PIN管脚描述句柄。
+6. 通过PIN管脚描述句柄,并用funName承接获取的管脚功能名,如果操作失败则释放PIN管脚描述句柄。
+7. 使用完PIN后,不再对管脚进行操作,释放PIN管脚描述句柄。
+
+```
+#include "hdf_log.h" /* 标准日志打印头文件 */
+#include "pin_if.h" /* PIN标准接口头文件 */
+
+int32_t PinTestSample(void)
+{
+ int32_t ret;
+ uint32_t strengthNum;
+ enum PinPullType pullTypeNum;
+ char pinName;
+ char *funName;
+ DevHandle handle = NULL;
+
+ /* PIN管脚名,要填写实际要设置的管脚名 */
+ pinName = "P18";
+ /* PIN获取管脚描述句柄 */
+ handle = PinGet(pinName);
+ if (handle == NULL) {
+ HDF_LOGE("PinGet: failed!\n");
+ return;
+ }
+ /* PIN设置管脚推拉方式为上拉 */
+ pullTypeNum = 1;
+ ret = PinSetPull(handle, pullTypeNum);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinSetPull: failed, ret %d\n", ret);
+ goto ERR;
+ }
+ /* PIN获取管脚推拉方式 */
+ ret = PinGetPull(handle, &pullTypeNum);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinGetPull: failed, ret %d\n", ret);
+ goto ERR;
+ }
+ /* PIN设置管脚推拉强度为2 */
+ strengthNum = 2;
+ ret = PinSetStrength(handle, strengthNum);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinSetStrength: failed, ret %d\n", ret);
+ goto ERR;
+ }
+ /* PIN获取管脚推拉强度 */
+ ret = PinGetStrength(handle, &strengthNum);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinGetStrength: failed, ret %d\n", ret);
+ goto ERR;
+ }
+ /* PIN设置管脚功能为LSADC_CH1 */
+ funName = "LSADC_CH1";
+ ret = PinSetFunc(handle, funName);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinSetFunc: failed, ret %d\n", ret);
+ goto ERR;
+ }
+ /* PIN获取管脚功能 */
+ ret = PinGetFunc(handle, &funcName);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("PinGetFunc: failed, ret %d\n", ret);
+ goto ERR;
+ }
+ERR:
+ /* 释放PIN管脚描述句柄 */
+ PinPut(handle);
+ return ret;
+}
diff --git a/zh-cn/device-dev/driver/driver-platform-pin-develop.md b/zh-cn/device-dev/driver/driver-platform-pin-develop.md
index ca0ca47d8e16a3988067e904104d4cc6e1be7fee..3e098c1fd43fb59d5a347958817e681e76ede03b 100755
--- a/zh-cn/device-dev/driver/driver-platform-pin-develop.md
+++ b/zh-cn/device-dev/driver/driver-platform-pin-develop.md
@@ -1,19 +1,54 @@
# PIN
-- [概述](#section1_PinDevelop)
-- [接口说明](#section2_PinDevelop)
-- [开发步骤](#section3_PinDevelop)
-- [开发实例](#section4_PinDevelop)
+- [概述](#section1_PinDevelop)
+ - [功能简介](#section2_PinDevelop)
+ - [基本概念](#section3_PinDevelop)
+ - [运作机制](#section4_PinDevelop)
+ - [约束与限制](#section5_PinDevelop)
+- [使用指导](#section6_PinDevelop)
+ - [场景介绍](#section7_PinDevelop)
+ - [接口说明](#section8_PinDevelop)
+ - [开发步骤](#section9_PinDevelop)
## 概述
-PIN模块用于控制系统中管脚的状态和功能特性。在HDF框架中,PIN的接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,其关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。
+### 功能简介
+PIN即管脚控制器,用于统一管理各SoC厂商管脚资源,对外提供管脚复用功能。
-图 1 无服务模式结构图
+### 基本概念
+
+PIN是一个软件层面的概念,目的是为了统一各SoC厂商PIN管脚管理,对外提供管脚复用功能,配置PIN管脚的电气特性。
+
+- SoC(System on Chip)
+
+ 系统级芯片,也有称作片上系统,通常是面向特定用途将微处理器、模拟IP核、数字IP核和存储器集成在单一芯片的标准产品。
+
+- 管脚复用
+
+ 由于芯片自身的引脚数量有限,无法满足日益增多的外接需求。此时可以通过软件层面的寄存器设置,让引脚工作在不同的状态,从而实现相同引脚完成不同功能的目的。
+
+### 运作机制
+
+在HDF框架中,PIN模块暂不支持用户态,所以不需要发布服务,接口适配模式采用无服务模式(如图1所示),用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,其关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。
+
+PIN模块各分层作用:接口层提供获取PIN管脚、设置PIN管脚推拉方式、获取PIN管脚推拉方式、设置PIN管脚推拉强度、获取PIN管脚推拉强度、设置PIN管脚功能、获取PIN管脚功能、释放PIN管脚的接口。核心层主要提供PIN管脚资源匹配,PIN管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。适配层主要是将钩子函数的功能实例化,实现具体的功能。
+
+**图 1** 无服务模式结构图
![image1](figures/无服务模式结构图.png)
-## 接口说明
+### 约束与限制
+
+ PIN模块目前仅支持轻量和小型系统内核(LiteOS)。
+
+## 开发指导
+
+### 场景介绍
+PIN模块主要用于管脚资源管理。在各SoC厂商对接HDF框架时,需要来适配PIN驱动。
+
+### 接口说明
+
+通过以下PinCntlrMethod中的函数调用PIN驱动对应的函数。
PinCntlrMethod定义:
```c
@@ -29,288 +64,370 @@ struct PinCntlrMethod {
**表 1** PinCntlrMethod成员的回调函数功能说明
-| 成员函数 | 入参 | 返回值 | 功能 |
-| ------------ | ------------------------------------------- | ------ | ---- |
-| SetPinPull | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**pullType**:枚举常量,Pin管脚推拉方式; |HDF_STATUS相关状态|设置Pin管脚推拉方式|
-| GetPinPull | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**pullType**:枚举常量指针,传出Pin管脚推拉方式; | HDF_STATUS相关状态 | 获取Pin管脚推拉方式 |
-| SetPinStrength | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**strength**:uint32_t变量,Pin推拉强度; | HDF_STATUS相关状态 | 设置Pin推拉强度 |
-| GetPinStrength | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**strength**:uint32_t变量指针,传出Pin推拉强度; | HDF_STATUS相关状态 | 获取Pin推拉强度 |
-| SetPinFunc | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**funcName**:char指针常量,传入Pin管脚功能; | HDF_STATUS相关状态 | 设置Pin管脚功能 |
-| GetPinFunc | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**funcName**:char双重指针常量,传出Pin管脚功能; | HDF_STATUS相关状态 | 获取Pin管脚功能 |
+| 成员函数 | 入参 | 出参 | 返回值 | 功能 |
+| ------------ | ------------------------------------------- | ------ | ---- | ---- |
+| SetPinPull | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**pullType**:枚举常量,Pin管脚推拉方式; | 无 |HDF_STATUS相关状态|PIN设置管脚推拉方式|
+| GetPinPull | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号; | **pullType**:枚举常量指针,传出Pin管脚推拉方式; | HDF_STATUS相关状态 | PIN获取管脚推拉方式 |
+| SetPinStrength | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**strength**:uint32_t变量,Pin推拉强度; | 无 | HDF_STATUS相关状态 | PIN设置推拉强度 |
+| GetPinStrength | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号; | **strength**:uint32_t变量指针,传出Pin推拉强度; | HDF_STATUS相关状态 | PIN获取推拉强度 |
+| SetPinFunc | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号;
**funcName**:char指针常量,传入Pin管脚功能; | 无 | HDF_STATUS相关状态 | PIN设置管脚功能 |
+| GetPinFunc | **cntlr**:结构体指针,核心层Pin控制器;
**index**:uint32_t变量,管脚索引号; | **funcName**:char双重指针常量,传出Pin管脚功能; | HDF_STATUS相关状态 | PIN获取管脚功能 |
+
+### 开发步骤
-## 开发步骤
+PIN模块适配包含以下四个步骤:
-PIN模块适配的三个环节是实例化驱动入口、配置属性文件、以及实例化核心层接口函数。
+- 实例化驱动入口。
+- 配置属性文件。
+- 实例化核心层接口函数。
+- 驱动调试。
1. **实例化驱动入口:**
-
+
- 实例化HdfDriverEntry结构体成员。
+ 驱动开发首先需要实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。
+
- 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。
-
-2. **配置属性文件:**
+ 一般在加载驱动时HDF会先调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
+
+ ```c
+ static struct HdfDriverEntry g_hi35xxPinDriverEntry = {
+ .moduleVersion = 1,
+ .Bind = Hi35xxPinBind,
+ .Init = Hi35xxPinInit,
+ .Release = Hi35xxPinRelease,
+ .moduleName = "hi35xx_pin_driver", // 【必要且与HCS文件中里面的moduleName匹配】
+ };
+ HDF_INIT(g_hi35xxPinDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
+ ```
- - 在device_info.hcs文件中添加deviceNode描述。
- - 【可选】添加pin_config.hcs器件属性文件。
+2. **配置属性文件:**
+ - 在vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。
+ ```c
+ root {
+ device_info {
+ platform :: host {
+ hostName = "platform_host";
+ priority = 50;
+ device_pin :: device {
+ device0 :: deviceNode { // 为每一个Pin控制器配置一个HDF设备节点,存在多个时须添加,否则不用
+ policy = 0; // 2:用户态可见,1:内核态可见,0:不需要发布服务
+ priority = 10; // 驱动启动优先级
+ permission = 0644; // 驱动创建设备节点权限
+ /* 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致 */
+ moduleName = "hi35xx_pin_driver";
+ /* 【必要】用于配置控制器私有数据,要与pin_config.hcs中对应控制器保持一致,具体的控制器信息在pin_config.hcs中 */
+ deviceMatchAttr = "hisilicon_hi35xx_pin_0";
+ }
+ device1 :: deviceNode {
+ policy = 0;
+ priority = 10;
+ permission = 0644;
+ moduleName = "hi35xx_pin_driver";
+ deviceMatchAttr = "hisilicon_hi35xx_pin_1";
+ }
+ ......
+ }
+ }
+ }
+ }
+ ```
+ - 添加pin_config.hcs器件属性文件。
+ 在device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs目录下配置器件属性 ,其中配置参数如下:
+ ```c
+ root {
+ platform {
+ pin_config_hi35xx {
+ template pin_controller { // 【必要】模板配置,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省
+ number = 0; // 【必要】controller编号
+ regStartBasePhy = 0; // 【必要】寄存器物理基地址起始地址
+ regSize = 0; // 【必要】寄存器位宽
+ pinCount = 0; // 【必要】管脚数量
+ match_attr = "";
+ template pin_desc {
+ pinName = ""; // 【必要】管脚名称
+ init = 0; // 【必要】寄存器默认值
+ F0 = ""; // 【必要】功能0
+ F1 = ""; // 功能1
+ F2 = ""; // 功能2
+ F3 = ""; // 功能3
+ F4 = ""; // 功能4
+ F5 = ""; // 功能5
+ }
+ }
+ controller_0 :: pin_controller {
+ number = 0;
+ regStartBasePhy = 0x10FF0000;
+ regSize = 0x48;
+ pinCount = 18;
+ match_attr = "hisilicon_hi35xx_pin_0";
+ T1 :: pin_desc {
+ pinName = "T1";
+ init = 0x0600;
+ F0 = "EMMC_CLK";
+ F1 = "SFC_CLK";
+ F2 = "SFC_BOOT_MODE";
+ }
+ ...... // 对应管脚控制器下的每个管脚,按实际添加
+ }
+ ......//每个管脚控制器对应一个controller节点,如存在多个Pin控制器,请依次添加对应的controller节点。
+ }
+ }
+ }
+ ```
3. **实例化PIN控制器对象:**
-
- 初始化PinCntlr成员。
-
- - 实例化PinCntlr成员PinCntlrMethod。
-
- >![](../public_sys-resources/icon-note.gif) **说明:**
- >实例化PinCntlr成员PinCntlrMethod,其定义和成员说明见[接口说明](#section2_PINDevelop)。
-
-4. **驱动调试:**
-
- - 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,数据传输的成功与否等。
-
-## 开发实例
+ 在Hi35xxPinCntlrInit函数中对PinCntlr成员进行初始化操作。
-下方将以pin_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。
+ ```c
+ struct Hi35xxPinDesc {
+ // 管脚名
+ const char *pinName;
+ // 初始化值
+ uint32_t init;
+ // 管脚索引
+ uint32_t index;
+ // 管脚推拉方式
+ int32_t pullType;
+ // 管脚推拉强度
+ int32_t strength;
+ // 管脚功能名字符串数组
+ const char *func[HI35XX_PIN_FUNC_MAX];
+ };
+
+ struct Hi35xxPinCntlr {
+ // 管脚控制器
+ struct PinCntlr cntlr;
+ // 管脚描述结构体指针
+ struct Hi35xxPinDesc *desc;
+ // 寄存器映射地址
+ volatile unsigned char *regBase;
+ // 管脚控制器编号
+ uint16_t number;
+ // 寄存器物理基地址起始地址
+ uint32_t regStartBasePhy;
+ // 寄存器位宽
+ uint32_t regSize;
+ // 管脚数量
+ uint32_t pinCount;
+ };
+
+ // PinCntlr是核心层控制器,其中的成员在init函数中会被赋值
+ struct PinCntlr {
+ struct IDeviceIoService service;
+ struct HdfDeviceObject *device;
+ struct PinCntlrMethod *method;
+ struct DListHead node; // 链表节点
+ OsalSpinlock spin; // 自旋锁
+ uint16_t number; // 管脚控制器编号
+ uint16_t pinCount; // 管脚数量
+ struct PinDesc *pins;
+ void *priv; // 私有数据
+ };
+
+ // PinCntlr管脚控制器初始化
+ static int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx)
+ {
+ struct DeviceResourceIface *drsOps = NULL;
+ int32_t ret;
+ // 从hcs文件读取管脚控制器相关属性
+ drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+ if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
+ HDF_LOGE("%s: invalid drs ops fail!", __func__);
+ return HDF_FAILURE;
+ }
+ ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: read number failed", __func__);
+ return ret;
+ }
+
+ ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: read regStartBasePhy failed", __func__);
+ return ret;
+ }
+ ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: read regSize failed", __func__);
+ return ret;
+ }
+ ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0);
+ if (ret != HDF_SUCCESS) {
+ HDF_LOGE("%s: read pinCount failed", __func__);
+ return ret;
+ }
+ // 将读取的值赋值给管脚控制器的成员,完成管脚控制器初始化
+ hi35xx->cntlr.pinCount = hi35xx->pinCount;
+ hi35xx->cntlr.number = hi35xx->number;
+ hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize); // 管脚控制器映射
+ if (hi35xx->regBase == NULL) {
+ HDF_LOGE("%s: remap Pin base failed", __func__);
+ return HDF_ERR_IO;
+ }
+ hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount);
+ hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount);
+ return HDF_SUCCESS;
+ }
+ ```
-1. 驱动开发首先需要实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf\_device\_desc.h 中定义)类型的全局变量,且moduleName要和device\_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。
+ - PinCntlr成员回调函数结构体PinCntlrMethod的实例化,其他成员在Init函数中初始化。
- 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
+ ```c
+ // PinCntlrMethod结构体成员都是回调函数,厂商需要根据表1完成相应的函数功能。
+ static struct PinCntlrMethod g_method = {
+ .SetPinPull = Hi35xxPinSetPull, // 设置推拉方式
+ .GetPinPull = Hi35xxPinGetPull, // 获取推拉方式
+ .SetPinStrength = Hi35xxPinSetStrength, // 设置推拉强度
+ .GetPinStrength = Hi35xxPinGetStrength, // 获取推拉强度
+ .SetPinFunc = Hi35xxPinSetFunc, // 设置管脚功能
+ .GetPinFunc = Hi35xxPinGetFunc, // 获取管脚功能
+ };
+ ```
- PIN驱动入口参考
+ - Init函数
- ```c
- static struct HdfDriverEntry g_hi35xxPinDriverEntry = {
- .moduleVersion = 1,
- .Bind = Hi35xxPinBind,
- .Init = Hi35xxPinInit,
- .Release = Hi35xxPinRelease,
- .moduleName = "hi35xx_pin_driver",//【必要且与HCS文件中里面的moduleName匹配】
- };
- //调用HDF_INIT将驱动入口注册到HDF框架中
- HDF_INIT(g_hi35xxPinDriverEntry);
- ```
+ 入参:
+ HdfDeviceObject这个是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。
-2. 完成驱动入口注册之后,下一步请在device\_info.hcs文件中添加deviceNode信息,并在pin\_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层PinCntlr成员的默认值或限制范围有密切关系。
-
- >![](../public_sys-resources/icon-note.gif) **说明:**
- >如有更多个器件信息,则需要在device\_info文件增加deviceNode信息,以及在pin\_config文件中增加对应的器件属性。
-
- - device\_info.hcs 配置参考。
-
- ```c
- root {
- device_info {
- platform :: host {
- hostName = "platform_host";
- priority = 50;
- device_pin :: device {
- device0 :: deviceNode { //为每一个Pin控制器配置一个HDF设备节点,存在多个时须添加,否则不用
- policy = 0; //2:用户态可见,1:内核态可见,0:不需要发布服务
- priority = 10; // 驱动启动优先级
- permission = 0644; // 驱动创建设备节点权限
- /*【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致;*/
- moduleName = "hi35xx_Pin_driver";
- /*【必要】用于配置控制器私有数据,要与Pin_config.hcs中对应控制器保持一致,具体的控制器信息在Pin_config.hcs 中*/
- deviceMatchAttr = "hisilicon_hi35xx_Pin_0";
- }
- device1 :: deviceNode {
- policy = 0;
- priority = 10;
- permission = 0644;
- moduleName = "hi35xx_Pin_driver";
- deviceMatchAttr = "hisilicon_hi35xx_Pin_1";
- }
- ...
- }
- }
- }
- }
- ```
-
- - Pin\_config.hcs 配置参考。
-
- ```c
- root {
- platform {
- Pin_config_hi35xx {
- template Pin_controller { //【必要】模板配置,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省
- number = 0; //【必要】controller 编号
- regStartBasePhy = 0; //【必要】寄存器物理基地址起始地址
- regSize = 0; //【必要】寄存器位宽
- PinCount = 0; //【必要】管脚数量
- match_attr = "";
- template Pin_desc {
- PinName = ""; //【必要】管脚名称
- init = 0; //【必要】寄存器默认值
- F0 = ""; //【必要】功能0
- F1 = ""; //功能1
- F2 = ""; //功能2
- F3 = ""; //功能3
- F4 = ""; //功能4
- F5 = ""; //功能5
- }
- }
- controller_0 :: Pin_controller {
- number = 0;
- regStartBasePhy = 0x10FF0000;
- regSize = 0x48;
- PinCount = 18;
- match_attr = "hisilicon_hi35xx_Pin_0";
- T1 :: Pin_desc {
- PinName = "T1";
- init = 0x0600;
- F0 = "EMMC_CLK";
- F1 = "SFC_CLK";
- F2 = "SFC_BOOT_MODE";
- }
- ...
- }
- ...//每个Pin控制器对应一个controller节点,如存在多个Pin控制器,请依次添加对应的controller节点。
- }
- }
- }
- ```
-
-3. 完成驱动入口注册之后,最后一步就是对核心层PinCntlr对象的初始化,包括厂商自定义结构体(传递参数和数据),实例化PinCntlr成员PinCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
-
- - 自定义结构体参考。
-
- 从驱动的角度看,PinCntlr结构体是参数和数据的载体,HDF框架通过DeviceResourceIface将pin\_config.hcs文件中的数值读入其中。
-
- ```c
- // PinCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
- struct PinCntlr {
- struct IDeviceIoService service;
- struct HdfDeviceObject *device;
- struct PinCntlrMethod *method;
- struct DListHead node;
- OsalSPinlock sPin;
- uint16_t number;
- uint16_t PinCount;
- struct PinDesc *Pins;
- void *priv;
- };
-
- struct PinDesc {
- const char *PinName; //Pin管脚名
- void *priv;
- };
- ```
-
- - 实例化PinCntlr成员PinCntlrMethod,其他成员在Init函数中初始化。
-
- ```c
- // Pin_hi35xx.c 中的示例:钩子函数的填充
- static struct PinCntlrMethod g_method = {
- .SetPinPull = Hi35xxPinSetPull,
- .GetPinPull = Hi35xxPinGetPull,
- .SetPinStrength = Hi35xxPinSetStrength,
- .GetPinStrength = Hi35xxPinGetStrength,
- .SetPinFunc = Hi35xxPinSetFunc,
- .GetPinFunc = Hi35xxPinGetFunc,
- };
- ```
-
- - Init函数参考
-
- 入参:
-
- HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。
-
- 返回值:
-
- HDF\_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见/drivers/framework/include/utils/hdf\_base.h中HDF\_STATUS 定义)。
-
- **表 2** HDF\_STATUS相关状态
+ 返回值:
+ HDF\_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见/drivers/framework/include/utils/hdf\_base.h中HDF\_STATUS 定义)。
-
- | -- | -
---|---|
- | -- | -
- | -- | -
- | -- | -
- | -- | -
- | -- | -
- | -- | -