Chinaunix首页 | 论坛 | 博客
  • 博客访问: 445218
  • 博文数量: 78
  • 博客积分: 2030
  • 博客等级: 大尉
  • 技术积分: 1002
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-28 15:25
文章分类

全部博文(78)

文章存档

2012年(1)

2011年(1)

2010年(4)

2009年(12)

2008年(60)

我的朋友

分类: LINUX

2008-10-29 18:17:07

2.4中的gpio要把内核数据放在proc下面,方法比较麻烦。看2.6的驱动,里面采用ctl_table结构来做,

而且是可读写的,使用和实现起来非常方便,统一放在proc/sys下面。
static ctl_table gpio_table[] = {
  {
    .ctl_name       = 3,
    .procname       = "gpio2",
    .maxlen         = sizeof(int),
    .mode           = 0644,
    .proc_handler   = &gpio_sysctl_op,
  },
  {
    .ctl_name       = 2,
    .procname       = "gpio1",
    .maxlen         = sizeof(int),
    .mode           = 0644,
    .proc_handler   = &gpio_sysctl_op,
  },
 
  {
    .ctl_name       = 1,
    .procname       = "gpio0",
    .maxlen         = sizeof(int),
    .mode           = 0644,
    .proc_handler   = &gpio_sysctl_op,
  },
  { .ctl_name = 0 }
};

在写gpio_sysctl_op实现时遇到一些麻烦,比如说cat /proc/sys/gpio/gpio0 会不停的输出,后来看了

下别人的代码,加了一段程序就可以了
static int gpio_sysctl_op(ctl_table *table, int write, struct file *filp,
       void __user *buffer, size_t *lenp, loff_t *ppos)
 if (*ppos > 0) {
     *lenp = 0;
     return 0;
 }
在driver/cdrom/cdrom.c里面它是这样加的
  if (!*lenp || (*ppos && !write)) {
        *lenp = 0;
        return 0;
    }

此外你要使cat /proc/sys/gpio0 能正确显示,送到用户空间的必须是字符串,所以读出来的十六进制数要转换一下的。

整个函数如下,对其中的lenp和ppos还是搞得不是很清楚。
static int gpio_sysctl_op(ctl_table *table, int write, struct file *filp,
       void __user *buffer, size_t *lenp, loff_t *ppos)
{
 int i;
 unsigned int port_data = 0;
 unsigned char str_data[24] = {0};
 
 if (!*lenp || (*ppos && !write)) {
  *lenp = 0;
  return 0;
 }
 if (!write){
  /*read*/
  /*
  if (*ppos > 0) {
    *lenp = 0;
    return 0;
  }*/
  port_data = ar7100_reg_rd(AR7100_GPIO_IN); 
  
  for ( i = 0 ; i < 22 ; i++){
   int bit_i = (port_data & (1<   str_data[21-i] = bit_i ? '1':'0';
  }
  str_data[22] = '\n';
  str_data[23] = '\0';
   
  copy_to_user(buffer,&str_data,24);
  *ppos = *ppos + 24;
     *lenp = 24;
  return *lenp;   
  
  
 }
  


 return *lenp;
 
}

AR9132的gpio寄存器设计的很复杂,竟然rx和tx都能使能在gpio口上,要控制它要用到
GPIO_OE  方向设定
GPIO_IN  读数据
GPIO_OUT 写数据
GPIO_IN读数据不用设置GPIO_OE,但是要写数据到GPIO_OUT一定要先设置GPIO_OE,对应位置
1为输出。
5vt 131X的CPU的GPIO设置感觉很方便,它是分组的A,B,C每组都有
GPIO_DIR
GPIO_DATA
寄存器
设了方向后,就可以在GPIO_DATA上读数据或写数据到GPIO口上

阅读(1810) | 评论(0) | 转发(0) |
0

上一篇:mips地址的问题

下一篇:buildroot玩法

给主人留下些什么吧!~~