Chinaunix首页 | 论坛 | 博客
  • 博客访问: 195356
  • 博文数量: 40
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 25
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-31 10:34
文章分类
文章存档

2019年(2)

2017年(14)

2016年(8)

2015年(10)

2014年(6)

我的朋友

分类: 嵌入式

2017-03-03 15:29:20

    当然玩过单片机的人,或者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机制本来就是一块大的东西,需要专门来研究.

  
阅读(6095) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~