linux驱动程序

第一种用脚本文件:

Firstchardevice.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

 

MODULE_LICENSE("GPL");

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         return0;

}

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         register_chrdev(111,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         return0;

}

static void __exit myfirst_exit(void)

{

         unregister_chrdev(111,"first_drv");

}

module_init(myfirst_init);

module_exit(myfirst_exit);

 

test….c

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         write(fd,&val,4);

         return0;

}

 

Insertmodule.sh

#!/bin/bash

module="firstchardevice"

device="my_led"

/sbin/insmod ./$module.ko

major=$(awk"\$2==\"first_drv\" {print \$1}" /proc/devices)

echo $major

rm -f /dev/$device

/bin/mknod /dev/${device} c $major 0

 

Rmmodule.sh

#!/bin/bash

module="firstchardevice"

device="my_led"

/sbin/rmmod ./$module

/etc/rm -f $device

 

Makefile

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

 

 

自动mkmod

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/kernel.h>

 

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device *firstdrv_dev;

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_dev=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

static void __exit myfirst_exit(void)

{

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

module_init(myfirst_init);

module_exit(myfirst_exit);

 

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         write(fd,&val,4);

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

自动设备号

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

 

MODULE_LICENSE("GPL");

 

int major;

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         return0;

}

static void __exit myfirst_exit(void)

{

         unregister_chrdev(major,"first_drv");

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         write(fd,&val,4);

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

杂项驱动默认主设备号为10

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/miscdevice.h>

#include <linux/kernel.h>

 

MODULE_LICENSE("GPL")

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

};

 

static struct miscdevice led_drv_misc={

         .minor=255,

         .name="my_led",

         .fops=&myfirst_fops,

        

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         misc_register(&led_drv_misc);

         return0;

}

 

static void __exit myfirst_exit(void)

{

         misc_deregister(&led_drv_misc);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         write(fd,&val,4);

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

 

cdev标准字符设备需要手动mknod

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/cdev.h>

 

MODULE_LICENSE("GPL");

 

#define DEVICE_NAME "first_drv"

int major;

dev_t dev_nr=0;  //定义一个变量存放设备号

struct cdev my_cdev;

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

};

 

 

static int __init myfirst_init(void)

{

         intret;

         printk("welcometo init function!\n");

         if(major>0)

                  {

                          ret=register_chrdev_region(MKDEV(major,0),1,DEVICE_NAME);

                          if(ret<0)

                                   {

                                            printk("err!\n");

                                            returnret;

                                   }

                  }

         else

                  {

                          ret=alloc_chrdev_region(&dev_nr,0,1,DEVICE_NAME);

                          if(ret<0)

                                   {

                                            printk("err!\n");

                                            returnret;

                                   }

                          major=MAJOR(dev_nr);

                          printk("major:%d\n",major);

                  }

         cdev_init(&my_cdev,&myfirst_fops);

         my_cdev.owner=THIS_MODULE;

         ret=cdev_add(&my_cdev,dev_nr,1);

         if(ret<0)

                                   {

                                            printk("registererr!\n");

                                            unregister_chrdev_region(dev_nr,1);

                                           

                                   }

        

         returnret;

}

 

static void __exit myfirst_exit(void)

{

         cdev_del(&my_cdev);

         unregister_chrdev_region(dev_nr,1);

         printk("bye!\n");

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         write(fd,&val,4);

         return0;

}

 

Led灯驱动

#include <linux/init.h>

#include <asm/io.h>

 

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <asm/uaccess.h>

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

volatile unsigned long  *gpbcon;

volatile unsigned long  *gpbdat;

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         *gpbcon&=~((0x3<<(2*5))|(0x3<<(2*6))|(0x3<<(2*7))|(0x3<<(2*8)));

         *gpbcon|=((0x1<<(2*5))|(0x1<<(2*6))|(0x1<<(2*7))|(0x1<<(2*8)));

         *gpbdat&=~((1<<5)|(1<<6)|(1<<7)|(1<<8));

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         intval;

         printk("first_char_devicewrite test!\n");

         copy_from_user(&val,buf,count);

         if(val==1)

                  {

                          *gpbdat&=~((1<<5)|(1<<6)|(1<<7)|(1<<8));

                  }

         else

                  {

                          *gpbdat

=((1<<5)|(1<<6)|(1<<7)|(1<<8));

                  }

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         gpbcon=(unsignedlong*)ioremap(0x56000010,16);

         gpbdat=gpbcon+1;

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

         iounmap(gpbcon);

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

#include <sys/types.h>

#include <unistd.h>

int main(int argc,char** argv)

{

         intfd;

         intval;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         if(argc!=2)

                  {

                          printf("usage:\n");

                          printf("%s<on|off>\n",argv[0]);

                  }

         if(strcmp("on",argv[1])==0)

                  val=1;

         else

                  val=0;

         write(fd,&val,4);

         return0;

}

insmod 后

执行 /etc/rc.d/init.d/leds stop

  接着执行 test。。。。

就是测试那句

 

启动

/etc/rc.d/init.d/leds start

 

 

利用系统现成的函数做led驱动

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <asm/io.h>

#include <asm/uaccess.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

 

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

 

static unsigned long led_table[]=

{

         S3C2410_GPB5,

         S3C2410_GPB6,

         S3C2410_GPB7,

         S3C2410_GPB8,

};

 

static unsigned int gpio_cfg_table[]=

{

                  S3C2410_GPB5_OUTP,

                  S3C2410_GPB6_OUTP,

                  S3C2410_GPB7_OUTP,

                  S3C2410_GPB8_OUTP,

};

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

        

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         intval;

         inti;

         printk("first_char_devicewrite test!\n");

         copy_from_user(&val,buf,count);

         if(val==1)

                  {

                          for(i=0;i<4;i++)

                                   s3c2410_gpio_setpin(led_table[i],0);

                  }

         else

                  {

                          for(i=0;i<4;i++)

                                   s3c2410_gpio_setpin(led_table[i],1);

                  }

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         inti;

         printk("welcometo init function!\n");

         for(i=0;i<4;i++)

                  {

                          s3c2410_gpio_cfgpin(led_table[i],gpio_cfg_table[i]);

                          s3c2410_gpio_setpin(led_table[i],1);

                  }

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

#include <sys/types.h>

#include <unistd.h>

int main(int argc,char** argv)

{

         intfd;

         intval;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         if(argc!=2)

                  {

                          printf("usage:\n");

                          printf("%s<on|off>\n",argv[0]);

                  }

         if(strcmp("on",argv[1])==0)

                  val=1;

         else

                  val=0;

         write(fd,&val,4);

         return0;

}

insmod 后

执行 /etc/rc.d/init.d/leds stop

  接着执行 test。。。。

