本帖最后由 ぉ沙皮狗的忧伤 于 2019-11-12 11:34 编辑
之前使用寄存器配置GPIO口功能后,准备学习外部中断,想通过调用函数实现GPIO配置
第一步
简单的申请主设备,创建设备,创建类。。。。
补充:
在挂载ko文件后查看自己的设备号及设备名字cat /sys/class/****/****/uevent
第二步
申请GPIO口
这里unsigned gpio参数该怎么填写,之前我在学习三星4412时是有一个专门的宏去设置,在内核源码里面找了一圈,发现没有。。。。。
怎么办
还是去看看内核是怎么实现它的吧
在内核源码里面找到了这个
ret = gpio_request_one(gpio, GPIOF_IN, "monitor_key");
首先跟进这个函数中发现它底层也是使用的gpio_request
第一个参数unsigned gpio是通过of_get_gpio从child_node结构体里面获取的,
最后moni_key->dev = pdev->dev;我们得出结论,它是从设备树里面获取node节点,从节点的硬件信息中获取gpio的数值
ok,我们来到设备树中,看一下代码
看到gpios = <&gpio0 0x07 0x0>;
那我们猜想gpio是不是就等于0x7了,搞一下不就知道了
果然。。。。。失败了,连申请gpio_request都失败了,我们换种思路,去看看他是怎么获取GPIO的
gpio = of_get_gpio(child_node, 0);
继续往下走
在往下走
继续往下走
好了,到了这里,我们发现gpio的值,就是某个值+(某个值 - 某个值)
return desc->gdev->base + (desc - &desc->gdev->descs[0]);
好好好,来来来
通过观察,我们发现它是来自某个结构体中,于是我们就想那它是在哪里初始化的了?????
既然是初始化GPIO肯定要去zynq_gpio.c官方库里面去看
在zynq_gpio结构体中发现struct gpio_chip chip;正是我们需要的,ok,我们看它在哪里初始化的
static int zynq_gpio_probe(struct platform_device *pdev)
我们先进这里面看一看
ret = gpiochip_add_data(chip, gpio);
①gdev->ngpio = chip->ngpio;
gdev->data = data;
②base = gpiochip_find_base(chip->ngpio);
int base = ARCH_NR_GPIOS - ngpio;=====》base = 1024 - 118(MIO = 54,EMIO = 64 )= 906
gpio_request(unsigned int gpio, const char * label)中
unsigned int gpio = return desc->gdev->base + (desc - &desc->gdev->descs[0]);======》gpio = 906 + MIO值
完成了第一步,我真是太难了,网上完全没有资料,ZYNQ全是裸机代码
第二步
应该差不多了,搞一下,编译挂载KO文件。。。。。灯还是不亮
辛亏我跑了寄存器,把里面代码扣过来,发现竟然要设置GPIO口功能,配置模式,找了许久都没找到对应的函数,算了操作寄存器去
第三步
将这个代码加入到第二步之前
总结:
辛亏有大神带,
|