回答

收藏

[评测分享] 【米尔 MYD-YM62X 开发板入门评测】 3.LED驱动流程学习理解

#板卡评测 #板卡评测 1814 人阅读 | 0 人回复 | 2023-11-10

本帖最后由 andeyqi 于 2023-11-11 00:37 编辑

概述:
   本人对linux 的开发经验只限于应用层的层面,对linux 驱动理解也很有限,工作中也是mcu接触的多些,linux的驱动经验基本为零,正好一以此次米尔开发板的机会来以探寻(猜测)学习的态度了解下板载的gpio驱动,如果其中描述的不准确的希望大家指正。


应用层控制GPIO(LED):
   从原理图可知,板载的LED(D53,D54),公共端接到了3.3V,另一端接到了芯片端进行控制,低电平active 掂量的设计方式。



从米尔的如下资料描述我们不需要写代码,系统里已经继承了对应的驱动,只要载shell 里输入命令即可完成led的点亮关闭以及点亮方式的控制。

按照上面的文档的方式实测也是可以对板载的led 进行控制的,对于上述的控制方式有如下疑问点,我们带着如下问题点去理解代码流程。
  • /sys/class/leds/am62-sk\:d53/brightness 节点是如何创建的?

资料包的 04_Sources\myir-ti-linux-myd-am62x-linux-6.1.46\Documentation\leds\index.rst 文件中有对led驱动接口的简单描述

  1. Complex triggers while available to all LEDs have LED specific
  2. parameters and work on a per LED basis. The timer trigger is an example.
  3. The timer trigger will periodically change the LED brightness between
  4. LED_OFF and the current brightness setting. The "on" and "off" time can
  5. be specified via /sys/class/leds/<device>/delay_{on,off} in milliseconds.
  6. You can change the brightness value of a LED independently of the timer
  7. trigger. However, if you set the brightness value to LED_OFF it will
  8. also disable the timer trigger.

  9. You can change triggers in a similar manner to the way an IO scheduler
  10. is chosen (via /sys/class/leds/<device>/trigger). Trigger specific
  11. parameters can appear in /sys/class/leds/<device> once a given trigger is
  12. selected.

  13. LED registration API
  14. ====================

  15. A driver wanting to register a LED classdev for use by other drivers /
  16. userspace needs to allocate and fill a led_classdev struct and then call
  17. `[devm_]led_classdev_register`. If the non devm version is used the driver
  18. must call led_classdev_unregister from its remove function before
  19. free-ing the led_classdev struct.

  20. If the driver can detect hardware initiated brightness changes and thus
  21. wants to have a brightness_hw_changed attribute then the LED_BRIGHT_HW_CHANGED
  22. flag must be set in flags before registering. Calling
  23. led_classdev_notify_brightness_hw_changed on a classdev not registered with
  24. the LED_BRIGHT_HW_CHANGED flag is a bug and will trigger a WARN_ON.
复制代码

从如上的描述可知,led_classdev_register 接口会像系统内注册led设备,并通过via /sys/class/leds/<device>/ 路径去控制led设备