就是测试那句

 

启动

/etc/rc.d/init.d/leds start

 

 

Ioctl自编的

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <asm/uaccess.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

 

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

static unsigned long gpio_table [] =

{

         S3C2410_GPB5,

         S3C2410_GPB6,

         S3C2410_GPB7,

         S3C2410_GPB8,

};

 

static unsigned int gpio_cfg_table [] =

{

         S3C2410_GPB5_OUTP,

         S3C2410_GPB6_OUTP,

         S3C2410_GPB7_OUTP,

         S3C2410_GPB8_OUTP,

};

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         inti;

         printk("first_char_deviceopen test!\n");

         for(i = 0; i < 4; i++)

         {

                  s3c2410_gpio_cfgpin(gpio_table[i],gpio_cfg_table[i]);

                  s3c2410_gpio_setpin(gpio_table[i],0);

         }

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         intval;

         inti;

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static int myfirst_ioctl(struct inode*inode, struct file *file, unsigned int cmd, unsigned long arg)

{

         inti;

         if(arg>4)

                  {

                          printk("error!\n");

                          return-EINVAL;

                  }

         if(cmd==0)

                  {

                          if(arg==4)

                                   {

                                            for(i=0;i<4;i++)

                                                     s3c2410_gpio_setpin(gpio_table[i],1);

        

                                   }

                          else

                                   s3c2410_gpio_setpin(gpio_table[arg],1);

                  }

         else

                  {

                          if(arg==4)

                                   {

                                            for(i=0;i<4;i++)

                                                     s3c2410_gpio_setpin(gpio_table[i],0);

        

                                   }

                          else

                                   s3c2410_gpio_setpin(gpio_table[arg],0);

                  }

}

 

static int myfirst_close(struct inode*inode, struct file *file)

{

         printk("bye!\n");

         return0;

}

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

         .ioctl           =myfirst_ioctl,

         .release               =myfirst_close,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         intled_nu;

         inton;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         if((argc!=3)||sscanf(argv[1],"%d",&led_nu)!=1||sscanf(argv[2],"%d",&on)!=1||on<0||on>1||led_nu>4)

                  {

                          printf("usage:\n");

                          printf("%sled_nu 0|1>\n",argv[0]);

                          return0;

                  }

         ioctl(fd,on,led_nu);

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

跑马灯自编

My_misc_led.c

#include <linux/miscdevice.h>

#include <linux/delay.h>

#include <asm/irq.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/mm.h>

#include <linux/fs.h>

#include <linux/types.h>

#include <linux/delay.h>

#include <linux/moduleparam.h>

#include <linux/slab.h>

#include <linux/errno.h>

#include <linux/ioctl.h>

#include <linux/cdev.h>

#include <linux/string.h>

#include <linux/list.h>

#include <linux/pci.h>

#include <asm/uaccess.h>

#include <asm/atomic.h>

#include <asm/unistd.h>

#include "mycmdioctl.h"

 

#define DEVICE_NAME "myled"

/*用来实现宏名打印*/

#define   MACRO_(x)        #x

 

 

/* 鐢ㄦ潵鎸囧畾LED鎵€鐢ㄧ殑GPIO寮曡剼 */

static unsigned long gpio_table [] =

{

         S3C2410_GPB5,

         S3C2410_GPB6,

         S3C2410_GPB7,

         S3C2410_GPB8,

};

 

/* 鐢ㄦ潵鎸囧畾GPIO寮曡剼鐨勫姛鑳斤細杈撳嚭 */

static unsigned int gpio_cfg_table [] =

{

         S3C2410_GPB5_OUTP,

         S3C2410_GPB6_OUTP,

         S3C2410_GPB7_OUTP,

         S3C2410_GPB8_OUTP,

};

 

static int my_tq2440_gpio_ioctl(

         structinode *inode,

         structfile *file,

         unsignedint cmd,

         unsignedlong arg)

{

         interr = 0;

         intret = 0;

         inttemp = 0;

         intvalue =0;

         inti;

         printk(KERN_EMERG"\r\n/*--------------------------------------------------------------*/\r\n");

 

         /*提取命令cmd的type位域和number位域

          * 不解码错误命令

          */

         if(_IOC_TYPE(cmd) != MYCMD_IOC_MAGIC)

                  return-ENOTTY;

 

         if(_IOC_NR(cmd) > MYCMD_IOC_MAXNR)

                  return-ENOTTY;

 

         /*cmd的"Type"域 是针对用户空间而言的

          * access_ok是面向内核的

          * 因此,"读取"和"写入"的概念是相反的

          */

         /*_IOC_DIR(cmd) & _IOC_READ分析:

          * 判断CMD的dir字段是否是read

          * 之所以可以这样判断,是因为_IOC_READ、_IOC_WRITE、_IOC_NONE

          * 各对应位是互斥的,任何两两交叉AND操作均会得到0

          */

         if(_IOC_DIR(cmd) & _IOC_READ)

                  /*access_ok返回布尔值:       

                   * 1:访问成功

                   * 0:访问失败

                   */

                  err= !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));

 

         elseif (_IOC_DIR(cmd) & _IOC_WRITE)

                  err=  !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));

 

         if(err)

                  return-EFAULT;

 

 

         switch(cmd)

         {

         caseMYCMD_IOC_LEDS_NUM_ON:

 

                  /*打印宏名和内容*/

                  printk("%s:\r\n\r\n",MACRO_(MYCMD_IOC_LEDS_NUM_ON));      

                  get_user(value,(int *)arg);      

                  s3c2410_gpio_setpin(gpio_table[value],0);

                  return        0;

                  break;       

 

         caseMYCMD_IOC_LEDS_NUM_OFF:

 

                  /*打印宏名和内容*/

                  printk("%s:\r\n\r\n",MACRO_(MYCMD_IOC_LEDS_NUM_OFF));     

                  get_user(value,(int *)arg);      

                  s3c2410_gpio_setpin(gpio_table[value],1);

                  return        0;

                  break;      

                         

         caseMYCMD_IOC_LEDS_ALL_ON_SET:

                  /*打印宏名和内容*/

                  printk("%s:\r\n\r\n",MACRO_(MYCMD_IOC_LEDS_All_ON_SET));  

                  for(i = 0; i < 4; i++)

                  {

                          s3c2410_gpio_setpin(gpio_table[i],0);

                  }      

                  return0;

                  break;      

 

         caseMYCMD_IOC_LEDS_ALL_OFF_SET:

 

                  /*打印宏名和内容*/

                  printk("%s:\r\n\r\n",MACRO_(MYCMD_IOC_LEDS_ALL_OFF_SET));                 

                  for(i = 0; i < 4; i++)

                  {

                          s3c2410_gpio_setpin(gpio_table[i],1);

                  }

                  return0;

                  break;                       

         default:

                  printk("ivcmd:%d \r\n",cmd);

                  return-ENOTTY;;

         }

 

         return0;     /* 返回值根据命令的不同,意义不同

                                    * 一般情况

                                    * 成功执行,返回0

                                    * 失败,返回负错误码

                                    */   

}

 

