(11)2.6之後的字符驅動led

#include         // module_init  module_exit
#include <linux/init.h>            // __init   __exit
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank.h>        // arch/arm/mach-s5pv210/include/mach/gpio-bank.h

#include <linux/string.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/cdev.h>

#define MYMAJOR 200
#define MYNAME "chardev"
#define MYCNT 1
#define GPJ0CON        S5PV210_GPJ0CON //在regs-gpio.h和gpio-bank.h靜態映射好了s5pv210板上的led地址
#define GPJ0DAT        S5PV210_GPJ0DAT

#define rGPJ0CON    *((volatile unsigned int *)GPJ0CON)
#define rGPJ0DAT    *((volatile unsigned int *)GPJ0DAT)
#define GPJ0CON_PA    0xe0200240
#define GPJ0DAT_PA     0xe0200244
int mymajor ;
static dev_t mydev;
static struct cdev test_cdev;
char kbuf[100];
static int test_chardev_open(struct inode *inode,struct file *file)
{
printk(KERN_INFO "new test chardev_open\n");
return 0;
}
static int test_chardev_release(struct inode *inode,struct file *file){
printk(KERN_INFO "new test chardev_release wich led off when closing led \n");

rGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));
return 0;
}
static ssize_t test_chardev_read(struct file *file,char __user *buf,size_t size, loff_t *ppos)
{
printk(KERN_INFO "new test read\n");
return 0;

}
static ssize_t test_chardev_write(struct file *file,
const char __user *ubuf,size_t count,loff_t * ppos){
int ret=-1;
printk(KERN_INFO " new test write\n");

memset(kbuf, 0, sizeof(kbuf));

    ret = copy_from_user(kbuf, ubuf, count);
if (kbuf[0] == '1')

    {
//全on
        rGPJ0DAT = ((0<<3) | (0<<4) | (0<<5));

    }

    else if (kbuf[0] == '0')

    {

//全關


        rGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));

    
}
return 0;
}

static const struct file_operations test_fops={
.owner=THIS_MODULE,
.open=test_chardev_open,
.release=test_chardev_release,
.write=test_chardev_write,
.read=test_chardev_read,
};
static int __init chardev_init(void)
{ int ret=-1;
printk(KERN_INFO "new module chardev init");
mydev=MKDEV(MYMAJOR,0);
ret=register_chrdev_region(mydev,MYCNT,MYNAME)
;
if(ret)
{
printk(KERN_ERR "register_chrdev fail\n");
return -EINVAL;
}

printk(KERN_INFO "new register_chrdev success...myjor=%d.\n",mymajor);
cdev_init(&test_cdev,&test_fops);
ret=cdev_add(&test_cdev,mydev,MYCNT);
if(ret)
{
printk(KERN_ERR "unable to add cdev\n");
return -EINVAL;
}
printk(KERN_INFO "new cdev_add success\n");



return 0;
}
static void __exit chardev_exit(void)
{
    
printk(KERN_INFO "new module chardev exit\n");
cdev_del(&test_cdev);
unregister_chrdev_region(mydev, MYCNT);
}

module_init(chardev_init);
module_exit(chardev_exit);
// MODULE_xxx這種宏作用是用來添加模塊描述信息

MODULE_LICENSE("GPL");                // 描述模塊的許可證

MODULE_AUTHOR("aston");                // 描述模塊的作者

MODULE_DESCRIPTION("module test");    // 描述模塊的介紹信息

MODULE_ALIAS("alias xxx");            // 描述模塊的別名信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章