add 07_GPIO/05_GPIO子系统层次与数据结构

This commit is contained in:
weidongshan
2021-05-27 18:56:46 +08:00
parent 0325712b6a
commit 081149403f
19 changed files with 304 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
## GPIO子系统层次与数据结构
参考资料:
* Linux 5.x内核文档
* Linux-5.4\Documentation\driver-api
* Linux-5.4\Documentation\devicetree\bindings\gpio\gpio.txt
* Linux-5.4\drivers\gpio\gpio-74x164.c
* Linux 4.x内核文档
* Linux-4.9.88\Documentation\gpio
* Linux-4.9.88\Documentation\devicetree\bindings\gpio\gpio.txt
* Linux-4.9.88\drivers\gpio\gpio-74x164.c
### 1. GPIO子系统的层次
#### 1.1 层次
![image-20210527103908743](pic/07_GPIO/03_gpio_system_level.png)
#### 1.2 GPIOLIB向上提供的接口
| descriptor-based | legacy | 说明 |
| ---------------------- | --------------------- | ---- |
| 获得GPIO | | |
| gpiod_get | gpio_request | |
| gpiod_get_index | | |
| gpiod_get_array | gpio_request_array | |
| devm_gpiod_get | | |
| devm_gpiod_get_index | | |
| devm_gpiod_get_array | | |
| 设置方向 | | |
| gpiod_direction_input | gpio_direction_input | |
| gpiod_direction_output | gpio_direction_output | |
| 读值、写值 | | |
| gpiod_get_value | gpio_get_value | |
| gpiod_set_value | gpio_set_value | |
| 释放GPIO | | |
| gpio_free | gpio_free | |
| gpiod_put | gpio_free_array | |
| gpiod_put_array | | |
| devm_gpiod_put | | |
| devm_gpiod_put_array | | |
#### 1.3 GPIOLIB向下提供的接口
![image-20210527141654915](pic/07_GPIO/07_gpiochip_add_data.png)
### 2. 重要的3个核心数据结构
记住GPIO Controller的要素这有助于理解它的驱动程序
* 一个GPIO Controller里有多少个引脚有哪些引脚
* 需要提供函数,设置引脚方向、读取/设置数值
* 需要提供函数,把引脚转换为中断
以Linux面向对象编程的思想一个GPIO Controller必定会使用一个结构体来表示这个结构体必定含有这些信息
* GPIO引脚信息
* 控制引脚的函数
* 中断相关的函数
#### 2.1 gpio_device
每个GPIO Controller用一个gpio_device来表示
* 里面每一个gpio引脚用一个gpio_desc来表示
* gpio引脚的函数(引脚控制、中断相关)都放在gpio_chip里
![image-20210527115015701](pic/07_GPIO/04_gpio_device.png)
#### 2.2 gpio_chip
我们并不需要自己穿件gpio_device编写驱动时要创建的是gpio_chip里面提供了
* 控制引脚的函数
* 中断相关的函数
* 引脚信息:支持多少个引脚?各个引脚的名字?
![image-20210527141048567](pic/07_GPIO/05_gpio_chip.png)
#### 2.3 gpio_desc
我们去使用GPIO子系统时首先是获得某个引脚对应的gpio_desc。
gpio_device表示一个GPIO Controller里面支持多个GPIO。
在gpio_device中有一个gpio_desc数组每一引脚有一项gpio_desc。
![image-20210527142042290](pic/07_GPIO/08_gpio_desc.png)
### 3. 怎么编写GPIO Controller驱动程序
分配、设置、注册gpioc_chip结构体示例`drivers\gpio\gpio-74x164.c`
![image-20210527141554940](pic/07_GPIO/06_gpio_controller_driver_example.png)

View File

