目的: 在 linux 文件系统上使用 sysfs 来控制 ,gpio的高低的变化。
逻辑;我只在 内核中是能 gpio 的pinctrl ,并不设置 gpio ,看看能不能使用 sysfs
pinctrl 的设备树的配置。 关键是 pinctrl 的配置。
284 //topeet wang added
285 alphaled {
286 #address-cells = <1>;
287 #size-cells = <1>;
288 compatible = "atkalpha-led";
289 status = "okay";
290 pinctrl-names = "default";
291 pinctrl-0=<&hym8563_int>;
292 };
字符设备驱动的编写:
驱动,没有作用。
1 #include <linux/types.h>2 #include <linux/kernel.h>3 #include <linux/delay.h>4 #include <linux/ide.h>5 #include <linux/init.h>6 #include <linux/module.h>7 #include <linux/errno.h>8 #include <linux/gpio.h>9 #include <linux/cdev.h>10 #include <linux/device.h>11 #include <linux/of.h>12 #include <linux/of_address.h>13 #include <asm/mach/map.h>14 #include <asm/uaccess.h>15 #include <asm/io.h>16171819202122 #define DTSLED_CNT 1 /* 设备号个数 */23 #define DTSLED_NAME "dtsled" /* 名字 */24 #define LEDOFF 0 /* 关灯 */25 #define LEDON 1 /* 开灯 */2627 /* 映射后的寄存器虚拟地址指针 */28 static void __iomem *IMX6U_CCM_CCGR1;29 static void __iomem *SW_MUX_GPIO1_IO03;30 static void __iomem *SW_PAD_GPIO1_IO03;31 static void __iomem *GPIO1_DR;32 static void __iomem *GPIO1_GDIR;3334 /* dtsled设备结构体 */35 struct dtsled_dev{36 dev_t devid; /* 设备号 */37 struct cdev cdev; /* cdev */38 struct class *class; /* 类 */39 struct device *device; /* 设备 */40 int major; /* 主设备号 */41 int minor; /* 次设备号 */42 struct device_node *nd; /* 设备节点 */43 };4445 struct dtsled_dev dtsled; /* led设备 */4650 static int __init led_init(void)51 {5253 /* 获取设备树中的属性数据 */54 /* 1、获取设备节点:alphaled */55 dtsled.nd = of_find_node_by_path("/alphaled");56 if(dtsled.nd == NULL) {57 printk("alphaled node nost find!\r\n");58 return -EINVAL;59 } else {60 printk("alphaled node find!\r\n");61 }6263 /* 2、获取compatible属性内容 */64 proper = of_find_property(dtsled.nd, "compatible", NULL);65 if(proper == NULL) {66 printk("compatible property find failed\r\n");67 } else {68 printk("compatible = %s\r\n", (char*)proper->value);69 }7071 /* 3、获取status属性内容 */72 ret = of_property_read_string(dtsled.nd, "status", &str);73 if(ret < 0){74 printk("status read failed!\r\n");75 } else {76 printk("status = %s\r\n",str);77 }78798081 /* 注册字符设备驱动 */82 /* 1、创建设备号 */83 if (dtsled.major) { /* 定义了设备号 */84 dtsled.devid = MKDEV(dtsled.major, 0);85 register_chrdev_region(dtsled.devid, DTSLED_CNT, DTSLED_NAME);86 } else { /* 没有定义设备号 */87 alloc_chrdev_region(&dtsled.devid, 0, DTSLED_CNT, DTSLED_NAME); /* 申请设备号 */88 dtsled.major = MAJOR(dtsled.devid); /* 获取分配号的主设备号 */89 dtsled.minor = MINOR(dtsled.devid); /* 获取分配号的次设备号 */90 }91 printk("dtsled major=%d,minor=%d\r\n",dtsled.major, dtsled.minor);9293 /* 2、初始化cdev */94 dtsled.cdev.owner = THIS_MODULE;95 cdev_init(&dtsled.cdev, &dtsled_fops);9697 /* 3、添加一个cdev */98 cdev_add(&dtsled.cdev, dtsled.devid, DTSLED_CNT);100 /* 4、创建类 */
101 dtsled.class = class_create(THIS_MODULE, DTSLED_NAME);
102 if (IS_ERR(dtsled.class)) {
103 return PTR_ERR(dtsled.class);
104 }
105
106 /* 5、创建设备 */
107 dtsled.device = device_create(dtsled.class, NULL, dtsled.devid, NULL, DTSLED_NAME);
108 if (IS_ERR(dtsled.device)) {
109 return PTR_ERR(dtsled.device);
110 }
111
112
113
114
115
116 printk("wang test driver init\n");
117 return 0;
118 }
119
120
121
122
123 static void __exit led_exit(void)
124 {
125 }
126
127
128
129 module_init(led_init);
130 module_exit(led_exit);
131 MODULE_LICENSE("GPL");
132 MODULE_AUTHOR("zuozhongkai");
修改 makefile
编译+烧写测试。
系统之后, 通过sysfs文件系统,验证了我的猜想。
是可以控制 gpio的高低电平的。
总结:
1 我写的驱动 没什么用。只是一个打印。
2 主要是 驱动 匹配上之后,pinctrl 子系统,会配置 ,设备树中的 pinctrl-0=xxx 的配置。
这个是比较重要的。
3 也就是说,我要想在 sysfs 文件系统中,来控制, gpio ,是需要提前配置好pinctlr 的,至于 gpio 配置不配置,是不重要的。
但是如果真是这样才能 配置pinctrl 的话,那也太麻烦了。
sysfs 的测试。
首先是 瑞芯微的 gpio 的计算方式。
总结瑞芯微 gpio 的具体号码的计算方法。
先来看 gpio组, 一共4组,GPIO0,GPIO1,GPIO2,GPIO3,每组32个脚。 在一个 gpio组内又有 4个组 A,B,C,D,每个小组 8个脚,从0到7 。
比如 gpio0 的 B0 怎么计算呢, 那就是 8+1=9 第九个脚,但是 表示为 GPIO8 ,为什么呢? 因为是从零开始的。 GPIOA--> 0,1,2,3,4,5,6,7, GPIOB --->0,1,2,3,4,5,6,7, 所以表示为GPIOB_0,实际为第九脚。
这样在去看他的公式:
pin=bank*32 + number,
number=group*n + x.
bank 是从0 开始的,代表的是 GPIO0,GPIO1,GPIO2 , GPIO3 ,
group 也是从0 开始的,代表的是A,B,C,D 。
如果上来就看公式,一定是懵逼的。他公式的产生过程,也是先理解了逻辑,然后在套一个形式化的公式。
然后是我需要测试的gpio 的计算。
这个脚实际上是 第9脚, 但是 表示为 gpio8
然后是 一般来说 在 sys 文件系统下, 测试 gpio 的常用的命令。
cat /sys/kernel/debug/gpio ,查看的是所有配置的gpio 的设置。
echo 13 > /sys/class/gpio/export 导出某个gpio
echo out > /sys/class/gpio/gpio13/direction 配置输入还是输出
echo 1 > /sys/class/gpio/gpio13/value 配置输出高低电平。
总结:
1 我使用 sys fs 的前提应该是 首先要在内核中 配置好 pinctrl