注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小白的博客

嵌入式爱好者

 
 
 

日志

 
 

LED驱动程序——led单独控制  

2012-09-09 04:04:16|  分类: 韦东山视频第二轮 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
驱动程序:

#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/io.h>

volatile unsigned long *gpfcon;
volatile unsigned long *gpfdat;

static struct class *led_class;

int major;
int minor=0;

int led_open(struct inode *inode, struct file *file)
{
     //获得次设备号
     minor=MINOR(inode->i_rdev); 

    //配置gpio引脚可以用下面的函数:s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
    *gpfcon &= ~((3<<4*2)|(3<<5*2)|(3<<6*2));
    *gpfcon |= (1<<4*2) | (1<<5*2) | (1<<6*2);
    
    return 0;
}
ssize_t led_write(struct file *file, const char __user *buf, size_t size, loff_t *off)
{
    int val;
    
    copy_from_user(&val, buf, size);
    switch(minor)
    {
        case 0:
        {
            if(val==1)
            {
                //设置gpio引脚可以用下面的函数:s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
                *gpfdat &= ~((1<<4)|(1<<5)|(1<<6));
            }
            else
            {
                *gpfdat |= (1<<4)|(1<<5)|(1<<6);
            }
            break;
        }
        case 1:
        {
            if(val==1)
            {
                *gpfdat &= ~(1<<4);
            }
            else
            {
                *gpfdat |= (1<<4);
            }
            break;
        }
        case 2:
        {
            if(val==1)
            {
                *gpfdat &= ~(1<<5);
            }
            else
            {
                *gpfdat |= (1<<5);
            }
            break;
        }
        case 3:
        {
            if(val==1)
            {
                *gpfdat &= ~(1<<6);
            }
            else
            {
                *gpfdat |= (1<<6);
            }
            break;
        }

    }

    return 0;
}

static struct file_operations led_operation = {
    .owner=THIS_MODULE,
    .open=led_open,
    .write=led_write,   
};

int led_init(void)
{
    major=register_chrdev(0,"leds",&led_operation);

    led_class = class_create(THIS_MODULE, "leds_class");
    device_create(led_class, NULL, MKDEV(major, minor), NULL,"leds");
    for(minor=1;minor<=3;minor++)
        {
            device_create(led_class, NULL, MKDEV(major, minor), NULL,"led%d",minor);
        }

    gpfcon=(volatile unsigned long *)ioremap(0x56000050 , 8);
    gpfdat=gpfcon+1;
    
    return 0;
}

void led_exit(void)
{
    int i;
    unregister_chrdev(major,"led");
    for(i=0;i<=3;i++)
        {
            device_destroy(led_class,MKDEV(major, i));
        }
    
    class_destroy(led_class);
    iounmap(gpfcon);
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

用户程序:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc,char **argv)
{
    int fd;
    int val=1;
    if(argc!=3)
        {
            printf("Usage:%s </dev/leds|/dev/led1|/dev/led2|/dev/led3> <on|off>\n",argv[0]);
            return 0;
        }
    fd=open(argv[1],O_RDWR);
    if(fd<0)
        {
            printf("can't open\n");
            return 0;
        }
    if(strcmp(argv[2],"on")==0)
        {
            val=1;
        }
    else if(strcmp(argv[2],"off")==0)
        {
            val=0;
        }
        else
            {
                printf("Usage:%s </dev/leds|/dev/led1|/dev/led2|/dev/led3> <on|off>\n",argv[0]);
                return 0;
            }
    write(fd , &val , 4);
    return 0;
}

思路:我们在类下创建了4个设备:leds、led1、led2、led3。这4个设备主设备号相同,但是次设备号不相同,在内核里面我们可以根据次设备号来判断操作的是哪一个设备!

上面我们提到对于IO引脚的配置和设置可以用内核提供的函数来实现,用内核提供的函数实现可以使程序变得更加简单易懂,下一节我们将提供优化了的程序!
  评论这张
 
阅读(588)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017