当然玩过单片机的人,或者arm开发板的人,最容易入手的就是gpio了吧,虽然看似是一个小事情,但是这里还是要说下,gpio的应用最多就是来操作led灯了. 当然它还可以处理中断,我们再看88F6500 ARM sOC的时候,这里看它的cpu模块里引脚,会发现全部引脚都是MPP引脚,通过cpu相关寄存器我们可以配置单个引脚或者一组引脚来完成N多功能,包括各种总线.
GPIO故名思议输入输出,也就是高低电平.这里我不参考2410或者其他就拿我工作的感想来简单说一说吧.
或者有些soc里把GPIO单独列了出来,通过专有的寄存器来控制各个引脚.当然不论哪种方式我们都是通过控制相关寄存器来实现的.
首先要找到怎么去操作gpio控制寄存器,看看cpu相关寄存器的映射地址在哪里,这里可以从cpu相关的datasheet里找到,还有就是通过相关soc厂商提供的sdk代码里获取.
下面我就对应相关寄存器来,说下如何操作gpio来控制led灯.
一般我们开始会把所有的gpio(和led相连的)把它首先设置为输出,即可以点亮等,并把data out设置为0.把所有灯熄灭.
1.set GPIO Data Out Enable Control Register
2.set led on /off /blink
<1> set GPIO Data Out Register (for led on/off)
<2>set GPIO Blink Enable Register (for led blink)
这里我们可以写好操作gpio驱动层的函数接口.供内核里相关模块来调用. 如果想直接在用户空间来控制,也是一件十分容易的事情,那么我们可以通过/proc来实现,这里就不具体说实现过程.
也许我说了这么久和主题没有多大关系啊?O(∩_∩)O,这里先给上盘小菜,让我们从全局对gpio有个认识.我个人认为gpio中断是一个很棒的事情,至少感觉很cool.现如今我们一般不会从零来开发(如果有时间和精力是提高技术的不错的手段),系统会首先初始化各个irq.我们可以找到相关的代码来参考.我在做gpio中断的时候,感觉最难的点就是怎么找到相应gpio对于的中断号.这里其实我没有太深入的研究哈,在sdk里一般已经会把相关gpio作为中断号的哪部分中断号给分配好,至少会给出一个base+idx. gpio也有interrupt regs,当然有时候事情并不是那么简单,或许我们还要用到cpu 相关的interrupt regs.这个就需要我们看cpu datasheet啦.万般皆调试!
这里简单说一下:
GPIO interrupt Level Mask Reg设置gpio int 的电平触发.
GPIO interrupt Mask Reg 设置gpio int边沿触发.
GPIO interrupt Cause Reg 引发int,默认为0,触发会变成1.
当然还有cpu int相关部分,自己参考datasheet. 下面说说如何来实现.
1.初始化gpio int regs
2.调用request_irq()来注册中断例程.
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags, const char * devname, void *dev_id)
注册成功后,我们可以通过cat /proc/interrupts 来查看.
事情到这里还没有完工,因为虽然我们可以用中断例程来实现我们想要做的工作,可是也许我们想要把这个触发事情通知给用户层.那么这里我们需要借助netlink机制.
1.在用户空间创建一个socket (AF_NETLINK, SOCK_RAW, NETLINK_CTRL);
2.守护线程 recvmsg()来接触来自底层的消息
3.底层来发送消息.
netlink机制本来就是一块大的东西,需要专门来研究.
阅读(6170) | 评论(0) | 转发(0) |