700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > linux驱动程序的测试 Linux驱动学习笔记(4)字符设备驱动测试

linux驱动程序的测试 Linux驱动学习笔记(4)字符设备驱动测试

时间:2024-02-25 12:58:10

相关推荐

linux驱动程序的测试 Linux驱动学习笔记(4)字符设备驱动测试

首先装载模块

sudo insmod scull.ko

sudo cat /var/log/messages

Apr 28 21:04:36 garden kernel: [ 868.562322] scullsingle registered at f900008

Apr 28 21:04:36 garden kernel: [ 868.562325] sculluid registered at f900009

Apr 28 21:04:36 garden kernel: [ 868.562326] scullwuid registered at f90000a

Apr 28 21:04:36 garden kernel: [ 868.562327] sullpriv registered at f90000b

看到打印安装成功。通过dmesg命令也可以看到这些消息

cat /proc/devices

Character devices:

...

249 scull

249 scullp

249 sculla

...

看到字符设备下出现了scull,这是函数add_cdev成功将scull加入到了系统中,系统给scull分配的主设备号是249。

现在可以确认scull驱动程序已经运行在系统中了,那么怎么操作它呢?

我们首先要建立一个文件节点,使用mknod 命令,mknod 用法是这样的,mknod name type major minor,分别接节点名,类型,b表示块设备,c表示字符设备(scull是字符设备,因此用c),major是主设备号(scull主设备号是249),minor为次设备号。

sudomknod /dev/scull0 c 249 0

ls -l /dev

可以看到,有一个叫sucll0的设备出现在dev目录下。现在可以对这个字符设备进行读写操作了。我写了一个函数来验证scull是否能正确工作,先往scull里写数字,然后读出来,现写1000个整数,也就是4000Bytes,从0写到999,看能否正确的读出来。代码如下:

点击(此处)折叠或打开

#include

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

int i,fd;

int *content,*buffer;

fd=open("/dev/scull0",O_RDWR);

content=(int*)malloc(1000*sizeof(int));

for(i=0;i<1000;i++) //初始化content内容为0~999

*(content+i)=i;

write(fd,content,i*sizeof(int)); //此处write是以byte为单位的

lseek(fd,0L,SEEK_SET); //指针重新定位到文件开头

buffer=(int*)malloc(1000*sizeof(int));

read(fd,buffer,i*sizeof(int)); //同样,读也是以byte为单位

for(i=0;i<1000;i++)

{

printf("%d\t",*(buffer+i));

if((i+1)%10==0)

printf("\n");

}

printf("\n");

return 0;

}执行,终端打印了0-999共4000Byte单位的内存内容,那么,如果要写入更多呢?我们可以稍微修改一下程序,使得可以从终端读入需要写入scull的长度。代码进行小改动,如下

点击(此处)折叠或打开

#include

#include

#include

#include

#include

#include

void usage()

{

printf("usage: command \n");

exit(0);

}

int main(int argc,char **argv)

{

int i,fd,numbers;

int *content,*buffer;

if(argc!=2)

usage();

numbers=atoi(argv[1]); //将输入转化为int型

fd=open("/dev/scull0",O_RDWR);

content=(int*)malloc(numbers*sizeof(int));

for(i=0;i

*(content+i)=i;

write(fd,content,numbers*sizeof(int));

lseek(fd,0L,SEEK_SET);

buffer=(int*)malloc(numbers*sizeof(int));

read(fd,buffer,numbers*sizeof(int));

for(i=0;i

{

printf("%d\t",*(buffer+i));

if((i+1)%10==0)

printf("\n");

}

printf("\n");

return 0;

}现在我们可以随意指定写入scull的尺寸了。OK!那就试试写入更多的数字吧。运行./testScull 1100,发现1000以后的都是0了,这是怎么回事呢?仔细观察scull的write方法,原来,我们的驱动程序默认是一次写入1个quartum,4000字节,即使你只写了1个byte,也会消耗4000byte内存,而超过4000的数据会被截短。

点击(此处)折叠或打开

if(!dptr->data[s_pos])

{

dptr->data[s_pos]=kmalloc(quantum,GFP_KERNEL); //每次分配一个量子的内存

...

}

if(count>quantum-q_pos) //如果count大于quantum的大小,将截短

count=quantum-q_pos;事实上,我们的测试程序进行系统调用read和write的时候并没有检查它的返回值,这样做是不妥的,在任何时候进行系统调用我们都应该检查它的返回值。返回值有三种情况

1,返回值等于count,这种情况read(write)调用完成了请求

2,返回值小于0,这意味着发生错误了,用strerror(errno)查看错误信息

3,返回值等于0,没有读写发生,系统可能重复调用读写

4,返回值大于0小于count,写入部分,我们呢可以接着调用继续写入剩下的部分。

3和4的情况都不是错误,程序员需要根据返回值进行恰当的动作而不是直接返回error。

看来我们写入4400byte数据只能读出4000byte数据是合理的结果的,我们需要修改程序,对write和read的返回值进行检查。修改后的代码如下

点击(此处)折叠或打开

#include

#include

#include

#include

#include

#include

#include

#include

void usage()

{

printf("usage: command \n");

exit(0);

}

int main(int argc,char **argv)

{

int i,fd,numbers,count,rest;

int *content,*buffer;

if(argc!=2)

usage();

numbers=atoi(argv[1]); //将输入转化为int型

rest=numbers*sizeof(int);

fd=open("/dev/scull0",O_RDWR);

content=(int*)malloc(numbers*sizeof(int));

if(content<0)

printf("malloc failed:%s",strerror(errno));

for(i=0;i

*(content+i)=i;

count=write(fd,content,numbers*sizeof(int));

while(count!=rest)

{

if(count<0)

{

printf("%s\n",strerror(errno));

exit(0);

}

else if(count

{

rest=rest-count;

content+=count/sizeof(int);

count=write(fd,content,rest);

}

}

if(rest

content-=numbers-rest/sizeof(int);

free(content);

lseek(fd,0L,SEEK_SET);

rest=numbers*sizeof(int);

buffer=(int*)malloc(numbers*sizeof(int));

if(buffer<0)

printf("malloc failed:%s\n",strerror(errno));

count=read(fd,buffer,rest);

while(count!=rest)

{

if(count<0)

{

printf("%s",strerror(errno));

exit(0);

}

else if(count

{

rest-=count;

buffer+=count/sizeof(int);

count=read(fd,buffer,rest);

}

}

if(rest

buffer-=numbers-rest/sizeof(int);

for(i=0;i

{

printf("%d\t",*(buffer+i));

if((i+1)%10==0)

printf("\n");

}

printf("\n");

free(buffer);

return 0;

}

89,1 Bot运行程序,后面可以写入很大的数据,观察内存占用的情况。比如可以写100M数据,在命令行用free查看,当然,这个时候需要先把79到85行注释掉先,不然电脑打印100M个数据会卡死的,哈哈。最后附上测试文件

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。