第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验

7.11.1.iMX Pins Tool v6安装

    先确定引脚并生成设备树节点,使用NXP i.MX Pins Tool v6之后加载配置文件时,跳出错误:

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第1张图片

    这软件搞不定,郁闷!群里一个哥们说是网速的问题,连续试了几天都不行,周日早上起来又试了下,发现可以了!可能周日早上用网络的少,网速快些!这软件和STM32CubeMX挺像。

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第2张图片

    上图中左侧为引脚选择区域,下方对应选择引脚的特性,中间区域为封装示意图,右侧为复用该引脚对应的.dts内容,将生成的代码复制到iomuxc_snvs节点中即可。

7.11.2.创建pin controller

    使用Pins Tool创建出pinctrl然后到设备树100ask_imx6ull-14x14.dts中进行添加。

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第3张图片

7.11.3.创建client device

    .dts中应该已经添加了对应pinctrl_leds的节点,搜索一下找到下图内容,现在已经知道了这是板子上的指示灯,需要屏蔽掉先。添加status = “disabled”将该节点屏蔽掉,编译设备树,覆盖板子上原来的设备树文件,重启,发现led不再闪烁,说明已屏蔽掉了。

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第4张图片

    参照屏蔽掉的led节点,重新创建一个节点:

 91     leds_my {
 93         compatible = "100ask,leddrv";  //来自leddrv.c的of_device_id ask100_leds[]
 94         pinctrl-names = "default"; //默认
 95         pinctrl-0 = <&pinctrl_leds>;
 96
 97         led0_my: led0_my { //对应要修改gpiod_get(&pdev->dev, "led0_my", 0);
 98             label = "myled";
 99             gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
100             default-state = "on";
102         };
103     };

    编译设备树,覆盖板子上原来的设备树文件,重启,查看下设备树中是否添加了leds_my节点。

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第5张图片

    Insmod leddrv.ko出现了错误:

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第6张图片

但100ask_led主设备还是注册成功了, 

测试出现错误,不存在次设备。

    找下错误,leddrv.c的94行,gpiod_get(&pdev->dev, "led0_my", 0);这里有问题,看打印信息发现主设备100ask_led注册成功了,但是次设备没有注册成功,查看下次设备ls /dev/ -l的确没有100ask_ledx。

    在设备树文件中把gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;前面加上了led-gpios,修改gpiod_get(&pdev->dev, "led", 0)还是有错误。猜测应该是这个con_id有问题,看下别人是怎么用gpiod_get的,

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第7张图片

    参考1:gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH);

    参考2:pdata->sfp_rdy = gpiod_get(dev, "rxlos", GPIOD_IN);不知道去哪里的设备树找"panel"和 "rxlos"。反向找下板子上驱动led是怎么调用的,也没找到,郁闷!

    去看看搜索出来的几个.txt文档,在board.txt中有重大发现!原文复制过来!

GPIO Mappings

=============

This document explains how GPIOs can be assigned to given devices and functions. Note that it only applies to the new descriptor-based interface. For a description of the deprecated integer-based GPIO interface please refer to gpio-legacy.txt (actually, there is no real mapping possible with the old interface; you just fetch an integer from somewhere and request the corresponding GPIO).

All platforms can enable the GPIO library, but if the platform strictly requires GPIO functionality to be present, it needs to select GPIOLIB from its Kconfig. Then, how GPIOs are mapped depends on what the platform uses to

describe its hardware layout. Currently, mappings can be defined through device tree, ACPI, and platform data.

Device Tree

-----------

GPIOs can easily be mapped to devices and functions in the device tree. The exact way to do it depends on the GPIO controller providing the GPIOs, see the device tree bindings for your controller.

GPIOs mappings are defined in the consumer device's node, in a property named-gpios, where is the function the driver will request through gpiod_get(). For example:

foo_device {

compatible = "acme,foo";

...

led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, /* red */

    <&gpio 16 GPIO_ACTIVE_HIGH>, /* green */

    <&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */

power-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;

};

Properties named -gpio are also considered valid and old bindings use it but are only supported for compatibility reasons and should not be used for newer bindings since it has been deprecated.

 

This property will make GPIOs 15, 16 and 17 available to the driver under the "led" function, and GPIO 1 as the "power" GPIO:

struct gpio_desc *red, *green, *blue, *power;

red = gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH);

green = gpiod_get_index(dev, "led", 1, GPIOD_OUT_HIGH);

blue = gpiod_get_index(dev, "led", 2, GPIOD_OUT_HIGH);

power = gpiod_get(dev, "power", GPIOD_OUT_HIGH);

gpio_get是默认获取整个xxx-gpios,但内部只定义了一个pin,gpio_get_index是可以获取xxx-goios里面的多个pins

The led GPIOs will be active-high, while the power GPIO will be active-low (i.e. gpiod_is_active_low(power) will be true).

The second parameter of the gpiod_get() functions, the con_id string, has to be the -prefix of the GPIO suffixes ("gpios" or "gpio", automatically looked up by the gpiod functions internally) used in the device tree. With above "led-gpios" example, use the prefix without the "-" as con_id parameter: "led".

Internally, the GPIO subsystem prefixes the GPIO suffix ("gpios" or "gpio") with the string passed in con_id to get the resulting string (snprintf(... "%s-%s", con_id, gpio_suffixes[]).

    清楚了GPIO Mappings,其实就是引用GPIO,先执行看下,感受一下再来分析。

myled {
	compatible = "100ask,leddrv";
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_leds>;
	led-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
}; 

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第8张图片

    执行./ledtest /dev/100ask_led0 on/off可以实现开关板子上的led。

   到此可以先理顺一下基于pinctrl和gpio子系统的文件组成:

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第9张图片

第七章 驱动程序开发-LED驱动-7.11.100ASK_IMX6ULL 上机实验_第10张图片

 

 

 

 

你可能感兴趣的:(I.MX6)