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

小白的博客

嵌入式爱好者

 
 
 

日志

 
 

LED驱动程序——led同时亮灭  

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

  下载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 led_open(struct inode *inode, struct file *file)
{
    *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;
    //buf所指向的是用户空间传递的值,也就是write函数的第二个参数
    //使用copy_from_user从用户空间拷贝数据到内核空间
    //使用copy_to_user从内核空间拷贝数据到用户空间
    copy_from_user(&val, buf, size);
    if(val==1)
        {
            *gpfdat &= ~((1<<4)|(1<<5)|(1<<6));
        }
    else
        {
            *gpfdat |= (1<<4)|(1<<5)|(1<<6);
        }
    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,"led",&led_operation);

    led_class = class_create(THIS_MODULE, "led_class");
    device_create(led_class, NULL, MKDEV(major, 0), NULL,"led_device");

    //在内核空间使用的是虚拟地址,所以要先将物理地址映射为虚拟地址
    //volatile保证每次*gpfcon时都是直接从0x56000050这个地址取值,而不是采用之前保存的值
    gpfcon=(volatile unsigned long *)ioremap(0x56000050 , 8);
    gpfdat=gpfcon+1;
    
    return 0;
}

void led_exit(void)
{
    unregister_chrdev(major,"led");
    device_destroy(led_class,MKDEV(major, 0));
    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!=2)
        {
            printf("Usage:%s on|off\n",argv[0]);
            return 0;
        }
    fd=open("/dev/led_device",O_RDWR);
    if(fd<0)
        {
            printf("can't open\n");
            return 0;
        }
    if(strcmp(argv[1],"on")==0)
        {
            val=1;
        }
    else if(strcmp(argv[1],"off")==0)
        {
            val=0;
        }
        else
            {
                printf("Usage:%s on|off\n",argv[0]);
                return 0;
            }
    write(fd , &val , 4);
    return 0;
}

  评论这张
 
阅读(551)| 评论(0)
推荐 转载

历史上的今天

评论

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

页脚

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