用户工具

站点工具


jaysnote:gpio_libc

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

jaysnote:gpio_libc [2019/04/26 17:13]
jaylee
jaysnote:gpio_libc [2021/06/22 23:14]
行 1: 行 1:
-<markdown> 
-# gpio 
- 
-对linux c app里面的一个gpio操作云里雾里半天,是时候好好理理了。 
- 
-* https://www.kernel.org/doc/Documentation/gpio/sysfs.txt 
-* https://www.kernel.org/doc/Documentation/gpio/gpio-legacy.txt 
- 
-主要是这gpio number是如何同pin number 一一对应的。 
- 
-```shell 
-256 
-root@mxj-zbcs-310:#tree /sys/class/gpio 
-. 
-|-- export 
-|-- gpio120 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpio120 
-|-- gpio228 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpio228 
-|-- gpio229 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpio229 
-|-- gpio232 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpio232 
-|-- gpio32 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpio32 
-|-- gpio33 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpio33 
-|-- gpio359 -> ../../devices/soc.0/1f02c00.pinctrl/gpio/gpio359 
-|-- gpio64 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpio64 
-|-- gpiochip0 -> ../../devices/soc.0/1c20800.pinctrl/gpio/gpiochip0 
-|-- gpiochip1024 -> ../../devices/soc.0/pinctrl.1/gpio/gpiochip1024 
-|-- gpiochip352 -> ../../devices/soc.0/1f02c00.pinctrl/gpio/gpiochip352 
-`-- unexport 
-``` 
- 
-奇怪,今天发现`sys/class/gpio` 下面的gpio没有了。只剩下`gpiochip`了。原来需要在应用export 对应io number。 
- 
-```shell 
-    fd = open("/sys/class/gpio/export", O_WRONLY); 
-    len = snprintf(buffer, sizeof(buffer), "%d", pin); 
-    if (write(fd, buffer, len) < 0) { 
-    } 
-``` 
- 
-这里的`export`和`unport`以及之后对 io number value的`read write` 操作都是在`gpiolibc` 上实现的。 
- 
-```c 
-    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); 
-    fd = open(path, O_WRONLY); 
-    if (fd < 0) { 
-    } 
- 
-    if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0) { 
- }         
-``` 
- 
-接下来需要理一理`gpiolibc` 的实现,`gpiolibc` 所有操作都是基于`gpio_desc *desc` 变量。改变量通过`gpio_desc` 结构体定义这里的数组。数组索引就对应我们这里的io number。 
-```c 
-static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; 
-``` 
-这个结构体的实现主要是是通过`gpio_chip`来操作的,例如`gpiod_set_value` 是通过`gpio_desc` 获取到`gpio_chip` 然后在通过`gpio_chip->set()` 实现IO的读写。 
- 
-```c 
-static void gpiod_set_value(struct gpio_desc *desc, int value) { 
- struct gpio_chip *chip; 
- 
- if (!desc) 
- return; 
- chip = desc->chip; 
- /* Should be using gpio_set_value_cansleep() */ 
- WARN_ON(chip->can_sleep); 
- trace_gpio_value(desc_to_gpio(desc), 0, value); 
- if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) 
- _gpio_set_open_drain_value(desc, value); 
- else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) 
- _gpio_set_open_source_value(desc, value); 
- else 
- chip->set(chip, gpio_chip_hwgpio(desc), value); 
-} 
-``` 
- 
-所以对于`gpio_chip` 的初始化就很重要了。然而我并没有找。 
- 
-```c 
-static inline u32 sunxi_data_reg(u16 pin)  { 
- u8 bank = pin / PINS_PER_BANK; 
- u32 offset = bank * BANK_MEM_SIZE; 
- offset += DATA_REGS_OFFSET; 
- offset += pin % PINS_PER_BANK / DATA_PINS_PER_REG * 0x04; 
- return round_down(offset, 4); 
-} 
- 
-#define PINS_PER_BANK    32     //其中 PINS_PER_BANK  为32 
-``` 
-对于如上计算的`bank`  `1-7`依次对应 `PB-PH`。 
-`8` 对应`PL` 
- 
-![](http://docs.leconiot.com/lib/exe/fetch.php?media=jaysnote:images:cpux_port.png) 
- 
-![](http://docs.leconiot.com/lib/exe/fetch.php?media=jaysnote:images:cpux_port_l.png) 
- 
->Page.396 3.21. Port Controller(CPUx-PORT) 
- 
-`pin % PINS_PER_BANK` 对于Port 尾号,例如pin=32,对应 `PB0` 
- 
-```c 
-#define  IO_NUMBER_CARD_READER0     228     //!< PH4 (IC-D0_L)    读卡器信号0  
-#define  IO_NUMBER_CARD_READER1     229     //!< PH5 (IC-D1_L)    读卡器信号1  
-#define  IO_NUMBER_DOOR_CTRL        33      //!< PB1 (Core_OPEN)门禁控制 
-#define  IO_NUMBER_DOOR_CHECK       64      //!< PC0 (button)按键选择(非门控制) 
-#define  IO_NUMBER_USER_KEY         32      //!< PB0 (Userkey)用户按键 
-#define  IO_NUMBER_A64_SHUTDOWN     359     //!< PL7 (Core_SHUTDOWN) 用MCU 控制 A64 软件开关机 
-#define  IO_NUMBER_BODY_RADAR       232     //!< PH8 (Body_Sensor)人体雷达     
-#define  IO_NUMBER_A64_SENSE                //!< PH4 (Core_SENSE) 未知功能 
-``` 
- 
- 
- 
-shell 脚本转换 
- 
-```shell 
-num2name(){ 
-  local num=$1 
-  local h=$[$num/32] 
-  local l=$[$num%32] 
- 
-  local H=$(echo -e `printf '\\\x%02x' $[0x41+h]`) 
-  echo P$H$l 
-} 
-name2num(){ 
-local name=$1 
-name=${name#P} 
-local H=${name:0:1} 
-local l=${name:1} 
-local h=$[`printf '%d' \'$H`-0x41] 
- 
-echo $[h*32+l] 
-} 
- 
-``` 
-</markdown> 
  
jaysnote/gpio_libc.txt · 最后更改: 2021/06/22 23:14 (外部编辑)