Linux pinctrl与gpio子系统详解
pinctrl子系统概述pinctrl子系统是Linux内核中用于管理引脚复用和配置的框架。它允许开发者通过设备树或代码动态配置芯片引脚的功能如GPIO、I2C、SPI等。pinctrl子系统通过抽象硬件差异提供统一的API接口简化了驱动开发。pinctrl的核心数据结构包括pinctrl_dev和pinctrl_desc。pinctrl_desc描述引脚控制器的能力和操作集pinctrl_dev代表一个具体的引脚控制器实例。开发者需要实现pinctrl_ops和pinmux_ops中定义的回调函数。设备树中pinctrl的配置通常如下pinctrl: pinctrl1000000 { compatible vendor,pinctrl; reg 0x1000000 0x1000; uart0_default: uart0_default { mux { function uart0; groups uart0_tx, uart0_rx; }; config { bias-disable; drive-strength 8; }; }; };gpio子系统架构gpio子系统提供通用的GPIO操作接口包括方向设置、读写和中断处理。其核心是gpio_chip结构体描述GPIO控制器的属性和操作集。gpiolib作为中间层向上提供统一的用户接口向下抽象硬件差异。GPIO控制器在设备树中的典型定义gpio0: gpio2000000 { compatible vendor,gpio; reg 0x2000000 0x1000; ngpios 32; gpio-controller; #gpio-cells 2; interrupt-controller; #interrupt-cells 2; };pinctrl与gpio协同工作当GPIO功能需要引脚复用时pinctrl子系统先配置引脚为GPIO模式再由gpio子系统接管控制。例如将引脚P1.2设置为GPIO输出pinctrl { gpio_out: gpio_out { config { pins P1.2; function gpio; output-high; }; }; };驱动代码中通过以下方式申请和使用GPIOstruct gpio_desc *desc; desc gpiod_get(dev, led, GPIOD_OUT_HIGH); gpiod_set_value(desc, 0);驱动实现示例以下代码展示一个同时使用pinctrl和gpio子系统的LED驱动#include linux/module.h #include linux/gpio/consumer.h #include linux/pinctrl/consumer.h struct pinctrl *pinctrl; struct pinctrl_state *pins_default; struct gpio_desc *led_gpio; static int led_probe(struct platform_device *pdev) { pinctrl devm_pinctrl_get(pdev-dev); pins_default pinctrl_lookup_state(pinctrl, default); pinctrl_select_state(pinctrl, pins_default); led_gpio devm_gpiod_get(pdev-dev, led, GPIOD_OUT_LOW); gpiod_direction_output(led_gpio, 1); return 0; } static struct platform_driver led_driver { .driver { .name led-driver, .of_match_table of_match_ptr(led_of_match), }, .probe led_probe, }; module_platform_driver(led_driver);对应的设备树节点led { compatible vendor,led; pinctrl-names default; pinctrl-0 led_pins; gpios gpio0 15 GPIO_ACTIVE_HIGH; }; led_pins: led_pins { config { pins P2.7; function gpio; bias-pull-up; }; };中断处理实现gpio子系统支持中断功能以下示例展示如何配置GPIO中断static irqreturn_t button_isr(int irq, void *dev_id) { struct gpio_desc *desc dev_id; int val gpiod_get_value(desc); // 处理中断逻辑 return IRQ_HANDLED; } static int button_probe(struct platform_device *pdev) { struct gpio_desc *btn; int irq, ret; btn devm_gpiod_get(pdev-dev, button, GPIOD_IN); irq gpiod_to_irq(btn); ret request_irq(irq, button_isr, IRQF_TRIGGER_FALLING, button, btn); return ret; }调试与验证调试pinctrl和gpio子系统时可以通过以下sysfs节点获取信息/sys/kernel/debug/pinctrl/ /sys/class/gpio/常用的调试命令包括cat /proc/interrupts dmesg | grep pinctrl gpiodetect gpioinfo性能优化建议在高速GPIO应用中建议采取以下优化措施使用gpiolib提供的批量操作API如gpiod_set_array()对于频繁切换的GPIO考虑直接操作寄存器使用中断线程化减少延迟启用GPIO缓存功能避免重复配置通过合理使用pinctrl和gpio子系统可以构建稳定高效的嵌入式驱动。这两个子系统已在内核中得到充分验证适用于大多数嵌入式场景。 不畏惧挫折勇敢面对生活中的每一次考验每一次磨砺都在为我们的人生增添厚重的底色。每个清晨都是新的开始愿我们都能怀揣希望迎接每一天的挑战努力去创造属于自己的未来。有梦就去追无所畏惧让心灵在努力的拼搏中飞翔迎接生命中的每一次闪光与机会。坚持梦想坚定想法是生活的重要组成唯有在探索中不断前行才能收获生命中的精彩。每一次的微笑都是生命的馈赠愿我们都能在这优美的旋律中感受生活的真谛与温暖。https://github.com/ticbrewhete71/buw_4mhp/issues/48https://github.com/hellcourt42/29f_txuo/issues/46https://github.com/tadrits611/z3u_bxsp/issues/46https://github.com/willss46/k63_9o51/issues/47https://github.com/slakrishbirk86/uk5_aa9y/issues/47
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2439365.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!