频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

内核入门:较为基础的Linux系统设备驱动

来源: 作者:佚名 出处:巧巧读书 2007-12-12 进入讨论组

  驱动程序为:
 
  

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
static unsigned int major = 0;
static unsigned int minor = 0;
static unsigned int devno;
static char *filename = "mydevice";
static struct cdev *mycdev = NULL;
static int mycdevflg = 0;
static int devnoflg = 0;
static int adddevflg = 0;
MODULE_LICENSE("Dual BSD/GPL");
static int myopen(struct inode *inodep, struct file *flipl)
{ 
printk("my open is run\n");
return 0;
}
static ssize_t myread(struct file *flip, char __user *buf, size_t size, loff_t offset)
{
printk("myread is ok!\n");
static int i = 0;
///copy_to_user(buf,from,size);
*buf = i++;
return 0;
}
static int myrelease(struct inode *myindoe, struct file *flip)
{
printk("myrelease is run.\n");
return 0;
}
static struct file_operations myfops =
{
.owner = THIS_MODULE,
.open = myopen,
.read = myread,
.release= myrelease,
};
/* 初始化设备的过程主要是三步:1,生成设备号;2初始化设备;3,添加到内核。
*/
static int __init myinit(void)
{
int result = -1;
if(major)
{
devno = MKDEV(major,minor); //生成设备号
result = register_chrdev_region(devno,1,filename);//注册设备号devno,1为设备的个数
devnoflg = 1;
}
else
{
result = alloc_chrdev_region(&devno,minor,1,filename);//生成设备号兵注册,
mior为次设备号,这里注意的是指针devno?
major = MAJOR(devno);
devnoflg = 1;
}
if(result < 0)
{
printk("can't register the major num!\n");
devnoflg = 0;
return -1;
}
//mycdev = kmalloc(sizeof(struct cdev),GFP_KERNEL);
//如果采用cdev_init(struct cdev*,struct file *)方式的话,这个才需要。
mycdev = cdev_alloc();//申请cdev内存兵初始化设备cdev,不能在这之前申请内存,
否则要释放两次!
if(NULL == mycdev)
{
printk("can't request the memory!\n");
}
mycdevflg = 1;
//memset(mycdev,0,sizeof(mycdev));
mycdev->owner = THIS_MODULE;//如果采用cdev_init(struct cdev*,struct file *)方式的话,
这两项可以去掉
mycdev->ops = &myfops;//如果采用cdev_init(struct cdev*,struct file *)方式的话,
这两项可以去掉
result = cdev_add(mycdev,devno,1);//设备和设备号联系起来,
即通常说的添加设备到内核
if(result < 0)
{
printk("can't add cdev.2\n");
adddevflg = 0;
}
else
{
adddevflg = 1;
}
return 0;
}
/* 以和设备注册的次序"卸载",注意有的时候,当出错的时候,要注意是否用到这些操作,
所以要加上判断,否则比如对空指针free会导致系统崩溃!
*/
static void myexit(void)
{
printk("myexit begin.\n");
if(adddevflg) 
{
cdev_del(mycdev);
adddevflg = 0;
}
if(mycdev) 
{
kfree(mycdev);
mycdev = NULL;
}
if(devnoflg)
{
unregister_chrdev_region(devno,1);
devno = 0;
devnoflg = 0;
}
printk("exit over.\n");
}
module_init(myinit);
module_exit(myexit);


 
  应用程序为:
 
  

#include 
#include 
#include 
#include 
#include 
int main() 
{ 
int fd; 
int i=0; 
fd = open("/dev/mydevice", O_RDONLY); 
if (fd < 0) 
{ 
printf("error1\n"); 
return -1; 
} 
int j = 0;
while(j++<10000)
{
if (read(fd, &i, sizeof(int)) < 0) 
{ 
printf("read error2\n"); 
return -1; 
} 
printf("i = %d\n",i);
}
close("/dev/mydevice");
return 0; 
}


 
  一定要注意register_chrdev_region(),alloc_chrdev_region(),cdev_init(),cdev_alloc(),cdev_add()这些函数的参数类型,不要把指针当成非指针,把int类型当作指针(或者&)来使用!正文:http://www.qqread.com/linux/2007/12/o385974.html 更多文章 更多内容请看系统优化大全系统安全设置系统安装手册专题,或进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章