#include<linux/module.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/uaccess.h>
#include<linux/io.h>
#include<linux/device.h>
#include"head.h"
#define RED_BASE 0xC001A000
#define GREEN_BASE 0xC001E000
#define BLUE_BASE 0xC001B000
unsigned int *red_base=NULL;
unsigned int *green_base=NULL;
unsigned int *blue_base=NULL;
struct class *cls;
struct device *dev;
char kbuf[128]={0};
#define CNAME "hello"
int major=0;
int mycdev_open(struct inode *inode,struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
long mycdev_ioctl(struct file *file,unsigned int request,unsigned long args)
{
int ret;
switch(request)
{
case RLED_ON:
*red_base |=(1<<28);
break;
case RLED_OFF:
*red_base &=~(1<<28);
break;
case ACCESS_R:
ret=copy_to_user((void *)args,kbuf,sizeof(kbuf));
if(ret)
{
printk("to fail\n");
return -EAGAIN;
}
break;
case ACCESS_W:
ret=copy_from_user(kbuf,(void *)args,sizeof(kbuf));
if(ret)
{
printk("to fail\n");
return -EAGAIN;
}
break;
case ACCESS_W:
ret=copy_from_user(kbuf,(void *)args,sizeof(kbuf));
if(ret)
{
printk("from fail\n");
return -EAGAIN;
}
break;
}
return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
const struct file_operations fops=
{
.open=mycdev_open,
// .read=mycdev_read,
// .write=mycdev_write,
.unlocked_ioctl=mycdev_ioctl,
.release=mycdev_close,
};
static int __init mycdev_init(void)
{
//注册字符设备驱动
major=register_chrdev(major,CNAME,&fops);
if(major<0)
{
printk("register char device err\n");
return major;
}
red_base=ioremap(RED_BASE,36);
if(red_base==NULL)
{
printk("red ioremap err\n");
return -ENOMEM;
}
blue_base=ioremap(BLUE_BASE,36);
if(blue_base==NULL)
{
printk("blue ioremap err\n");
return -ENOMEM;
}
green_base=ioremap(GREEN_BASE,36);
if(green_base==NULL)
{
printk("green ioremap err\n");
return -ENOMEM;
}
*red_base &=~(1<<28);
*(red_base+1) |=(1<<28);
*(red_base+9)&=~(3<<24);
*blue_base &=~(1<<12);
*(blue_base+1) |=(1<<12);
*(blue_base+8)&=~(3<<24);
*(blue_base+8) |=(1<<25);
*green_base &=~(1<<13);
*(green_base+1) |=(1<<13);
*(green_base+8)&=~(3<<26);
//自动开设备节点
cls=class_create(THIS_MODULE,CNAME);
if(IS_ERR(cls))
{
printk("FAIL\n");
return PTR_ERR(cls);
}
dev=device_create(cls,NULL,MKDEV(major,0),NULL,CNAME);
if(IS_ERR(cls))
{
printk("FAIL\n");
return PTR_ERR(dev);
}
return 0;
}
static void __exit mycdev_exit(void)
{
device_destroy(cls,MKDEV(major,0));
class_destroy(cls);
iounmap(green_base);
iounmap(blue_base);
iounmap(red_base);
//注销字符设备驱动
unregister_chrdev(major,CNAME);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
———————————————————————————————————————————
1 #ifndef __HEAD_H__
2 #define __HEAD_H__
3 #define type 'a'
4 #define RLED_ON _IO(type,0)
5 #define RLED_OFF _IO(type,1)
6
7 #define ACCESS_R _IOR(type,0,char *)
8 #define ACCESS_W _IOW(type,0,char *)
9
10
11
12
13
14
15
16 #endif
———————————————————————————————————————————
#include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <string.h>
7 #include <sys/ioctl.h>
8 #include "head.h"
9 int main(int argc,const char *argv[])
10 {
11 int fd;
12 char buf[128]="Fuck You bitch";
13 // int a=66;
14 fd=open("/dev/hello",O_RDWR);
15 if(fd==-1)
16 {
17 perror("open err\n");
18 return -1;
19 }
20 while(1)
21 {
22 // write(fd,buf,sizeof(buf));
23 ioctl(fd,RLED_ON);
24 sleep(1);
ioctl(fd,RLED_OFF);
26 sleep(1);
27 ioctl(fd,ACCESS_W,buf);
28 memset(buf,0,sizeof(buf));
29 ioctl(fd,ACCESS_R,buf);
30 printf("%s\n",buf);
31 // buf[0]=buf[0]?0:1;
32 }
43 close(fd);
44 return 0;
45 }
———————————————————————————————————————————
1 #KERNELDIR:=/lib/modules/$(shell uname -r)/build/
2 KERNELDIR:=/opt/source/kernel-3.4.39/
3 PWD:=$(shell pwd)
4 all:
5 make -C $(KERNELDIR) M=$(PWD) modules
6 clean:
7
8 make -C $(KERNELDIR) M=$(PWD) clean
9
10 obj-m:=mydev.o
~