static struct file_operations my_dev_fops ={

         .owner        =       THIS_MODULE,

         .ioctl  =       my_tq2440_gpio_ioctl,

};

 

static struct miscdevice misc = {

         .minor= MISC_DYNAMIC_MINOR,

         .name= DEVICE_NAME,

         .fops= &my_dev_fops,

};

 

static int __init dev_init(void)

{

         intret;

 

         inti;

        

         for(i = 0; i < 4; i++)

         {

                  s3c2410_gpio_cfgpin(gpio_table[i],gpio_cfg_table[i]);

                  s3c2410_gpio_setpin(gpio_table[i],0);

         }

 

         ret= misc_register(&misc);

 

         printk(DEVICE_NAME" initialized\n");

 

         returnret;

}

 

static void __exit dev_exit(void)

{

         misc_deregister(&misc);

}

 

module_init(dev_init);

module_exit(dev_exit);

mycmdioctl.h

#ifndef __MY_CMD_IOCTL_H__

#define __MY_CMD_IOCTL_H__

 

#include <linux/ioctl.h>

 

/* Use 't' as magic number */

#define MYCMD_IOC_MAGIC  't'

 

#define MYCMD_IOC_LEDS_NUM_ON     _IOW(MYCMD_IOC_MAGIC, 0,int)         //点亮当前led

#define MYCMD_IOC_LEDS_NUM_OFF    _IOW(MYCMD_IOC_MAGIC, 1,int)         //熄灭当前led

#define MYCMD_IOC_LEDS_ALL_ON_SET     _IO(MYCMD_IOC_MAGIC,2)    //全部开led

#define MYCMD_IOC_LEDS_ALL_OFF_SET    _IO(MYCMD_IOC_MAGIC,3)    //全部关led

 

#define MYCMD_IOC_MAXNR 3

#endif

Test-----

#include <stdio.h>

#include <fcntl.h>

#include "mycmdioctl.h"

unsigned long cmd_buf[]={

         MYCMD_IOC_LEDS_NUM_ON,MYCMD_IOC_LEDS_NUM_OFF,

         MYCMD_IOC_LEDS_ALL_ON_SET,MYCMD_IOC_LEDS_ALL_OFF_SET,

         };

int main(int argc,char** argv)

{

         intfd;

         intcmd_arg;

         fd=open("/dev/myled",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

       while (1)

         {      

                  for(cmd_arg=0;cmd_arg<4;cmd_arg++)

                  {

                          ioctl(fd,MYCMD_IOC_LEDS_NUM_ON,&cmd_arg);

                          sleep(1);

                          ioctl(fd,MYCMD_IOC_LEDS_NUM_OFF,&cmd_arg);

                  }

                  sleep(1);

                  ioctl(fd,MYCMD_IOC_LEDS_ALL_ON_SET);

                  sleep(1);

                  ioctl(fd,MYCMD_IOC_LEDS_ALL_OFF_SET);

                  sleep(1);

         }

         return0;

}

MODNAME=my_misc_led

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4

obj-m=$(MODNAME).o

all:

         make-C $(KERNALDIR)  SUBDIRS=`pwd` modules

         arm-linux-gcctest$(MODNAME).c -o test$(MODNAME)

clean:

         make-C $(KERNALDIR)  SUBDIRS=`pwd` clean

myclean:

         @rm-rf *.o *.ko *.mod.c modules.* Module.*

 

杂项设备

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/miscdevice.h>

 

MODULE_LICENSE("GPL");

static int canopen=1;

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         if(--canopen!=0)

                  {

                          printk("filewas already opend,only once!\n");

                          canopen++;

                          return-EBUSY;

                  }

         printk("first_char_deviceopen test!\n");

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

static int myfirst_close(struct inode*inode, struct file *file)

{

         printk("first_char_deviceclose test!\n");

         canopen++;

         return0;

}

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

         .release               =myfirst_close,

};

static struct miscdevice  my_misc_test={

         .minor=MISC_DYNAMIC_MINOR,

         .name="my_led",

         .fops=&myfirst_fops,

};

 

static int __init myfirst_init(void)

{

         intret;

         printk("welcometo init function!\n");

         ret=misc_register(&my_misc_test);

         if(ret<0)

                  printk("registermiscdevice failed!\n");

         returnret;

}

 

static void __exit myfirst_exit(void)

{

         printk("bye!\n");

         misc_deregister(&my_misc_test);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         write(fd,&val,4);

         sleep(15);

         close(fd);

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

 

等待队列

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/wait.h>

#include <linux/sched.h>

#include <linux/uaccess.h>

 

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

static DECLARE_WAIT_QUEUE_HEAD(key_queue);

static int vpress=0;

static int testval=55;

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         return0;

}

static ssize_t myfirst_read(struct file*file, char __user *buf, size_t size, loff_t *ppos)

{

         printk("first_char_deviceread test!\n");

         //直接进入休眠,挂在等待队列中

         wait_event_interruptible(key_queue,vpress);

         printk("%d\n",testval);

         copy_to_user(buf,&testval,4);

         vpress=0;

         printk("waitqueue:finishedto read data from device!\n");

         return0;

}

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         copy_from_user(&vpress,buf,count);

         wake_up_interruptible(&key_queue);

         printk("waitqueue:finishedto write data to device!\n");

         return0;

}

static int myfirst_close(struct inode*inode, struct file *file)