04_Sources\myir-ti-linux-myd-am62x-linux-6.1.46\drivers\leds 目录下有如下好多驱动文件,我们的板子使用的呢?
  1. total 860
  2. .
  3. ..
  4. Kconfig
  5. Makefile
  6. TODO
  7. blink
  8. flash
  9. led-class-flash.c
  10. led-class-multicolor.c
  11. led-class.c
  12. led-core.c
  13. led-triggers.c
  14. leds-88pm860x.c
  15. leds-acer-a500.c
  16. leds-adp5520.c
  17. leds-an30259a.c
  18. leds-apu.c
  19. leds-ariel.c
  20. leds-asic3.c
  21. leds-aw2013.c
  22. leds-bcm6328.c
  23. leds-bcm6358.c
  24. leds-bd2802.c
  25. leds-blinkm.c
  26. leds-clevo-mail.c
  27. leds-cobalt-qube.c
  28. leds-cobalt-raq.c
  29. leds-cpcap.c
  30. leds-cr0014114.c
  31. leds-da903x.c
  32. leds-da9052.c
  33. leds-dac124s085.c
  34. leds-el15203000.c
  35. leds-gpio-register.c
  36. leds-gpio.c
  37. leds-hp6xx.c
  38. leds-ip30.c
  39. leds-ipaq-micro.c
  40. leds-is31fl319x.c
  41. leds-is31fl32xx.c
  42. leds-lm3530.c
  43. leds-lm3532.c
  44. leds-lm3533.c
  45. leds-lm355x.c
  46. leds-lm36274.c
  47. leds-lm3642.c
  48. leds-lm3692x.c
  49. leds-lm3697.c
  50. leds-locomo.c
  51. leds-lp3944.c
  52. leds-lp3952.c
  53. leds-lp50xx.c
  54. leds-lp5521.c
  55. leds-lp5523.c
  56. leds-lp5562.c
  57. leds-lp55xx-common.c
  58. leds-lp55xx-common.h
  59. leds-lp8501.c
  60. leds-lp8788.c
  61. leds-lp8860.c
  62. leds-lt3593.c
  63. leds-max77650.c
  64. leds-max8997.c
  65. leds-mc13783.c
  66. leds-menf21bmc.c
  67. leds-mlxcpld.c
  68. leds-mlxreg.c
  69. leds-mt6323.c
  70. leds-net48xx.c
  71. leds-netxbig.c
  72. leds-nic78bx.c
  73. leds-ns2.c
  74. leds-ot200.c
  75. leds-pca9532.c
  76. leds-pca955x.c
  77. leds-pca963x.c
  78. leds-pm8058.c
  79. leds-powernv.c
  80. leds-pwm.c
  81. leds-rb532.c
  82. leds-regulator.c
  83. leds-s3c24xx.c
  84. leds-sc27xx-bltc.c
  85. leds-spi-byte.c
  86. leds-ss4200.c
  87. leds-sunfire.c
  88. leds-syscon.c
  89. leds-tca6507.c
  90. leds-ti-lmu-common.c
  91. leds-tlc591xx.c
  92. leds-tps6105x.c
  93. leds-turris-omnia.c
  94. leds-wm831x-status.c
  95. leds-wm8350.c
  96. leds-wrap.c
  97. leds.h
  98. rgb
  99. simple
  100. trigger
  101. uleds.c
复制代码

