如何编写Ubuntu字符驱动


如何 编写Ubuntu字符驱动

//////////////////////////////////////////////////////////////

1、随便在一个目录下,新建一个目录叫 chardev ,
再在此目录下新建三个文件分别叫 Makefile chardev.c main.c
2、把如下的内容分别写入到三个文件中
3、打开终端 使用 su 命令,切换到 super user 身份,然后写位到 chardev 目录下
4、输入 make 命令,编译 驱动程序 chardev.c
5、输入 gcc main.c 命令,编译 测试程序
6、输入 insmod chardev.ko 加载驱动模块
7、输入 gedit /proc/devices 查看 chardev 驱动模块的主设备号
8、输入 mknod /dev/chardev c 250 0 在/dev/目录下,创建设备 chardev
其中,c代码字符驱动,250是驱动主设备号,0是次设备号。次设备号一般都为0
9、输入 ./a.out 运行测试程序
10、测试程序退出后,输入 rmmod chardev 卸载 驱动模块
11、输入 rm -rf /dev/chardev 删除 /dev/目录下的 chardev 设备

//////////////////////////////////////////////////////////////

#Makefile
#make -C $(KDIR) M=$(SRCPWD) modules此语句前必须要一个Tab键
#rm -rf chardev.o此语句前必须要一个Tab键
#//////////////////////////////////////////////////////////////

obj-m:=chardev.o
KDIR:=/lib/modules/$(shell uname -r)/build
SRCPWD:=$(shell pwd)
all:
make -C $(KDIR) M=$(SRCPWD) modules
clean:
rm -rf chardev.o
#//////////////////////////////////////////////////////////////


//chardev.c
//////////////////////////////////////////////////////////////

#include <linux/kernel.h>
#include <linux/fs.h>                 
#include <linux/module.h>
#include <asm/uaccess.h>              
#include <linux/cdev.h>                

//////////////////////////////////////////////////////////////

static int char_read(struct file *filp,char __user *buffer,size_t,loff_t *);       
static int char_open(struct inode *,struct file *);                                     
static int char_write(struct file *filp,const char __user *buffer,size_t ,loff_t*);
static int char_release(struct inode *,struct file *);                                  

//////////////////////////////////////////////////////////////

//static int device_open_count;                    
static int major;

//////////////////////////////////////////////////////////////

static const struct file_operations file_ops = {
.read = char_read,
.write = char_write,
.open = char_open,
.release = char_release,
};

static int __init char_init(void)

int value;
major = 0;
value = register_chrdev(major, "chardev", &file_ops);
if (value < 0) {
printk("register dev failed!\n");
return value;
}
if (major == 0) 
major = value;
return 0;
}

static int char_open(struct inode *inode,struct file *file)
{
//  if(device_open_count == 0)
//    device_open_count++;
//  else{
//     printk("设备已经被打开\n");
//     return -1;
//  }
try_module_get(THIS_MODULE);

return 0;
}

static int char_release(struct inode *inode,struct file *file)
{
//    device_open_count--;
module_put(THIS_MODULE);
return 0;
}

static int char_read(struct file *filp,char __user *buffer,size_t length,loff_t *offset)

if(length < 0)
return -1;
else if(length > 12)
length = 12;

if(0 == copy_to_user(buffer,"Hello Linux!",length))
return length;
return -1;
}

static int char_write(struct file *filp,const char __user  *buffer,size_t length,loff_t *offset)
{
return 0;
}

static void __exit module_close(void)
{
unregister_chrdev(major, "chardev");
}

//////////////////////////////////////////////////////////////

module_init(char_init);
module_exit(module_close);

//////////////////////////////////////////////////////////////

 

//main.c
///////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

///////////////////////////////////////////////////////////

int main(void)
{
char ch = 0;
int testdev;
int i,rf=0;
char buf[15];

memset(buf, 0, sizeof(buf));
testdev = open("/dev/chardev",O_RDWR);
if ( testdev == -1 )
{
perror("open error!\n");
exit(0);
}

while ('q' != ch)
{
rf=read(testdev,buf,11);
if(rf<0)
{
printf("read error[%d]!\n",rf);
}
else
{
printf("R:%s\n",buf);
}
scanf("%c",&ch);
}
close(testdev);

return 0;
}

///////////////////////////////////////////////////////////

相关内容