Chinaunix首页 | 论坛 | 博客
  • 博客访问: 34675
  • 博文数量: 17
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 180
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-02 12:04
文章分类
文章存档

2011年(1)

2010年(6)

2008年(10)

我的朋友
最近访客

分类: LINUX

2008-07-17 10:02:34

linux的用户空间不能直接访问io口,只能通过函数来访问io。atmel的关于gpio的头文件在/arm/arm/mach-at91/gpio.c;/include/asm/arch/gpio.h io.h.点亮led的驱动和测试函数如下。
 
#include
#include
#include
#include
#include
#include
#include
#include
#define led1 AT91_PIN_PA6
#define led2 AT91_PIN_PA6
#define led3 AT91_PIN_PA6
#define led4 AT91_PIN_PA6
#define NAME "four led test"
static int major =231;//define device major
static ssize_t myled_driver_write(struct file *file,const char __user *data,size_t len,loff_t
*ppos)
{    unsigned char buf_data;
 printk("this is write");
    if(copy_from_user((char*)&buf_data,data,len))
    return -EFAULT;
    printk("MYled test Driver -write:user_data 0x=%x\n",buf_data);
      switch(buf_data)
    {
        case    0x0:gpio_set_value(led1,0);    printk("MYled test Driver -write:user_data 0x=%x\n",buf_data);break;
        case    0x1:gpio_set_value(led2,0);break;
        case    0x2:gpio_set_value(led3,0);break;
        case    0x3:gpio_set_value(led4,0);break;
        case    0x4:gpio_set_value(led1,1);break;
        case    0x5:gpio_set_value(led2,1);break;
        case    0x6:gpio_set_value(led3,1);break;
        case    0x7:gpio_set_value(led4,1);break;
        default:break;           
    }
    return(len<8 ? len:8);
}
static ssize_t myled_driver_read(struct file *file,char __user *buf,size_t len,loff_t *ppos)
{
    unsigned int i = 0;
    i|= gpio_get_value(led1);
    i|= gpio_get_value(led2);
    printk("Read:value =0x%08X\n",i);
      if(len >8) return 0;
    return (len <4 ?len:4);
   
}
static int myled_driver_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
      unsigned int regled1,regled2;
 regled1=gpio_get_value(led1);
 printk("led1 reg is : %d",regled1);
         at91_set_gpio_output(led1,1);
 
    switch(cmd)
    {
        case    0x0:at91_set_gpio_value(led1,0); printk("Led test driver-ioctl: 1 param %u %lu\n",cmd,arg);       regled1=gpio_get_value(led1);
        printk("led1 reg is : %d",regled1);
                                            break;
        case    0x1:gpio_set_value(led2,0); printk("Led test driver-ioctl: 2 param %u %lu\n",cmd,arg);break;
        case    0x2:gpio_set_value(led3,0); printk("Led test driver-ioctl: 3 param %u %lu\n",cmd,arg);break;
        case    0x3:gpio_set_value(led4,0); printk("Led test driver-ioctl: 4 param %u %lu\n",cmd,arg);break;
        case    0x4:gpio_set_value(led1,1); printk("Led test driver-ioctl: 5 param %u %lu\n",cmd,arg);break;
        case    0x5:at91_set_gpio_value(led2,1); printk("Led test driver-ioctl: 6 param %u %lu \n",cmd,arg);break;
        case    0x6:gpio_set_value(led3,1); printk("Led test driver-ioctl: 7 param %u %lu\n",cmd,arg);break;
        case    0x7:gpio_set_value(led4,1); printk("Led test driver-ioctl: 8 param %u %lu\n",cmd,arg);break;
        default:break;   
    }
    return 1;
}
static int myled_driver_open(struct inode *inode,struct file *file)
{
    unsigned m =iminor(inode);
    if(m>63) return -EINVAL;
    printk("led test driver opened!\n");
    return nonseekable_open(inode,file);
}
static int myled_driver_release(struct inode *inode,struct file *file)
{
    printk("my test driver released!\n");
    return 0;
}
static struct file_operations myled_driver_fops =
{
    .owner =THIS_MODULE,
    .read =myled_driver_read,
    .write =myled_driver_write,
    .ioctl =myled_driver_ioctl,
    .open =myled_driver_open,
    .release =myled_driver_release,
};
static int __init myled_driver_init(void) /*妯″潡鍔犺浇鍑芥暟*/
{
       int ret;    /*鍒濆?鍖栦唬鐮?/
       gpio_set_value(led1,0);
       gpio_set_value(led2,1);
       gpio_set_value(led3,0);
       gpio_set_value(led4,1);
       printk(KERN_ALERT "led modules is install\n");
         ret=register_chrdev(major,NAME,&myled_driver_fops);
        if(ret<0)
         {
              printk("unable to register myled driver!\n");
             return ret;
         }           
        return 0;
}
static void __exit myled_driver_exit(void)/*__exit涓哄畯瀹氫箟*/
{
      int ret;
       ret=unregister_chrdev(major,NAME);
       if(ret<0) printk("unable to register character device!\n");
       else printk("my led test driver unloaded!");
       printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(myled_driver_init);
module_exit(myled_driver_exit);
MODULE_AUTHOR("lxs()");
MODULE_DESCRIPTION("this is test modules used to test at91sam9261 led");
MODULE_LICENSE("Dual BSD/GPL");  /*妯″潡璁稿彲璇佸繀闇
阅读(1592) | 评论(6) | 转发(0) |
0

上一篇:关于copy_to_user

下一篇:关于system系统调用

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

chinaunix网友2008-12-19 18:06:40

看来,我应该把这个驱动写的更完整些,谢谢大家的光临,我也会把测试函数放上来。

chinaunix网友2008-12-16 19:52:49

只看到驱动!没看到测试函数啊?

chinaunix网友2008-10-30 17:00:24

最近也一直在弄at91sam9260,有时间可以交流交流;msn:miracle@live.cn,上面的兄弟问是否可以通用,答案是基本可以,这个基本的前提就是把头文件里和at91相关的换成2410的就可以了,你对照一下2410的例程,其实和这个没有什么区别,除了头文件。

chinaunix网友2008-08-03 13:39:32

把这个函数放在哪里呢?放在文件系统里还是内核里阿?

cdarm2008-07-29 09:25:37

对不起,这个是针对at9260。2410的例子更多。