{

         printk("first_char_deviceclose !\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .read          =myfirst_read,

         .write         = myfirst_write,

         .release              =myfirst_close,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         init_waitqueue_head(&key_queue);

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=1;

         inttest;

         charch;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         while(1)

                  {

                          //显示菜单

                          printf("\t1.presskey \'r\' to read device!\n");

                          printf("\t1.presskey \'w\' to write device!\n");

                          printf("\t1.presskey \'q\' to exit!\n");

                          ch=getchar();

                          getchar();

 

                          //根据输入进行判断

                          if('q'==ch)

                                   break;

                          switch(ch){

                                   case'r':

                                            printf("testbefore reading...\n");

                                            read(fd,&test,4);

                                            printf("val=%d\n",test);

                                            printf("testafter reading...\n");

                                            break;

                                   case'w':

                                            printf("testbefore writing...\n");

                                            val=5;

                                            write(fd,&val,4);

                                            printf("testafter writing...\n");

                                            break;

                                   default:

                                            break;

                          sleep(1);

                                   }

                  }

         close(fd);            

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

led灯按键操作

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <asm/uaccess.h>

#include <asm/io.h>

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

volatile unsigned long  *gpfcon;

volatile unsigned long  *gpfdat;

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         *gpfcon&=~((0x3<<0)|(0x3<<2)|(0x3<<4)|(0x3<<8));

         return0;

}

static ssize_t myfirst_read(struct file*file, char __user *buf, size_t size, loff_t *ppos)

{

         intkey_val=0;

         printk("first_char_deviceread test!\n");

         if(!(*gpfdat&(0x1<<0)))

                  {key_val=1;printk("%d\n",key_val);}

         if(!(*gpfdat&(0x1<<1)))

                  {key_val=2;printk("%d\n",key_val);}

         if(!(*gpfdat&(0x1<<2)))

                  {key_val=3;printk("%d\n",key_val);}

         if(!(*gpfdat&(0x1<<4)))

                  {key_val=4;printk("%d\n",key_val);}

         copy_to_user(buf,&key_val,4);

         return0;

}

 

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .write         = myfirst_write,

         .read         =myfirst_read,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         gpfcon=(unsignedlong*)ioremap(0x56000050,16);

         gpfdat=gpfcon+1;

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

         iounmap(gpfcon);

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

#include <sys/types.h>

#include <unistd.h>

int main(int argc,char** argv)

{

         intfd;

         intval;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         while(1)

                  {

                          if(read(fd,&val,4)==0)

                                   if(val)

                                            printf("keynumber is %d\n",val);

                  }

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

led按键驱动

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#include <asm/io.h>

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         printk("first_char_deviceopen test!\n");

         s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_INP);

         s3c2410_gpio_cfgpin(S3C2410_GPF1,S3C2410_GPF1_INP);

         s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_INP);

         s3c2410_gpio_cfgpin(S3C2410_GPF4,S3C2410_GPF4_INP);

         return0;

}

static ssize_t myfirst_read(struct file*file, __user char *buf, size_t count,

                          loff_t*ppos)

{      

         intkey_val;

         //printk("first_char_deviceread test!\n");

         if(!(s3c2410_gpio_getpin(S3C2410_GPF0)))

                  key_val=1;

         if(!(s3c2410_gpio_getpin(S3C2410_GPF1)))

                  key_val=2;

         if(!(s3c2410_gpio_getpin(S3C2410_GPF2)))

                  key_val=3;

         if(!(s3c2410_gpio_getpin(S3C2410_GPF4)))

                  key_val=4;

         copy_to_user(buf,&key_val,4);

         return0;

}

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .read          =myfirst_read,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

        

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

 

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=0;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         while(1)

                  {

                          if(read(fd,&val,4)==0)

                                   {

                                   if((val==1) || (val==2) || (val==3) || (val==4))

                                            printf("keynumber is %d\n",val);

                                   }

                  }

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

led按键驱动for循环

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#include <asm/io.h>

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

 

struct keynumdata {

         unsigned  long pin_key;

         unsignedint pin_key_cfg;

};

static struct keynumdata mykeydata[4]=

{

                  {S3C2410_GPF0,S3C2410_GPF0_INP},

                  {S3C2410_GPF1,S3C2410_GPF1_INP},

                  {S3C2410_GPF2,S3C2410_GPF2_INP},

                  {S3C2410_GPF4,S3C2410_GPF4_INP},

};

 

static int myfirst_open(struct inode *inode,struct file *file)

{

         inti;

         printk("first_char_deviceopen test!\n");

         for(i=0;i<4;i++)

                  s3c2410_gpio_cfgpin(mykeydata[i].pin_key,mykeydata[i].pin_key_cfg);

         return0;

}

static ssize_t myfirst_read(struct file*file, __user char *buf, size_t count,

                          loff_t*ppos)

{      

         intkey_val;

         inti;

         for(i=0;i<4;i++)

                  if(!(s3c2410_gpio_getpin(mykeydata[i].pin_key)))

                          key_val=i+1;

         copy_to_user(buf,&key_val,4);

         return0;

}

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .read          =myfirst_read,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

        

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

 

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         intval=0;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         while(1)

                  {

                          if(read(fd,&val,4)==0)

                                   {

                                   if((val==1) || (val==2) || (val==3) || (val==4))

                                            printf("keynumber is %d\n",val);

                                   }

                  }

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

 

内核修改中断

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <asm/io.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#include <linux/interrupt.h>

#include <mach/irqs.h>

#include <linux/wait.h>

 

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

static int vpress=0;

static DECLARE_WAIT_QUEUE_HEAD(key_queue);

static unsigned char key_val;

 

struct keynumdata {

         unsignedlong pin_key;

         unsignedint pin_key_cfg;

         unsignedchar pin_key_val;

         char* name;

         intirq_nu;

        

};

 

static struct keynumdata mykeydata[4]=

{

                  {S3C2410_GPF0,S3C2410_GPF0_EINT0,0x01,"key1",IRQ_EINT0},

                  {S3C2410_GPF1,S3C2410_GPF1_EINT1,0x02,"key2",IRQ_EINT1},

                  {S3C2410_GPF2,S3C2410_GPF2_EINT2,0x03,"key3",IRQ_EINT2},

                  {S3C2410_GPF4,S3C2410_GPF4_EINT4,0x04,"key4",IRQ_EINT4},

};

 

static irqreturn_t key_int_function(int irq,void *mypoint)

{

         printk("enterinterrupt!");

         structkeynumdata  *mykeydata_tmp=(structkeynumdata  *)(mypoint);

         if(!(s3c2410_gpio_getpin(mykeydata_tmp->pin_key)))

                          key_val=mykeydata_tmp->pin_key_val|0x80;

         else

                          key_val=mykeydata_tmp->pin_key_val;

         vpress=1;

         wake_up_interruptible(&key_queue);

         returnIRQ_HANDLED;

}

static int myfirst_open(struct inode *inode,struct file *file)

{

         inti;

         printk("first_char_deviceopen test!\n");

         for(i=0;i<4;i++)

                  {

                          s3c2410_gpio_cfgpin(mykeydata[i].pin_key,mykeydata[i].pin_key_cfg);

                          request_irq(mykeydata[i].irq_nu,key_int_function,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_SHARED,mykeydata[i].name, (void *)&mykeydata[i]);

                  }

         return0;

}

static ssize_t myfirst_read(struct file*file, __user char *buf, size_t count,

                          loff_t*ppos)