04_Sources\myir-ti-linux-myd-am62x-linux-6.1.46\drivers\leds\Makefile 文件可知,具体的那个驱动加入编译是通过(CONFIG_LEDS_xxx)配置宏来配置的
  1. # SPDX-License-Identifier: GPL-2.0

  2. # LED Core
  3. obj-$(CONFIG_NEW_LEDS)                        += led-core.o
  4. obj-$(CONFIG_LEDS_CLASS)                += led-class.o
  5. obj-$(CONFIG_LEDS_CLASS_FLASH)                += led-class-flash.o
  6. obj-$(CONFIG_LEDS_CLASS_MULTICOLOR)        += led-class-multicolor.o
  7. obj-$(CONFIG_LEDS_TRIGGERS)                += led-triggers.o

  8. # LED Platform Drivers (keep this sorted, M-| sort)
  9. obj-$(CONFIG_LEDS_88PM860X)                += leds-88pm860x.o
  10. obj-$(CONFIG_LEDS_ACER_A500)                += leds-acer-a500.o
  11. obj-$(CONFIG_LEDS_ADP5520)                += leds-adp5520.o
  12. obj-$(CONFIG_LEDS_AN30259A)                += leds-an30259a.o
  13. obj-$(CONFIG_LEDS_APU)                        += leds-apu.o
  14. obj-$(CONFIG_LEDS_ARIEL)                += leds-ariel.o
  15. obj-$(CONFIG_LEDS_ASIC3)                += leds-asic3.o
  16. obj-$(CONFIG_LEDS_AW2013)                += leds-aw2013.o
  17. obj-$(CONFIG_LEDS_BCM6328)                += leds-bcm6328.o
  18. obj-$(CONFIG_LEDS_BCM6358)                += leds-bcm6358.o
  19. obj-$(CONFIG_LEDS_BD2802)                += leds-bd2802.o
  20. obj-$(CONFIG_LEDS_BLINKM)                += leds-blinkm.o
  21. obj-$(CONFIG_LEDS_CLEVO_MAIL)                += leds-clevo-mail.o
  22. obj-$(CONFIG_LEDS_COBALT_QUBE)                += leds-cobalt-qube.o
  23. obj-$(CONFIG_LEDS_COBALT_RAQ)                += leds-cobalt-raq.o
  24. obj-$(CONFIG_LEDS_CPCAP)                += leds-cpcap.o
  25. obj-$(CONFIG_LEDS_DA903X)                += leds-da903x.o
  26. obj-$(CONFIG_LEDS_DA9052)                += leds-da9052.o
  27. obj-$(CONFIG_LEDS_GPIO)                        += leds-gpio.o
  28. obj-$(CONFIG_LEDS_GPIO_REGISTER)        += leds-gpio-register.o
  29. obj-$(CONFIG_LEDS_HP6XX)                += leds-hp6xx.o
  30. obj-$(CONFIG_LEDS_INTEL_SS4200)                += leds-ss4200.o
  31. obj-$(CONFIG_LEDS_IP30)                        += leds-ip30.o
  32. obj-$(CONFIG_LEDS_IPAQ_MICRO)                += leds-ipaq-micro.o
  33. obj-$(CONFIG_LEDS_IS31FL319X)                += leds-is31fl319x.o
  34. obj-$(CONFIG_LEDS_IS31FL32XX)                += leds-is31fl32xx.o
  35. obj-$(CONFIG_LEDS_LM3530)                += leds-lm3530.o
  36. obj-$(CONFIG_LEDS_LM3532)                += leds-lm3532.o
  37. obj-$(CONFIG_LEDS_LM3533)                += leds-lm3533.o
  38. obj-$(CONFIG_LEDS_LM355x)                += leds-lm355x.o
  39. obj-$(CONFIG_LEDS_LM36274)                += leds-lm36274.o
  40. obj-$(CONFIG_LEDS_LM3642)                += leds-lm3642.o
  41. obj-$(CONFIG_LEDS_LM3692X)                += leds-lm3692x.o
  42. obj-$(CONFIG_LEDS_LM3697)                += leds-lm3697.o
  43. obj-$(CONFIG_LEDS_LOCOMO)                += leds-locomo.o
  44. obj-$(CONFIG_LEDS_LP3944)                += leds-lp3944.o
  45. obj-$(CONFIG_LEDS_LP3952)                += leds-lp3952.o
  46. obj-$(CONFIG_LEDS_LP50XX)                += leds-lp50xx.o
  47. obj-$(CONFIG_LEDS_LP5521)                += leds-lp5521.o
  48. obj-$(CONFIG_LEDS_LP5523)                += leds-lp5523.o
  49. obj-$(CONFIG_LEDS_LP5562)                += leds-lp5562.o
  50. obj-$(CONFIG_LEDS_LP55XX_COMMON)        += leds-lp55xx-common.o
  51. obj-$(CONFIG_LEDS_LP8501)                += leds-lp8501.o
  52. obj-$(CONFIG_LEDS_LP8788)                += leds-lp8788.o
  53. obj-$(CONFIG_LEDS_LP8860)                += leds-lp8860.o
  54. obj-$(CONFIG_LEDS_LT3593)                += leds-lt3593.o
  55. obj-$(CONFIG_LEDS_MAX77650)                += leds-max77650.o
  56. obj-$(CONFIG_LEDS_MAX8997)                += leds-max8997.o
  57. obj-$(CONFIG_LEDS_MC13783)                += leds-mc13783.o
  58. obj-$(CONFIG_LEDS_MENF21BMC)                += leds-menf21bmc.o
  59. obj-$(CONFIG_LEDS_MIKROTIK_RB532)        += leds-rb532.o
  60. obj-$(CONFIG_LEDS_MLXCPLD)                += leds-mlxcpld.o
  61. obj-$(CONFIG_LEDS_MLXREG)                += leds-mlxreg.o
  62. obj-$(CONFIG_LEDS_MT6323)                += leds-mt6323.o
  63. obj-$(CONFIG_LEDS_NET48XX)                += leds-net48xx.o
  64. obj-$(CONFIG_LEDS_NETXBIG)                += leds-netxbig.o
  65. obj-$(CONFIG_LEDS_NIC78BX)                += leds-nic78bx.o
  66. obj-$(CONFIG_LEDS_NS2)                        += leds-ns2.o
  67. obj-$(CONFIG_LEDS_OT200)                += leds-ot200.o
  68. obj-$(CONFIG_LEDS_PCA9532)                += leds-pca9532.o
  69. obj-$(CONFIG_LEDS_PCA955X)                += leds-pca955x.o
  70. obj-$(CONFIG_LEDS_PCA963X)                += leds-pca963x.o
  71. obj-$(CONFIG_LEDS_PM8058)                += leds-pm8058.o
  72. obj-$(CONFIG_LEDS_POWERNV)                += leds-powernv.o
  73. obj-$(CONFIG_LEDS_PWM)                        += leds-pwm.o
  74. obj-$(CONFIG_LEDS_REGULATOR)                += leds-regulator.o
  75. obj-$(CONFIG_LEDS_S3C24XX)                += leds-s3c24xx.o
  76. obj-$(CONFIG_LEDS_SC27XX_BLTC)                += leds-sc27xx-bltc.o
  77. obj-$(CONFIG_LEDS_SUNFIRE)                += leds-sunfire.o
  78. obj-$(CONFIG_LEDS_SYSCON)                += leds-syscon.o
  79. obj-$(CONFIG_LEDS_TCA6507)                += leds-tca6507.o
  80. obj-$(CONFIG_LEDS_TI_LMU_COMMON)        += leds-ti-lmu-common.o
  81. obj-$(CONFIG_LEDS_TLC591XX)                += leds-tlc591xx.o
  82. obj-$(CONFIG_LEDS_TPS6105X)                += leds-tps6105x.o
  83. obj-$(CONFIG_LEDS_TURRIS_OMNIA)                += leds-turris-omnia.o
  84. obj-$(CONFIG_LEDS_WM831X_STATUS)        += leds-wm831x-status.o
  85. obj-$(CONFIG_LEDS_WM8350)                += leds-wm8350.o
  86. obj-$(CONFIG_LEDS_WRAP)                        += leds-wrap.o

  87. # LED SPI Drivers
  88. obj-$(CONFIG_LEDS_CR0014114)                += leds-cr0014114.o
  89. obj-$(CONFIG_LEDS_DAC124S085)                += leds-dac124s085.o
  90. obj-$(CONFIG_LEDS_EL15203000)                += leds-el15203000.o
  91. obj-$(CONFIG_LEDS_SPI_BYTE)                += leds-spi-byte.o

  92. # LED Userspace Drivers
  93. obj-$(CONFIG_LEDS_USER)                        += uleds.o

  94. # Flash and Torch LED Drivers
  95. obj-$(CONFIG_LEDS_CLASS_FLASH)                += flash/

  96. # RGB LED Drivers
  97. obj-$(CONFIG_LEDS_CLASS_MULTICOLOR)        += rgb/

  98. # LED Triggers
  99. obj-$(CONFIG_LEDS_TRIGGERS)                += trigger/

  100. # LED Blink
  101. obj-y                                        += blink/

  102. # Simple LED drivers
  103. obj-y                                        += simple/
