[X]关闭

使用函数配置GPIO口总结

文档创建者:ぉ沙皮狗的忧伤
浏览次数:8971
最后更新:2023-06-09
本帖最后由 ぉ沙皮狗的忧伤 于 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口功能,配置模式,找了许久都没找到对应的函数,算了操作寄存器去

第三步
将这个代码加入到第二步之前






总结:
  辛亏有大神带,



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

发表评论已发布 4

uisrc

发表于 2019-11-7 13:05:13 | 显示全部楼层

这么认真,我考虑送你一个ZU开发板,继续加油!
越努力越幸运!加油!

ぉ沙皮狗的忧伤

发表于 2019-11-7 13:56:46 | 显示全部楼层

msxbo 发表于 2019-11-7 13:05
这么认真,我考虑送你一个ZU开发板,继续加油!

感谢感谢,微信私聊

曾光瓦亮大脑门

发表于 2023-6-9 15:56:18 | 显示全部楼层

牛牛牛,楼主,我有个疑问,调用gpio=of_get_gpio(child_node, 0);获取的gpio不就是MIO_PIN_7的值吗???我在这一步获取到的是负值,错误的值,请问您这边又遇到过吗??
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则