视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
linux设备驱动程序的编写
2024-12-27 23:52:46 责编:小OO
文档


系统大全为您提供
 先介绍下我的环境,用的ubuntu发行版,kernel版本是3.8.0,《Linux设备驱动程序》一书是针对2.6.0的kernel,在这个例子中会看到一些差异。这个例子要实现的目标是,编译装载该module后,通过udev动态的生成设备节点star0,读取设备节点cat /dev/star0可以打印出星号,星号的数量可以由模块参数动态的指定。以下为源代码:
star.h
#ifndef STAR_H_H_H
#define STAR_H_H_H
#define AUTHOR "Tao Yang"
#define DESCRIPTION "A CHAR DEVICE DIRVERS SAMPLE USING UDEV"
#define VERSION "0.1"
#endif
star.c
//module_init module_exit
#include
#include
//module_param
#include
//printk container_of
#include
//dev_t MAJOR MInor MKDEV
#include
//file_operations file register/unregister_chrdev_region alloc_chrdev_region register/unregister_chrdev(old)
#include
/
ev cdev_init/add/del
#include
//copy_from_user copy_to_user
#include
#include
#include "star.h"
//define device number
#define STAR_MAJOR 0
#define STAR_MInor 0
#define STAR_DEVS 1
#define DEVICE_NAME "star0"
#define CLASS_NAME "star"
static int howmany=5;
module_param(howmany,int,S_IRUGO);
//module info
MODULE_AUTHOR(AUTHOR);
MODULE_DESCRIPTION(DESCRIPTION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
//device variables
static struct class* star_class=NULL;
static struct device* star_sysdevice=NULL;
int star_major=STAR_MAJOR;
int star_minor=STAR_MInor;
int star_nr_devs=STAR_DEVS;
//device struct
static struct star_dev {
char *data;
struct cdev cdev;
};
static struct star_dev star_device;
static ssize_t star_read(struct file * filp,char * buf,size_t count,loff_t *ppos)
{
int i;
char star_str[10000];
struct star_dev *dev=filp->private_data;
for (i=0;i
star_str[i]='*';
}
star_str[howmany]='
';
int len=strlen(star_str);
if(count
return -EINVAL;
if(*ppos!=0)
return 0;
if(copy_to_user(buf,star_str,len))
return -EINVAL;
*ppos=len;
return len;
}
int star_open(struct inode *inode,struct file *filp)
{
struct star_dev *dev;
dev=container_of(inode->i_cdev,struct star_dev,cdev);
filp->private_data=dev;
//......
return 0;
}
//file operations
static const struct file_operations star_fops = {
.owner = THIS_MODULE,
.read = star_read,
.open = star_open,
};
static void star_setup_cdev(struct star_dev *dev,int index)
{
int err,devno=MKDEV(star_major,star_minor+index);
printk(KERN_ALERT "setup cdev...
");
cdev_init(&dev->cdev,&star_fops);
dev->cdev.owner=THIS_MODULE;
dev->cdev.ops=&star_fops;
err=cdev_add(&dev->cdev,devno,1);
if(err)
printk(KERN_ALERT "Error %d adding star%d",err,index);
}
static int __init star_init(void)
{
int ret;
dev_t dev;
printk(KERN_ALERT "hello tom!
");
if(star_major){
dev=MKDEV(star_major,star_minor);
ret=register_chrdev_region(dev,star_nr_devs,DEVICE_NAME);
printk(KERN_ALERT "static!
");
}else{
ret=alloc_chrdev_region(&dev,star_minor,star_nr_devs,DEVICE_NAME);
star_major=MAJOR(dev);
printk(KERN_ALERT "dynamic!
");
printk(KERN_ALERT "Device Major is %d!
",star_major);
}
if(ret<0){
printk(KERN_ALERT "star:can't get major %d
",star_major);
return ret;
}
printk(KERN_ALERT "set up cdev!");
star_setup_cdev(&star_device,0);
star_class=class_create(THIS_MODULE,CLASS_NAME);
if(IS_ERR(star_class)){
printk(KERN_ALERT "Failed to register device class '%s'
",CLASS_NAME);
}
//with a class ,the easiest way to instantiate a device is to call device_create()
star_sysdevice=device_create(star_class,NULL,MKDEV(star_major,0),NULL,DEVICE_NAME);
return 0;
}
static void __exit star_exit(void)
{
device_destroy(star_class,MKDEV(star_major,star_minor));
class_unregister(star_class);
class_destroy(star_class);
cdev_del(&star_device.cdev);
printk(KERN_ALERT "goodbye...
");
}
module_init(star_init);
module_exit(star_exit);
Makefile
ifneq ($(KERNELRELEASE),)
obj-m:=star.o
else
KERNELDIR ?= 
b/modules/$(shell uname -r)
ild
PWD :=$(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
编译源代码:
root@ubuntu:~/embedded_linux/ldd3/practice# make
make -C 
b/modules/3.8.0-29-generic
ild M=/home/tom/embedded_linux/ldd3/practice modules
make[1]: Entering directory `/usr
c
nux-headers-3.8.0-29-generic'
CC [M] /home/tom/embedded_linux/ldd3/practice/star.o
/home/tom/embedded_linux/ldd3/practice/star.c:58:1: warning: useless storage class specifier in empty declaration [enabled by default]
/home/tom/embedded_linux/ldd3/practice/star.c: In function ‘star_read’:
/home/tom/embedded_linux/ldd3/practice/star.c:72:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
/home/tom/embedded_linux/ldd3/practice/star.c:66:22: warning: unused variable ‘dev’ [-Wunused-variable]
/home/tom/embedded_linux/ldd3/practice/star.c:81:1: warning: the frame size of 10032 bytes is larger than 1024 bytes [-Wframe-larger-than=]
Building modules, stage 2.
MODPOST 1 modules
CC /home/tom/embedded_linux/ldd3/practice/star.mod.o
LD [M] /home/tom/embedded_linux/ldd3/practice/star.ko
make[1]: Leaving directory `/usr
c
nux-headers-3.8.0-29-generic'
root@ubuntu:~/embedded_linux/ldd3/practice#
安装驱动模块:
root@ubuntu:~/embedded_linux/ldd3/practice# insmod star.ko
root@ubuntu:~/embedded_linux/ldd3/practice# dmesg -c
[ 3946.696548] hello tom!
[ 3946.6992] dynamic!
[ 3946.6994] Device Major is 249!
[ 3946.6995] set up cdev!
 
[3946.6996]setupcdev...
root@ubuntu:~/embedded_linux/ldd3/practice#
这时可以看到/dev/目录下自动生成了设备节点:
root@ubuntu:~/embedded_linux/ldd3/practice#ls-l/dev/star0
crw-------1rootroot249,0Feb814:25/dev/star0
root@ubuntu:~/embedded_linux/ldd3/practice#
接下来去读取设备节点:
root@ubuntu:~/embedded_linux/ldd3/practice#cat/dev/star0
*****
在加载驱动模块时,传递参数,也就是指定打印出星号的个数:
root@ubuntu:~/embedded_linux/ldd3/practice#insmodstar.kohowmany=10
root@ubuntu:~/embedded_linux/ldd3/practice#cat/dev/star0
**********
root@ubuntu:~/embedded_linux/ldd3/practice#
最后,以上是我在学习过程中写的一个精简的例子,因此很多技巧及错误处理都没有注意,主要是为了勾勒出linux设备驱动程序的宏观骨架,自己最好能通过读代码总结画出一个流程图,加深印象,代码也是配合着ldd3写的,希望能对正在读这本著作的初学者有所帮助。
  以上就是系统大全给大家介绍的如何使的方法都有一定的了解了吧,好了,如果大家还想了解更多的资讯,那就赶紧点击系统大全官网吧。 
 
本文来自系统大全http:///如需转载请注明!推荐:win7纯净版

下载本文
显示全文
专题