@@ -0,0 +1,96 @@
## IMX6ULL的GPIO驱动源码分析
参考资料:
* Linux 4.x内核文档
* Linux-4.9.88\Documentation\gpio
* Linux-4.9.88\Documentation\devicetree\bindings\gpio\gpio.txt
* Linux-4.9.88\drivers\gpio\gpio-mxc.c
* Linux-4.9.88\arch\arm\boot\dts\imx6ull.dtsi
### 1. 设备树
Linux-4.9.88\arch\arm\boot\dts\imx6ull.dtsi
```shell
aliases {
can0 = &flexcan1;
can1 = &flexcan2;
ethernet0 = &fec1;
ethernet1 = &fec2;
gpio0 = &gpio1;
};
gpio1: gpio@0209c000 {
compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
reg = <0x0209c000 0x4000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
```
GPIO控制器的设备树中有两项是必须的
* gpio-controller : 表明这是一个GPIO控制器
* gpio-cells : 指定使用多少个cell(就是整数)来描述一个引脚
当解析设备节点中的GPIO信息时需要用到上面的属性。
比如下面的`led-gpios`,在`#gpio-cells = <2>`的情况下它表示的引脚数量是1。
```shell
myled {
compatible = "100ask,leddrv";
led-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
};
```
### 2. 驱动程序
Linux-4.9.88\drivers\gpio\gpio-mxc.c
#### 2.1 分配gpio_chip
```c
static int mxc_gpio_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mxc_gpio_port *port;
struct resource *iores;
int irq_base = 0;
int err;
mxc_gpio_get_hw(pdev);
port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
```
#### 2.2 设置gpio_chip
![image-20210527175122546](pic/07_GPIO/09_imx6ull_gpio_chip_set.png)
#### 2.3 注册gpio_chip
```c
err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port);
if (err)
goto out_bgio;
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -229,6 +229,12 @@ git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
04_在100ASK_STM32MP157上机实验
```
* 2021.05.27 发布"GPIO子系统":
```shell
05_GPIO子系统层次与数据结构
```

View File

@@ -0,0 +1,101 @@
## GPIO子系统层次与数据结构
参考资料:
* Linux 5.x内核文档
* Linux-5.4\Documentation\driver-api
* Linux-5.4\Documentation\devicetree\bindings\gpio\gpio.txt
* Linux-5.4\drivers\gpio\gpio-74x164.c
* Linux 4.x内核文档
* Linux-4.9.88\Documentation\gpio
* Linux-4.9.88\Documentation\devicetree\bindings\gpio\gpio.txt
* Linux-4.9.88\drivers\gpio\gpio-74x164.c
### 1. GPIO子系统的层次
#### 1.1 层次
![image-20210527103908743](pic/07_GPIO/03_gpio_system_level.png)
#### 1.2 GPIOLIB向上提供的接口
| descriptor-based | legacy | 说明 |
| ---------------------- | --------------------- | ---- |
| 获得GPIO | | |
| gpiod_get | gpio_request | |
| gpiod_get_index | | |
| gpiod_get_array | gpio_request_array | |
| devm_gpiod_get | | |
| devm_gpiod_get_index | | |
| devm_gpiod_get_array | | |
| 设置方向 | | |
| gpiod_direction_input | gpio_direction_input | |
| gpiod_direction_output | gpio_direction_output | |
| 读值、写值 | | |
| gpiod_get_value | gpio_get_value | |
| gpiod_set_value | gpio_set_value | |
| 释放GPIO | | |
| gpio_free | gpio_free | |
| gpiod_put | gpio_free_array | |
| gpiod_put_array | | |
| devm_gpiod_put | | |
| devm_gpiod_put_array | | |
#### 1.3 GPIOLIB向下提供的接口
![image-20210527141654915](pic/07_GPIO/07_gpiochip_add_data.png)
### 2. 重要的3个核心数据结构
记住GPIO Controller的要素这有助于理解它的驱动程序
* 一个GPIO Controller里有多少个引脚有哪些引脚
* 需要提供函数,设置引脚方向、读取/设置数值
* 需要提供函数,把引脚转换为中断
以Linux面向对象编程的思想一个GPIO Controller必定会使用一个结构体来表示这个结构体必定含有这些信息
* GPIO引脚信息
* 控制引脚的函数
* 中断相关的函数
#### 2.1 gpio_device
每个GPIO Controller用一个gpio_device来表示
* 里面每一个gpio引脚用一个gpio_desc来表示
* gpio引脚的函数(引脚控制、中断相关)都放在gpio_chip里
![image-20210527115015701](pic/07_GPIO/04_gpio_device.png)
#### 2.2 gpio_chip
我们并不需要自己穿件gpio_device编写驱动时要创建的是gpio_chip里面提供了
* 控制引脚的函数
* 中断相关的函数
* 引脚信息:支持多少个引脚?各个引脚的名字?
![image-20210527141048567](pic/07_GPIO/05_gpio_chip.png)
#### 2.3 gpio_desc
我们去使用GPIO子系统时首先是获得某个引脚对应的gpio_desc。
gpio_device表示一个GPIO Controller里面支持多个GPIO。
在gpio_device中有一个gpio_desc数组每一引脚有一项gpio_desc。
![image-20210527142042290](pic/07_GPIO/08_gpio_desc.png)
### 3. 怎么编写GPIO Controller驱动程序
分配、设置、注册gpioc_chip结构体示例`drivers\gpio\gpio-74x164.c`
![image-20210527141554940](pic/07_GPIO/06_gpio_controller_driver_example.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB