分类: 嵌入式
2010-08-10 11:18:18
完成一个驱动实验。实现的功能是在内存中开辟一段空间,write实现了往这段内中写数据,read正好相反,是从这段内存中读出数据。
步骤:
1编写驱动函数,测试函数。并进行编译。
编译驱动时候命令为:
gcc -DMODULE -D__KERNEL__ -I /usr/src/linux-
2 加载驱动模块。
命令:insmod module.o
3 在/dev目录下创建设备节点。
命令:mknod /dev/module c 254 0
4 为了测试加载的设备能否正常使用,编写了read,write函数测试。
由截图可以看出write函数向缓冲写入26个英文字符,又通过read函数成功读取。验证了设备的可用性。
5 使用结束,卸载设备。
命令:rmmod module
源代码来自辛军:
1 module.c
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
unsigned int test_major = 254; //设备号
char *str_test; //存放内存空间的指针
unsigned int count_driver; //当前内存中拥有的数据的字节数
const unsigned int count_driver_max=255; //容量的最大值
static int open_test(struct inode *inode,struct file *file)
{
MOD_INC_USE_COUNT;
return 0;
}
static int release_test(struct inode *inode,struct file *file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t write_test(struct file *file,const char *buf,size_t count,loff_t *t)
{
int result;
if(count
{
if((result=copy_from_user(str_test,buf,count))==0)
count_driver=count;
else
count_driver=0;
}
else
{
if((result=copy_from_user(str_test,buf,count_driver_max))==0)
count_driver=count_driver_max;
else
count_driver=0;
}
return count_driver;
}
static ssize_t read_test(struct file *file,char *buf, size_t count,loff_t *t )
{
int result,read_num;
if(access_ok(VERIFY_WRITE,buf,count) == -EFAULT)
return -EFAULT;
printk("read start!\n");
if(count_driver>0)
{
if(count_driver>=count)
{
if((result=copy_to_user(buf,str_test,count))==0)
read_num=count;
else
read_num=0;
}
else
{
if((result=copy_to_user(buf,str_test,count_driver))==0)
read_num=count_driver;
else
read_num=0;
}
}
else
read_num=0;
return read_num;
}
struct file_operations test_fops={
read:read_test,
write:write_test,
open:open_test,
release:release_test,
};
static int test_init_module(void)
{
int result;
result = register_chrdev(test_major,"test",&test_fops);
if(result < 0)
{
printk(KERN_INFO"test:can't get major number\n");
return result;
}
printk("register ok\n");
if((str_test=(char*)kmalloc(256,GFP_KERNEL))==NULL) //申请256字节的内存空间
{
printk("kmalloc error\n");
return -1;
}
else
{
printk("kamlloc success!\n");
count_driver = 0;
}
return 0;
}
static void test_exit_module( void )
{
unregister_chrdev( test_major, "test");
printk(KERN_ALERT "test_exit:OK! \n");
}
module_init(test_init_module);
module_exit(test_exit_module);
2 test_write.c
#include
#include
#include
#include
int main(void)
{
int i;
int testdev;
int result=2,resultr;
char buf[27]={'\0'};
testdev = open("/dev/module",O_RDWR);
if(testdev < 0)
{
printf("Cann't open file\n");
return 1;
}
printf("open ok\n");
buf[0]='a';
for(i=1;i<26;i++)
buf[i]=buf[0]+i;
if((result=write(testdev,buf,26)) < -1)
{
printf("write failed\n");
return -1;
}
printf("write into driver success\nresult=%d,and the buf = %s\n",result,buf);
close(testdev);
return 0;
}
3 test_read.c
#include
#include
#include
#include
int main(void)
{
int i;
int testdev;
int result;
char buf[27]={'\0'};
testdev = open("/dev/module",O_RDWR);
if(testdev < 0)
{
printf("Cann't open file\n");
return 1;
}
printf("open ok\n");
if((result=read(testdev,buf,26))<0)
{
printf("read failed\n");
return -1;
}
printf("read from driver success\nnumber=%d,and the buff=%s\n",result,buf);
close(testdev);
return 0;
}