linux字符设备驱动helloword
来源:互联网 发布:app软件开发软件 编辑:程序博客网 时间:2024/05/16 10:23
linux版本 ubuntu12.04LTS
//驱动部分
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/fcntl.h>
#include <linux/vmalloc.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
MODULE_LICENSE("Dual BSD/GPL");
static struct hello_dev{
dev_t devno;
struct cdev cdev;
};
struct hello_dev *hello =NULL;
static int hello_open(struct inode *inode, struct file *file)
{
printk(KERN_ALERT "hello open\n");
return 0;
}
static int hello_close(struct inode *inode, struct file *file)
{
printk(KERN_ALERT "hello close\n");
return 0;
}
static long hello_ioctl(struct file *file,unsigned int cmd, unsigned long arg)
{
int i;
i=cmd;
printk("ioctl in driver::cmd=%d.\n", cmd);
switch(i)
{
case 1:printk("ioctl command1 successfully\n");break;
case 2:printk("ioctl command2 successfully\n");break;
default:
{
printk("ioctl fail\n");
return -1;
}
}
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.unlocked_ioctl = hello_ioctl,
.release = hello_close,
};
static int hello_init(void)
{
int ret;
dev_t devno;
devno=MKDEV(235,0);//静态获得设备号,注意不要和原来的设备号冲突
//ret=alloc_chrdev_region(&devno,0,1,"hello");//动态获得设备号
ret= register_chrdev_region(devno,1,"hello");
if(ret<0)
{
printk(KERN_WARNING "HEHE\n");
return 0;
}
hello = kmalloc(sizeof(struct hello_dev),GFP_KERNEL);
memset(hello,0,sizeof(struct hello_dev));
hello->devno = devno;
cdev_init(&hello->cdev,&dev_fops);//把获得的设备号与驱动的方法关联起来
hello->cdev.owner = THIS_MODULE;
ret =cdev_add(&hello->cdev,devno,1);//这句我的理解是,把设备号与驱动方法关联到内核中
if(ret)
{
printk(KERN_NOTICE "Error %d.\n",ret);
return 0;
}
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
dev_t devno =hello->devno;
cdev_del(&hello->cdev);
if(hello)
{
kfree(hello);
}
unregister_chrdev_region(devno,1);
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
下面是调试代码:就是调试一下驱动写的方法有没有实现。
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<linux/rtc.h>
#include<linux/ioctl.h>
#include<stdio.h>
#include<stdlib.h>
#define TEXT 2
int main()
{
int fd;
int i;
unsigned int j;
int retval;
fd=open("/dev/hello",O_RDWR);
if(fd==-1)
{
perror("error open\n");
exit(-1);
}
printf("open success\n");
j=1;
retval=ioctl(fd,j,0);
if(retval==-1)
{
perror("ioctl error\n");
exit(-1);
}
printf("send command1 successfully\n");
retval=ioctl(fd,2,0);
if(retval==-1)
{
perror("ioctl error\n");
exit(-1);
}
printf("send command2 successfully\n");
close(fd);
}
在本机调试,驱动的makefile如下:
ifneq ($(KERNELRELEASE),)
obj-m += char_hello.o //这个与你的文件名有关
else
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
endif
加载驱动,首先要编译生成.ko文件
insmod char_hello.ko
通过lsmod就能看到加载了内核 或者 dmesg | tail -10可以看到加载了驱动中_init函数printk的信息
然后用mknod -m 0666(权限) /dev/hello c 235 0 //c代表字符设备 235 是主设备号,0是此设备号 这里我用了静态指定设备号,如果用动态的话,就先在终端执行cat /proc/devices查看
删除驱动就用rmmod char_hello
测试程序直接用gcc编译执行就行了。
编者在学习期间遇到一个奇怪的问题,在PC机测试过程中,驱动中的ioctl函数里面,当驱动收到cmd=2的话,是不会进入函数体的,终端会显示地址错误的提示,编者更改测试程序中传的值,尝试过10个左右不同的数字,除了“2”,其他都是正常的。编者忽略这个问题,直接把代码移植到开发板上。发觉丝毫没有问题。
我和我的小伙伴都惊呆了。
这问题,编者一直没想出个所以然。
- linux字符设备驱动helloword
- LINUX--字符设备驱动
- Linux字符设备驱动
- Linux字符设备驱动
- Linux字符设备驱动
- linux字符设备驱动
- linux字符设备驱动
- linux 字符设备驱动
- linux字符设备驱动
- linux 字符设备驱动
- Linux字符设备驱动
- linux字符设备驱动
- Linux字符设备驱动
- linux 字符设备驱动
- Linux字符设备驱动
- linux字符设备驱动
- Linux字符设备驱动
- Linux字符设备驱动
- SQL 优化
- pat:1011<advanced> <World Cup>
- 理解Load Average做好压力测试
- Linux shell的算术运算
- MySQL存储引擎--MyISAM与InnoDB区别
- linux字符设备驱动helloword
- 黑马程序员-第七天(内部类)
- Debian7, ubuntu 13.10下配置Bugzilla
- jQuery.extend 函数详解
- 67.windbg-!thread、.thread(内核)
- 九度:1015<A+B>
- Unix同步+互斥量
- 网络编程
- 压力测试衡量CPU的三个指标:CPU Utilization、Load Average和Context Switch Rate .