复制代码
04_Sources\myir-ti-linux-myd-am62x-linux-6.1.46\arch\arm64\configs\defconfig 文件中可知如下的LED的驱动会参与编译



我们接口时gpio 控制的led,根据上述信息我们猜测我们使用的驱动文件为leds-gpio.c 文件,既然有了猜测我们如何去验证我们的猜测呢? leds-gpio.c 驱动为Platform Driver的实现 ,驱动匹配后会调用gpio_led_probe 接口该接口通过如下调用关系会调到我们上面提到的[devm_]led_classdev_register 接口,gpio_led_probe->create_gpio_led->devm_led_classdev_register,按照我们的猜测系统在启动过程中会调用gpio_led_probe 接口,我么载接口中添加log 来验证我们的猜测,因为这部分代码是随内核一起编译的我们需要更新代码重新烧写内核,然后个烧写内核,我们按照文档的描述修改代码试验下,顺便掌握更新kenrnel的方法.
我们修改内核代码,在gpio_led_probe 函数入口添加如下打印信息。

按照上面的方法编译内核,更新内核镜像后,在串口的打印日志中发现了我们添加的log 信息,从而进一步证明我们的猜测。



确定和驱动的入口,那节点的名称是根据什么来的呢,之前有了解说是根据dts 配置的,我们在源码\myir-ti-linux\arch\arm64\boot\dts\myir\目录下找到对应的myd-y62x-common.dtsi 文件,关于led 的描述信息如下:
  1. leds {
  2.                 compatible = "gpio-leds";

  3.                 led-user {
  4.                         label = "am62-sk:d54";
  5.                         gpios = <&at9555 4 GPIO_ACTIVE_LOW>;
  6.                         max-brightness = <255>;
  7.                         linux,default-trigger = "heartbeat";
  8.                         function = LED_FUNCTION_HEARTBEAT;
  9.                         default-state = "off";
  10.                 };

  11.                 led-sys {
  12.                         label = "am62-sk:d53";
  13.                         pinctrl-names = "default";
  14.                         pinctrl-1 = <&mcu_run_led_pins_default>;
  15.                         gpios = <&mcu_gpio0 16 GPIO_ACTIVE_LOW>;
  16.                         linux,default-trigger = "heartbeat";
  17.                         function = LED_FUNCTION_HEARTBEAT;
  18.                         default-state = "on";
  19.                 };
  20.         };