{      

         //当vpress=0时,该进程挂入等待队列,休眠

         //当vpress=1时,通过wake_up_interruptible();唤醒队列

         printk("entermyfirst_read!\n");

        

         wait_event_interruptible(key_queue,vpress);

         vpress=0;

         copy_to_user(buf,&key_val,count);

         return0;

}

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .read          =myfirst_read,

         .write         = myfirst_write,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

         inti;

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

         for(i=0;i<4;i++)

                  {

                          free_irq(mykeydata[i].irq_nu,  (void *)&mykeydata[i]);

                  }

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char** argv)

{

         intfd;

         unsignedchar val;

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         while(1)

                  {

                          read(fd,&val,1);

                          printf("keys:0x%02x\n",val);

                  }

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

需要生成一个zimage

 

中断按键驱动

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#include <asm/io.h>

#include <linux/wait.h>

#include <linux/interrupt.h>

#include <linux/poll.h>

 

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

static int vpress=0;

static DECLARE_WAIT_QUEUE_HEAD(key_queue);

static char key_val;

 

struct keynumdata {

         unsignedlong pin_key;

         unsignedint pin_key_cfg;

         intirq_nu;

         char* name;

         unsignedchar pin_key_val;

};

 

static struct keynumdata mykeydata[4]=

{

                  {S3C2410_GPF0,S3C2410_GPF0_EINT0,IRQ_EINT0,"key1",0x01},

                  {S3C2410_GPF1,S3C2410_GPF1_EINT1,IRQ_EINT1,"key2",0x02},

                  {S3C2410_GPF2,S3C2410_GPF2_EINT2,IRQ_EINT2,"key3",0x03},

                  {S3C2410_GPF4,S3C2410_GPF4_EINT4,IRQ_EINT4,"key4",0x04},

};

 

irqreturn_t key_inter_function(int irq, void*mypoint)

{

         structkeynumdata *mykeydata_tmp=(struct keynumdata *)mypoint;

         if(!s3c2410_gpio_getpin(mykeydata_tmp->pin_key))

                  key_val=mykeydata_tmp->pin_key_val|0x80;

         else

                  key_val=mykeydata_tmp->pin_key_val;

         vpress=1;

         wake_up_interruptible(&key_queue);

         returnIRQ_HANDLED;

}

static int myfirst_open(struct inode *inode,struct file *file)

{

         inti;

         printk("first_char_deviceopen test!\n");

         for(i=0;i<4;i++)

                  {

                          s3c2410_gpio_cfgpin(mykeydata[i].pin_key,mykeydata[i].pin_key_cfg);

                  request_irq(mykeydata[i].irq_nu,key_inter_function,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING|IRQF_SHARED,mykeydata[i].name,(void*)&mykeydata[i]);

                  }

         return0;

}

static ssize_t myfirst_read(struct file*file, __user char *buf, size_t count,

                          loff_t*ppos)

{      

        

         vpress=0;

         copy_to_user(buf,&key_val,count);

         return0;

}

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static int myfirst_close(struct inode *inode, struct file * file)

{

         inti;

         for(i=0;i<4;i++)

                  free_irq(mykeydata[i].irq_nu,(void*)&mykeydata[i]);

         return0;

}

 

static unsigned int myfirst_poll (structfile *file, struct poll_table_struct * wait)

{

         unsignedint mask=0;

         poll_wait(file,&key_queue, wait);

         if(vpress)

                  mask|= POLLIN | POLLRDNORM;

         returnmask;

}

 

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .read          =myfirst_read,

         .write         = myfirst_write,

         .release               =myfirst_close,

         .poll                    =myfirst_poll,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

 

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

#include <poll.h>

 

int main(int argc,char** argv)

{

         intfd;

         intret;

         unsignedchar  val=0;

         structpollfd key_pollfd[1];

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         key_pollfd[0].fd=fd;

         key_pollfd[0].events=POLLIN;

         while(1)

                  {

                  ret=poll(key_pollfd,1, 5000);

                  if(ret==-1)

                          printf("error!\n");

                  elseif (ret==0)

                          {

                                   printf("timeout!\n");

                          }

                  else

                          {

                                   read(fd,&val,1);

                                   printf("keynumber:0x%02x\n",val);

                          }

                  }

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

 

定时器

Key_timer.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/timer.h>

 

MODULE_LICENSE("GPL");

 

static struct timer_list key_timer;

static void timer_function(unsigned longdata)

{

         staticunsigned int i = 0;

        printk("timer:%ld!\n",data);

 #if 0

        my_timer.expires = jiffies + 2*HZ

 add_timer(&key_timer);

 #endif

 

 if(i++<5)

        mod_timer(&key_timer,jiffies + 2*HZ);

}

 

static int __init timer_init(void)

{

         init_timer(&key_timer);

         key_timer.expires=jiffies+5*HZ;

         key_timer.function=timer_function;

         key_timer.data=5;

         add_timer(&key_timer);

         return0;

}

 

static void __exit timer_exit(void)

{

         del_timer(&key_timer);

}

 

module_init(timer_init);

module_exit(timer_exit);

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=key_timer

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         #arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

 

定时器消除中断抖动

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <asm/io.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#include <linux/interrupt.h>

#include <mach/irqs.h>

#include <linux/wait.h>

#include <linux/poll.h>

 

MODULE_LICENSE("GPL");

 

int major;

static struct class *firstdrv_class;

static struct device*firstdrv_device;

static int vpress=0;

static DECLARE_WAIT_QUEUE_HEAD(key_queue);

static unsigned char key_val;

static struct timer_list key_timer;

 

struct keynumdata {

         unsignedlong pin_key;

         unsignedint pin_key_cfg;

         unsignedchar pin_key_val;

         char* name;

         intirq_nu;

        

};

 

static struct keynumdata mykeydata[4]=

{

                  {S3C2410_GPF0,S3C2410_GPF0_EINT0,0x01,"key1",IRQ_EINT0},

                  {S3C2410_GPF1,S3C2410_GPF1_EINT1,0x02,"key2",IRQ_EINT1},

                  {S3C2410_GPF2,S3C2410_GPF2_EINT2,0x03,"key3",IRQ_EINT2},

                  {S3C2410_GPF4,S3C2410_GPF4_EINT4,0x04,"key4",IRQ_EINT4},

};

struct keynumdata  *mykeydata_tmp=&mykeydata[0];

 

 

static void key_timer_funciton(unsigned longdata)

{

if(!(s3c2410_gpio_getpin(mykeydata_tmp->pin_key)))

                          key_val=mykeydata_tmp->pin_key_val|0x80;

         else

                          key_val=mykeydata_tmp->pin_key_val;

         vpress=1;

         wake_up_interruptible(&key_queue);

}

static irqreturn_t key_int_function(int irq,void *mypoint)

{

         mykeydata_tmp=(structkeynumdata  *)(mypoint);

         mod_timer(&key_timer,jiffies+HZ/100);

         returnIRQ_HANDLED;

}

static int myfirst_open(struct inode *inode,struct file *file)

{

         inti;

         printk("first_char_deviceopen test!\n");

         for(i=0;i<4;i++)

                  {

                          s3c2410_gpio_cfgpin(mykeydata[i].pin_key,mykeydata[i].pin_key_cfg);

                          request_irq(mykeydata[i].irq_nu,key_int_function,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_SHARED,mykeydata[i].name, (void *)&mykeydata[i]);

                  }

         init_timer(&key_timer);

         key_timer.function=key_timer_funciton;

         add_timer(&key_timer);

         return0;

}

static ssize_t myfirst_read(struct file*file, __user char *buf, size_t count,

                          loff_t*ppos)

{      

         //当vpress=0时,该进程挂入等待队列,休眠

         //当vpress=1时,通过wake_up_interruptible();唤醒队列

         vpress=0;

         copy_to_user(buf,&key_val,count);

         return0;

}

static ssize_t myfirst_write(struct file*file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         printk("first_char_devicewrite test!\n");

         return0;

}

 

static unsigned int myfirst_poll(struct file*file , struct poll_table_struct *wait)

{

         unsignedint mask=0;

         poll_wait(file,&key_queue,wait);

         if(vpress)

                  mask|=POLLIN|POLLRDNORM;

         returnmask;

}

static const struct file_operationsmyfirst_fops = {

         .owner                = THIS_MODULE,

         .open          = myfirst_open,

         .read          =myfirst_read,

         .write         = myfirst_write,

         .poll                    =myfirst_poll,

};

 

static int __init myfirst_init(void)

{

         printk("welcometo init function!\n");

         major=register_chrdev(0,"first_drv",&myfirst_fops);

         printk("major:%d\n",major);

         firstdrv_class=class_create(THIS_MODULE,"myclass");

         firstdrv_device=device_create(firstdrv_class,NULL,MKDEV(major,0),NULL,"my_led");

         return0;

}

 

static void __exit myfirst_exit(void)

{

         inti;

         unregister_chrdev(major,"first_drv");

         device_destroy(firstdrv_class,MKDEV(major,0));

         class_destroy(firstdrv_class);

         for(i=0;i<4;i++)

                  {

                          free_irq(mykeydata[i].irq_nu,  (void *)&mykeydata[i]);

                  }

}

 

module_init(myfirst_init);

module_exit(myfirst_exit);

#include <stdio.h>

#include <fcntl.h>

#include <poll.h>

 

int main(int argc,char** argv)

{

         intfd;

         intret;

         unsignedchar val;

         structpollfd key_pollfd[1];

         fd=open("/dev/my_led",O_RDWR);

         if(fd<0)

                          printf("can'topen!\n");

         key_pollfd[0].fd=fd;

         key_pollfd[0].events=POLLIN;

         while(1)

                  {

                          ret=poll(key_pollfd,1,5000);

                          if(ret==-1)

                                   printf("error!\n");

                          elseif (ret==0)

                                   printf("timeout!\n");

                          else

                                   {

                                                     printf("ret=0x%02x\n",ret);

                                                     read(fd,&val,1);

                                                     printf("keys:0x%02x\n",val);

                                   }

                  }

         return0;

}

KERNALDIR=/root/opt/EmbedSky/linux-2.6.30.4/

MODULENAME=firstchardevice

 

obj-m :=$(MODULENAME).o

all:

         make-C $(KERNALDIR) M=`pwd` modules

         arm-linux-gcc-o test$(MODULENAME) test$(MODULENAME).c

clean:

         make-C $(KERNALDIR) M=`pwd` clean

 

 

平台设备驱动

led_device_platform.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/platform_device.h>

 

MODULE_LICENSE("GPL");

static struct resource led_resource[] = {

         [0]={

                  .start = 0x56000010,

                  .end   = 0x56000010+ 8 - 1,

                  .flags = IORESOURCE_MEM,

         },

         [1]={

                  .start = 5,

                  .end   = 5,

                  .flags = IORESOURCE_IRQ,

         }

};

 

static void my_led_release(struct device*dev)

{

         printk("my_led_release\n");

}

 

struct platform_device led_pdevice = {

         .name         ="led_device_driver_platform",

         .id              = -1,

         .resource    = led_resource,

         .num_resources    = ARRAY_SIZE(led_resource),

         .dev                    = {

                  .release      =my_led_release,

         },

};

 

 

static int __init led_device_init(void)

{      

         platform_device_register(&led_pdevice);

         return0;

}

 

static void __exit led_device_exit(void)

{

         platform_device_unregister(&led_pdevice);

}

 

module_init(led_device_init);

module_exit(led_device_exit);

led_driver_platform.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/uaccess.h>

#include <linux/platform_device.h>

#include <asm/io.h>

 

MODULE_LICENSE("GPL");

 

static int led_major;

static struct class *led_cls;

static int led_pin;

static volatile unsigned long *gpbcon;

static volatile unsigned long *gpbdat;

 

static int led_platform_open(struct inode*inode, struct file *file)

{      

         printk("led_platform_open!\n");

         //初始化gpbcon,设置为输出状态10-17

         *gpbcon&=~(0x3<<(led_pin*2));

         *gpbcon|=(0x1<<(led_pin*2));

         //初始化gpbdat,设置灯的初始状态

         //*gpbdat|=(1<<led_pin);

         return0;

}

 

static ssize_t led_platform_write(structfile *file, const char __user *buf,

                           size_t count, loff_t *ppos)

{

         unsignedchar led_val=0;

         printk("led_platform_write!\n");

         //接收应用程序传递来的参数,根据参数的不同控制灯的亮灭

         copy_from_user(&led_val,buf,count);

         if(led_val)          //如果传递来是1,点亮灯

                  {

                          *gpbdat&=~(1<<led_pin);

                  }

         else                     //如果传递来是0,熄灭灯

                  {

                          *gpbdat|=(1<<led_pin);

                  }

         return0;

}

static int led_platform_close (struct inode*inode, struct file *file)

{

         printk("led_platform_close!\n");

         return0;

}

 

 

static const struct file_operationsled_fops={

         .owner        =THIS_MODULE,

         .open =led_platform_open,

         .write =led_platform_write,

         .release      =led_platform_close,

};

 

static int led_platform_probe(struct platform_device *pdevice)

{

         //获取资源

         structresource *res=platform_get_resource(pdevice,IORESOURCE_MEM,0);

         gpbcon=ioremap(res->start,res->end-res->start+1);

         gpbdat=gpbcon+1;

      res=platform_get_resource(pdevice,IORESOURCE_IRQ,0);

         led_pin=res->start;

         //普通字符设备驱动完成的工作,

         //例如注册字符设备,创建类,创建设备文件节点

         led_major=register_chrdev(0,"led_platform",&led_fops);

         led_cls=class_create(THIS_MODULE,"led_platform_class");

         device_create(led_cls,NULL,MKDEV(led_major,0),NULL,"myled");

         return0;

}

 

static int led_platform_remove(structplatform_device *pdevice)

{

         device_destroy(led_cls,MKDEV(led_major,0));

         class_destroy(led_cls);

         unregister_chrdev(led_major,"led_platform");

         return0;

}

 

static struct platform_driver led_pdriver ={

         .probe                 = led_platform_probe,

         .remove              = led_platform_remove,

         .driver                 = {

                  .name = "led_device_driver_platform",

                  .owner        = THIS_MODULE,

         },

};

static int __init led_driver_init(void)

{      

 

         returnplatform_driver_register(&led_pdriver);

        

}

static void __exit led_driver_exit(void)

{

         platform_driver_unregister(&led_pdriver);

}

 

module_init(led_driver_init);

module_exit(led_driver_exit);

test_led_devdri_platform.c

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

 

static void print_usage(char *str)

{

         printf("Usage:\n");

         printf("%s<on|off>\n", str);

}

 

int main(int argc, char **argv)

{

         intled_fd;

         unsignedchar led_val = 0;

         led_fd= open("/dev/myled", O_RDWR);

         if(led_fd< 0)

         {

                  printf("can'topen!\n");

                  return0;

         }

        

         if(argc!= 2)

         {

                  print_usage(argv[0]);

                  return0;

         }

 

         if(strcmp(argv[1],"on") == 0)

         {

                  led_val= 1; //点灯

         }

         else

         {

                  led_val= 0; //灭灯

         }

         write(led_fd,&led_val, 1);

         close(led_fd);

         return0;

}

 

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

static void print_usage(char *str)

{

         printf("Usage:\n");

         printf("%s<on|off>\n", str);

}

 

int main(int argc, char **argv)

{

         intled_fd;

         unsignedchar led_val = 0;

         led_fd= open("/dev/myled", O_RDWR);

         if(led_fd< 0)

         {

                  printf("can'topen!\n");

                  return0;

         }

         if(argc!= 2)

         {

                  print_usage(argv[0]);

                  return0;

         }

 

         if(strcmp(argv[1],"on") == 0)

         {

                  led_val= 1; //点灯

         }

         else

         {

                  led_val= 0; //灭灯

         }

         write(led_fd,&led_val, 1);

         close(led_fd);

         return0;

}

KERNELDIR?=/root/opt/EmbedSky/linux-2.6.30.4

obj-m +=led_device_platform.oled_driver_platform.o

default:

         arm-linux-gcctest_led_devdri_platform.c -o test_led_devdri_platform

         $(MAKE)-C $(KERNELDIR) M=`pwd` modules

clean:

         rm-rf *.o *.mod.* *.ko .$(MODNAME).* .tmp* module* Module*

 

先插入模块device

再插入模块driver

/etc/rc.d/init.d/leds stop 关掉

 

卸载的时候先 driver

再 device

 

 

块设备驱动

01

myramblock.c

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/genhd.h>

#include <linux/blkdev.h>

 

MODULE_LICENSE("GPL");

 

#define RAMBLOCKSIZE (1024*1024)

static struct gendisk *myramblock_disk;

static struct request_queue *myramblock_queue;

static int major;

static DEFINE_SPINLOCK(myramblock_lock);

 

static struct block_device_operationsmyramblock_fops =

{

         .owner                = THIS_MODULE,

};

 

static void do_myramblock_request(structrequest_queue *q)

{

 

         staticint cnt=0;

         printk("do_myramblock_request%d\n",++cnt);

        

}

static int __init myramblock_init(void)

{

       /*1、分配一个gendisk结构体*/

         myramblock_disk=alloc_disk(16);  /*次设备的个数*/

       /*2、设置*/

              /*2.1 设置队列   request_queue*/

         myramblock_queue=blk_init_queue(do_myramblock_request,&myramblock_lock);

         myramblock_disk->queue=myramblock_queue;

         /*2.2设置其他属性,例如容量等*/

         major=register_blkdev(0,"myramblock");

          myramblock_disk->major=major;

          myramblock_disk->first_minor=0;

          sprintf(myramblock_disk->disk_name,"myramblick");

         myramblock_disk->fops=&myramblock_fops;

         set_capacity(myramblock_disk,RAMBLOCKSIZE/512);

 

         /*3、添加块设备*/

       add_disk(myramblock_disk);

         return0;

}

static void __exit myramblock_exit(void)

{

         unregister_blkdev(major,"myramblock");

         del_gendisk(myramblock_disk);

}

 

module_init(myramblock_init);

module_exit(myramblock_exit);

KERNELDIR?=/root/opt/EmbedSky/linux-2.6.30.4

obj-m +=myramblock.o

default:

         #arm-linux-gcctest_led_devdri_platform.c -o test_led_devdri_platform

         $(MAKE)-C $(KERNELDIR) M=`pwd` modules

clean:

         rm-rf *.o *.mod.* *.ko .$(MODNAME).* .tmp* module* Module*

 

 

02

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/genhd.h>

#include <linux/blkdev.h>

 

MODULE_LICENSE("GPL");

 

#define RAMBLOCKSIZE (1024*1024)

static struct gendisk *myramblock_disk;

static struct request_queue*myramblock_queue;

static int major;

static DEFINE_SPINLOCK(myramblock_lock);

 

static struct block_device_operationsmyramblock_fops =

{

         .owner                = THIS_MODULE,

};

static void do_myramblock_request(structrequest_queue *q)

{

         structrequest *req;

         staticint cnt=0;

         printk("do_myramblock_request%d\n",++cnt);

         while((req= elv_next_request(q)) != NULL)

                  end_request(req,1);  //第二个参数为1,表示正确处理了请求

}

static int __init myramblock_init(void)

{

       /*1、分配一个gendisk结构体*/

         myramblock_disk=alloc_disk(16);  /*次设备的个数*/

       /*2、设置*/

              /*2.1 设置队列   request_queue*/

         myramblock_queue=blk_init_queue(do_myramblock_request,&myramblock_lock);

         myramblock_disk->queue=myramblock_queue;

         /*2.2设置其他属性,例如容量等*/

         major=register_blkdev(0,"myramblock");

          myramblock_disk->major=major;

          myramblock_disk->first_minor=0;

          sprintf(myramblock_disk->disk_name,"myramblick");

         myramblock_disk->fops=&myramblock_fops;

         set_capacity(myramblock_disk,RAMBLOCKSIZE/512);

 

         /*3、添加块设备*/

       add_disk(myramblock_disk);

         return0;

}

static void __exit myramblock_exit(void)

{

         unregister_blkdev(major,"myramblock");

         del_gendisk(myramblock_disk);

}

module_init(myramblock_init);

module_exit(myramblock_exit);

KERNELDIR ?=/root/opt/EmbedSky/linux-2.6.30.4

obj-m +=myramblock.o

default:

         #arm-linux-gcctest_led_devdri_platform.c -o test_led_devdri_platform

         $(MAKE)-C $(KERNELDIR) M=`pwd` modules

clean:

         rm-rf *.o *.mod.* *.ko .$(MODNAME).* .tmp* module* Module*

 

 

块设备修改

01

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/genhd.h>

#include <linux/blkdev.h>

 

MODULE_LICENSE("GPL");

 

static struct gendisk *myramblock_disk;

static int mymajor;

static struct request_queue*myramblock_queue;

static DEFINE_SPINLOCK(myramblock_lock);

#define MYRAMBLOCK_SIZE (1024*1024)

static unsigned char *ramblock_buffer;

 

static struct block_device_operationsmyramblock_fops = {

         .owner        = THIS_MODULE,

};

 

static void do_myramblock_request (structrequest_queue * q)

{

         structrequest *req;

         staticint cnt=0;

         printk("do_myramblock_request!%d\n",++cnt);

         while((req = elv_next_request(q)) != NULL) {

         /*判读读写方向,进行数据传递*/

      /*数据传递三要素:源,目的,大小*/

         unsignedlong offset = req->sector*512;

         unsignedlong len = req->nr_sectors*512;

         if(rq_data_dir(req) == READ)

                   memcpy(req->buffer, ramblock_buffer+offset,len);

          else

                   memcpy(ramblock_buffer+offset, req->buffer,len);

         end_request(req,1);     

         }

}

static int __init myramblock_init(void)

{

         mymajor=register_blkdev(0,"myramblock");

         /*1、分配一个gendisk结构体*/

          myramblock_disk= alloc_disk(8);

         /*2、设置*/

         /*2.1设置队列*/

         myramblock_queue= blk_init_queue(do_myramblock_request, &myramblock_lock);

         myramblock_disk->queue=myramblock_queue;

         /*2.2设置其他属性*/

         myramblock_disk->major=mymajor;

         myramblock_disk->first_minor=0;

         sprintf(myramblock_disk->disk_name,"myramblock");

         myramblock_disk->fops=&myramblock_fops;

         set_capacity(myramblock_disk,MYRAMBLOCK_SIZE/512);

         /*硬件操作,分配空间*/

         ramblock_buffer=kmalloc(MYRAMBLOCK_SIZE,GFP_KERNEL);

         /*4、添加块设备*/

         add_disk(myramblock_disk);

        

         return0;

}

static void __exit myramblock_exit(void)

{

         del_gendisk(myramblock_disk);

         kfree(ramblock_buffer);

         unregister_blkdev(mymajor,"myramblock");

}

 

module_init(myramblock_init);

module_exit(myramblock_exit);

KERNELDIR?=/root/opt/EmbedSky/linux-2.6.30.4

obj-m +=myramblock.o

default:

         #arm-linux-gcctest_led_devdri_platform.c -o test_led_devdri_platform

         $(MAKE)-C $(KERNELDIR) M=`pwd` modules

clean:

         rm-rf *.o *.mod.* *.ko .$(MODNAME).* .tmp* module* Module*

 

 

02

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/genhd.h>

#include <linux/blkdev.h>

#include <linux/hdreg.h>

 

MODULE_LICENSE("GPL");

 

static struct gendisk *myramblock_disk;

static int mymajor;

static struct request_queue*myramblock_queue;

static DEFINE_SPINLOCK(myramblock_lock);

#define MYRAMBLOCK_SIZE (1024*1024)

static unsigned char *ramblock_buffer;

 

static int

myramblock_getgeo(struct block_device *bdev,struct hd_geometry *geo)

{

         geo->cylinders=32;

         geo->heads= 2;

         geo->sectors=MYRAMBLOCK_SIZE/2/32/512;

         return0;

}

static struct block_device_operationsmyramblock_fops = {

         .owner        = THIS_MODULE,

         .getgeo   =myramblock_getgeo,

};

 

static void do_myramblock_request (struct request_queue* q)

{

         structrequest *req;

         staticint r_cnt=0;

         staticint w_cnt=0;

         while((req = elv_next_request(q)) != NULL) {

         /*判读读写方向,进行数据传递*/

      /*数据传递三要素:源,目的,大小*/

         unsignedlong offset = req->sector*512;

         unsignedlong len = req->nr_sectors*512;

         if(rq_data_dir(req) == READ)

                  {

                          memcpy(req->buffer,ramblock_buffer+offset, len);

                          printk("do_myramblock_request!read %d\n",++r_cnt);

                  }

          else

                 {

                          memcpy(ramblock_buffer+offset,req->buffer, len);

                          printk("do_myramblock_request!write %d\n",++w_cnt);

                 }

         end_request(req,1);     

         }

}

static int __init myramblock_init(void)

{

         mymajor=register_blkdev(0,"myramblock");

         /*1、分配一个gendisk结构体*/

          myramblock_disk= alloc_disk(8);

         /*2、设置*/

         /*2.1设置队列*/

         myramblock_queue= blk_init_queue(do_myramblock_request, &myramblock_lock);

         myramblock_disk->queue=myramblock_queue;

         /*2.2设置其他属性*/

         myramblock_disk->major=mymajor;

         myramblock_disk->first_minor=0;

         sprintf(myramblock_disk->disk_name,"myramblock");

         myramblock_disk->fops=&myramblock_fops;

         set_capacity(myramblock_disk,MYRAMBLOCK_SIZE/512);

         /*硬件操作,分配空间*/

         ramblock_buffer=kzalloc(MYRAMBLOCK_SIZE,GFP_KERNEL);

         /*4、添加块设备*/

         add_disk(myramblock_disk);

        

         return0;

}

 

static void __exit myramblock_exit(void)

{

         del_gendisk(myramblock_disk);

         kfree(ramblock_buffer);

         unregister_blkdev(mymajor,"myramblock");

}

 

module_init(myramblock_init);

module_exit(myramblock_exit);

KERNELDIR?=/root/opt/EmbedSky/linux-2.6.30.4

obj-m +=myramblock.o

default:

         #arm-linux-gcctest_led_devdri_platform.c -o test_led_devdri_platform

         $(MAKE)-C $(KERNELDIR) M=`pwd` modules

clean:

         rm-rf *.o *.mod.* *.ko .$(MODNAME).* .tmp* module* Module*

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值