今天我終於找到組織了
时间:2011-01-21
来源:互联网
RT
这代码我写挺久了,今天拿来测试不成功
当然以前写的时候测试是成功的,不过是在我同学的笔记本上编写和测试的
现在回到家是用家里的电脑测试,ubuntu是8.04的
谁帮我测试下有什么问题,谢谢了
mydev.c
main.c
编译:
make
gcc main.c -o main
插入模块:
sudo insmod mydev.ko
删除模块:
sudo rmmod mydev.ko
查看模块:
lsmod
测试:
./main
查看内核输出:
dmesg
如果成功的话会看到输出读取和写入多少数据的
这代码我写挺久了,今天拿来测试不成功
当然以前写的时候测试是成功的,不过是在我同学的笔记本上编写和测试的
现在回到家是用家里的电脑测试,ubuntu是8.04的
谁帮我测试下有什么问题,谢谢了
mydev.c
代码:
/***************************************************************************
* mydev.c
* -------------------
* 版本号 : v1.0
* 原始作者 : 天使之翼
* 创建时间 : 2009-8-16
* 文件说明 : 设备驱动的处理程序
* 实现功能 : 设备驱动的加载,卸载,打开,释放,读写,控制,定位
* 修改列表 :
*
***************************************************************************/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define BUF_SIZE 0x1000 //缓冲区大小
#define CLEAR_BUF 0x1 //清空缓冲区
#define MYDEV_NAME "mydev" //设备名
#define MYDEV_MAJOR 240 //主设备号
static int mydev_major = MYDEV_MAJOR;
//自定义的设备结构体
typedef struct mydev
{
struct cdev cdev;
unsigned char buf[BUF_SIZE];
}MYDEV;
MYDEV *p_mydev;
/***************************************************************************
功能: 打开设备
参数: 设备节点指针, 设备文件结构体指针
返回值: 0 成功
非0 失败
***************************************************************************/
int mydev_open(struct inode *inode, struct file *filp)
{
filp->private_data = p_mydev; //将自定义设备结构体指针赋给文件私有数据指针
return 0;
}
/***************************************************************************
功能: 释放设备
参数: 设备节点指针, 设备文件结构体指针
返回值: 0 成功
非0 失败
***************************************************************************/
int mydev_release(struct inode *inode, struct file *filp)
{
return 0;
}
/***************************************************************************
功能: 控制设备
参数: 设备节点指针, 设备文件结构体指针, 控制命令, 用户空间传递的自定义的数据
返回值: 0 成功
非0 失败
***************************************************************************/
static int mydev_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
MYDEV *p_mydev = filp->private_data;
switch(cmd)
{
case CLEAR_BUF:
memset(p_mydev->buf, 0, BUF_SIZE);
printk(KERN_INFO "buf is set to zero\n");
break;
default:
return -EINVAL;
}
return 0;
}
/***************************************************************************
功能: 读设备
参数: 设备文件结构体指针, 用户空间传递的缓冲区指针, 读取的字节数, 当前读写位置
返回值: 读取的字节数 成功
错误值 失败
***************************************************************************/
static ssize_t mydev_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
MYDEV *p_mydev = filp->private_data;
if(p >= BUF_SIZE)
{
return count ? -ENXIO : 0;
}
if(count > BUF_SIZE - p)
{
count = BUF_SIZE - p;
}
if(copy_to_user(buf, (void *)(p_mydev->buf + p), count))
{
ret = -EFAULT;
}
else
{
*ppos += count;
ret = count;
printk(KERN_INFO "read %d bytes(s) from %ld\n", count, p);
}
return ret;
}
/***************************************************************************
功能: 写设备
参数: 设备文件结构体指针, 用户空间传递的缓冲区指针, 写入的字节数, 当前读写位置
返回值: 写入的字节数 成功
错误值 失败
***************************************************************************/
static ssize_t mydev_write(struct file *filp, const char __user *buf,
size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
MYDEV *p_mydev = filp->private_data;
if(p >= BUF_SIZE)
{
return count ? -ENXIO : 0;
}
if(count > BUF_SIZE - p)
{
count = BUF_SIZE - p;
}
if(copy_from_user(p_mydev->buf + p, buf, count))
{
ret = -EFAULT;
}
else
{
*ppos += count;
ret = count;
printk(KERN_INFO "written %d bytes(s) from %ld\n", count , p);
}
return ret;
}
/***************************************************************************
功能: 定位
参数: 设备文件结构体指针, 偏移量, 何处移动
返回值: 当前读写位置 成功
错误值 失败
***************************************************************************/
static loff_t mydev_llseek(struct file *filp, loff_t offset, int whence)
{
loff_t ret = 0;
switch(whence)
{
case 0:
if(offset < 0)
{
ret = -EINVAL;
break;
}
if((unsigned int)offset > BUF_SIZE)
{
ret = -EINVAL;
break;
}
filp->f_pos = (unsigned int)offset;
ret = filp->f_pos;
break;
case 1:
if((filp->f_pos + offset) > BUF_SIZE)
{
ret = -EINVAL;
break;
}
if((filp->f_pos + offset) < 0)
{
ret = -EINVAL;
break;
}
filp->f_pos += offset;
ret = filp->f_pos;
break;
}
return ret;
}
//文件操作结构体
static struct file_operations mydev_fops =
{
.owner = THIS_MODULE,
.open = mydev_open,
.release = mydev_release,
.read = mydev_read,
.write = mydev_write,
.ioctl = mydev_ioctl,
.llseek = mydev_llseek,
};
/***************************************************************************
功能: 初始化并注册cdev
参数: 自定义的设备结构体指针, 次设备号
返回值: 无
***************************************************************************/
static void mydev_setup_cdev(MYDEV *p_mydev, int index)
{
dev_t devno;
int errno;
devno = MKDEV(mydev_major, index);
cdev_init(&p_mydev->cdev, &mydev_fops);
p_mydev->cdev.owner = THIS_MODULE;
p_mydev->cdev.ops = &mydev_fops;
errno = cdev_add(&p_mydev->cdev, devno, 1); //注册cdev
if(errno)
{
printk(KERN_INFO "Error %d adding LED %d\n", errno, index);
}
}
/***************************************************************************
功能: 加载设备驱动模块
参数: 无
返回值: 0 成功
非0 失败
***************************************************************************/
int mydev_init(void)
{
int ret;
dev_t devno;
devno = MKDEV(mydev_major, 0);
if(mydev_major)
{
ret = register_chrdev_region(devno, 1, MYDEV_NAME); //申请设备号
}
else
{
ret = alloc_chrdev_region(&devno, 0, 1, MYDEV_NAME); //动态申请设备号
mydev_major = MAJOR(devno);
}
if(ret < 0)
{
return ret;
}
p_mydev = kmalloc(sizeof(MYDEV), GFP_KERNEL);
if(!p_mydev)
{
ret = -ENOMEM;
goto fail_malloc;
}
memset(p_mydev, 0, sizeof(MYDEV));
mydev_setup_cdev(p_mydev, 0);
return 0;
fail_malloc:
unregister_chrdev_region(devno, 1);
return ret;
}
/***************************************************************************
功能: 卸载设备驱动模块
参数: 无
返回值: 无
***************************************************************************/
void mydev_exit(void)
{
cdev_del(&p_mydev->cdev); //注销cdev
kfree(p_mydev); //释放自定义设备结构体
unregister_chrdev_region(MKDEV(mydev_major, 0), 1); //释放设备号
}
module_init(mydev_init);
module_exit(mydev_exit);
MODULE_AUTHOR("Xie HoneYong");
MODULE_LICENSE("Dual BSD/GPL");
* mydev.c
* -------------------
* 版本号 : v1.0
* 原始作者 : 天使之翼
* 创建时间 : 2009-8-16
* 文件说明 : 设备驱动的处理程序
* 实现功能 : 设备驱动的加载,卸载,打开,释放,读写,控制,定位
* 修改列表 :
*
***************************************************************************/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define BUF_SIZE 0x1000 //缓冲区大小
#define CLEAR_BUF 0x1 //清空缓冲区
#define MYDEV_NAME "mydev" //设备名
#define MYDEV_MAJOR 240 //主设备号
static int mydev_major = MYDEV_MAJOR;
//自定义的设备结构体
typedef struct mydev
{
struct cdev cdev;
unsigned char buf[BUF_SIZE];
}MYDEV;
MYDEV *p_mydev;
/***************************************************************************
功能: 打开设备
参数: 设备节点指针, 设备文件结构体指针
返回值: 0 成功
非0 失败
***************************************************************************/
int mydev_open(struct inode *inode, struct file *filp)
{
filp->private_data = p_mydev; //将自定义设备结构体指针赋给文件私有数据指针
return 0;
}
/***************************************************************************
功能: 释放设备
参数: 设备节点指针, 设备文件结构体指针
返回值: 0 成功
非0 失败
***************************************************************************/
int mydev_release(struct inode *inode, struct file *filp)
{
return 0;
}
/***************************************************************************
功能: 控制设备
参数: 设备节点指针, 设备文件结构体指针, 控制命令, 用户空间传递的自定义的数据
返回值: 0 成功
非0 失败
***************************************************************************/
static int mydev_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
MYDEV *p_mydev = filp->private_data;
switch(cmd)
{
case CLEAR_BUF:
memset(p_mydev->buf, 0, BUF_SIZE);
printk(KERN_INFO "buf is set to zero\n");
break;
default:
return -EINVAL;
}
return 0;
}
/***************************************************************************
功能: 读设备
参数: 设备文件结构体指针, 用户空间传递的缓冲区指针, 读取的字节数, 当前读写位置
返回值: 读取的字节数 成功
错误值 失败
***************************************************************************/
static ssize_t mydev_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
MYDEV *p_mydev = filp->private_data;
if(p >= BUF_SIZE)
{
return count ? -ENXIO : 0;
}
if(count > BUF_SIZE - p)
{
count = BUF_SIZE - p;
}
if(copy_to_user(buf, (void *)(p_mydev->buf + p), count))
{
ret = -EFAULT;
}
else
{
*ppos += count;
ret = count;
printk(KERN_INFO "read %d bytes(s) from %ld\n", count, p);
}
return ret;
}
/***************************************************************************
功能: 写设备
参数: 设备文件结构体指针, 用户空间传递的缓冲区指针, 写入的字节数, 当前读写位置
返回值: 写入的字节数 成功
错误值 失败
***************************************************************************/
static ssize_t mydev_write(struct file *filp, const char __user *buf,
size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
MYDEV *p_mydev = filp->private_data;
if(p >= BUF_SIZE)
{
return count ? -ENXIO : 0;
}
if(count > BUF_SIZE - p)
{
count = BUF_SIZE - p;
}
if(copy_from_user(p_mydev->buf + p, buf, count))
{
ret = -EFAULT;
}
else
{
*ppos += count;
ret = count;
printk(KERN_INFO "written %d bytes(s) from %ld\n", count , p);
}
return ret;
}
/***************************************************************************
功能: 定位
参数: 设备文件结构体指针, 偏移量, 何处移动
返回值: 当前读写位置 成功
错误值 失败
***************************************************************************/
static loff_t mydev_llseek(struct file *filp, loff_t offset, int whence)
{
loff_t ret = 0;
switch(whence)
{
case 0:
if(offset < 0)
{
ret = -EINVAL;
break;
}
if((unsigned int)offset > BUF_SIZE)
{
ret = -EINVAL;
break;
}
filp->f_pos = (unsigned int)offset;
ret = filp->f_pos;
break;
case 1:
if((filp->f_pos + offset) > BUF_SIZE)
{
ret = -EINVAL;
break;
}
if((filp->f_pos + offset) < 0)
{
ret = -EINVAL;
break;
}
filp->f_pos += offset;
ret = filp->f_pos;
break;
}
return ret;
}
//文件操作结构体
static struct file_operations mydev_fops =
{
.owner = THIS_MODULE,
.open = mydev_open,
.release = mydev_release,
.read = mydev_read,
.write = mydev_write,
.ioctl = mydev_ioctl,
.llseek = mydev_llseek,
};
/***************************************************************************
功能: 初始化并注册cdev
参数: 自定义的设备结构体指针, 次设备号
返回值: 无
***************************************************************************/
static void mydev_setup_cdev(MYDEV *p_mydev, int index)
{
dev_t devno;
int errno;
devno = MKDEV(mydev_major, index);
cdev_init(&p_mydev->cdev, &mydev_fops);
p_mydev->cdev.owner = THIS_MODULE;
p_mydev->cdev.ops = &mydev_fops;
errno = cdev_add(&p_mydev->cdev, devno, 1); //注册cdev
if(errno)
{
printk(KERN_INFO "Error %d adding LED %d\n", errno, index);
}
}
/***************************************************************************
功能: 加载设备驱动模块
参数: 无
返回值: 0 成功
非0 失败
***************************************************************************/
int mydev_init(void)
{
int ret;
dev_t devno;
devno = MKDEV(mydev_major, 0);
if(mydev_major)
{
ret = register_chrdev_region(devno, 1, MYDEV_NAME); //申请设备号
}
else
{
ret = alloc_chrdev_region(&devno, 0, 1, MYDEV_NAME); //动态申请设备号
mydev_major = MAJOR(devno);
}
if(ret < 0)
{
return ret;
}
p_mydev = kmalloc(sizeof(MYDEV), GFP_KERNEL);
if(!p_mydev)
{
ret = -ENOMEM;
goto fail_malloc;
}
memset(p_mydev, 0, sizeof(MYDEV));
mydev_setup_cdev(p_mydev, 0);
return 0;
fail_malloc:
unregister_chrdev_region(devno, 1);
return ret;
}
/***************************************************************************
功能: 卸载设备驱动模块
参数: 无
返回值: 无
***************************************************************************/
void mydev_exit(void)
{
cdev_del(&p_mydev->cdev); //注销cdev
kfree(p_mydev); //释放自定义设备结构体
unregister_chrdev_region(MKDEV(mydev_major, 0), 1); //释放设备号
}
module_init(mydev_init);
module_exit(mydev_exit);
MODULE_AUTHOR("Xie HoneYong");
MODULE_LICENSE("Dual BSD/GPL");
main.c
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#define CLEAR_BUF 0x1 //清空缓冲区
#define DEVICE_FILENAME "/dev/mydev"
int main(void)
{
int handle;
char buf[128] = "Hello World!";
handle = open(DEVICE_FILENAME, O_RDWR | O_NDELAY);
printf("handle = %d\n", handle);
if(handle < 0)
{
printf("open mydev device failure!\n");
}
else
{
printf("open mydev device successful!\n");
printf("buf = %s\n", buf);
write(handle, buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
lseek(handle, 0, SEEK_SET);
read(handle, buf, sizeof(buf));
printf("buf = %s\n", buf);
ioctl(handle, CLEAR_BUF, 0);
lseek(handle, 0, SEEK_SET);
memset(buf, 0, sizeof(buf));
read(handle, buf, sizeof(buf));
printf("buf = %s\n", buf);
}
return 0;
}
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#define CLEAR_BUF 0x1 //清空缓冲区
#define DEVICE_FILENAME "/dev/mydev"
int main(void)
{
int handle;
char buf[128] = "Hello World!";
handle = open(DEVICE_FILENAME, O_RDWR | O_NDELAY);
printf("handle = %d\n", handle);
if(handle < 0)
{
printf("open mydev device failure!\n");
}
else
{
printf("open mydev device successful!\n");
printf("buf = %s\n", buf);
write(handle, buf, sizeof(buf));
memset(buf, 0, sizeof(buf));
lseek(handle, 0, SEEK_SET);
read(handle, buf, sizeof(buf));
printf("buf = %s\n", buf);
ioctl(handle, CLEAR_BUF, 0);
lseek(handle, 0, SEEK_SET);
memset(buf, 0, sizeof(buf));
read(handle, buf, sizeof(buf));
printf("buf = %s\n", buf);
}
return 0;
}
编译:
make
gcc main.c -o main
插入模块:
sudo insmod mydev.ko
删除模块:
sudo rmmod mydev.ko
查看模块:
lsmod
测试:
./main
查看内核输出:
dmesg
如果成功的话会看到输出读取和写入多少数据的
作者: 天使ッ翼 发布时间: 2011-01-21
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28