复制代码

此处定义了gpio active 的电平及名称等信息,我们修名称信息重新编译DTS 更新下,来验证下我们的猜测,节点名称修改为d53,d54,更新下dtb后读取下节点信息。

修改后会编译dtbs,会更新如下dtb
  1. rlk@rlk:~/ym625x/myd-ym62x-bsp/myir-ti-linux$ make dtbs
  2.   DTC     arch/arm64/boot/dts/myir/myd-y62x-6254.dtb
  3.   DTC     arch/arm64/boot/dts/myir/myd-y62x-6252.dtb
  4.   DTC     arch/arm64/boot/dts/myir/myd-y62x-6231.dtb
  5. rlk@rlk:~/ym625x/myd-ym62x-bsp/myir-ti-linux$
复制代码
我们更新下6252的dtb文件来验证节点名称是否发生变化,更新dtb 文件后发现 /sys/class/leds/ 目录下节点名称已经更新成D53 D54了跟我们预期的也是一致的。
  1. root@myd-am62x:~#  echo 0 > /sys/class/leds/d53/brightness
  2. root@myd-am62x:~#  echo 1 > /sys/class/leds/d53/brightness
  3. root@myd-am62x:~#
  4. root@myd-am62x:~#
  5. root@myd-am62x:~#  echo "timer" > /sys/class/leds/d53/trigger
复制代码

输入如上命令也可以正常控制led的熄灭点亮及闪烁的效果,跟之前的驱动效果也是一致的。


分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条