原创 linux字符设备驱动的学习

2009-11-25 10:24 2319 8 8 分类: MCU/ 嵌入式

字符设备驱动学习:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


设备--------à编写几个基本的函数--------àVFS注册


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />



file_operations()




register_chrdev()


unregister_chrdev()

<?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />


Linux内核与设备之间的数据传输方式:


轮询方式


中断方式


DMA方式


 


设备文件的分类:


字符设备


块设备:大量数据传输  或者慢速设备


网络设备


 


驱动程序的加载方法:


直接编译进内核


驱动程序模块加载


 


需要修改config文件和Makefile文件


 


linuxchar目录下面建立一个.c的文件


可以用vi方法建立  touch建立 


也可以直接用gedit建立


[root@localhost sep4020_char]#gedit globalvar.c


然后输入如下的代码:


 


#include <linux/init.h>


#include <linux/module.h>


#include <linux/fs.h>


#include <asm/uaccess.h>


 


#define MAJOR_NUM 254  //主设备号 254


MODULE_LICENSE("GPL");


 


static ssize_t globalvar_read(struct file *,char*,size_t,loff_t *);


 


static ssize_t globalvar_write(struct file *,const char*,size_t,loff_t *);


 


 


 


 


struct file_operations globalvar_fops=


{


read:globalvar_read,write:globalvar_write,


};


 


static int global_var=0;


 


static int globalvar_init(void)


{


int ret;


ret=register_chrdev(MAJOR_NUM,"globalvar",


&globalvar_fops);


if(ret)


{


printk("globalvar register failure\n");


}


else


{


printk("globalvar register success\n");


}


return ret;


}


 


 


static void globalvar_exit(void)


{


int ret;


ret=unregister_chrdev(MAJOR_NUM,"globalvar");


if(ret)


{


printk("failure\n");


}


else


{


printk("success\n");


}


}


 


 


 


 


 


 


static ssize_t globalvar_read(struct file *filp,char*buf,size_t len,loff_t *off)


{


if(copy_to_user(buf,&global_var,sizeof(int)))


{


return 0;


}


return sizeof(int);


}


 


static ssize_t globalvar_write(struct file *filp,const char*buf,size_t len,loff_t *off)


{


if(copy_from_user(&global_var,buf,sizeof(int)))


{


return 0;


}


return sizeof(int);


}


 


module_init(globalvar_init);


module_exit(globalvar_exit);


 


 


编写完成之后,保存退出


然后配置下你的KconfigMakefile文件:方法如下:


gedit Kconfig


在里面添加一句


config GLOBALVAR



tristate "sep4020 globalvar driver"



default y


保存并退出


 


然后执行gedit Makefile


在里面添加一句


obj-$(CONFIG_GLOBALVAR) += globalvar.o


 


然后再在linux目录下执行 make menuconfig


将你添加的globalvar driver 选择M(编译成模块的形式)


保存退出


 


然后再执行 make modules


就会在你创建.c文件的目录下同时创建一个.ko文件


然后再在/dev目录下创建一个设备节点,方法如下


mknod /dev/globalvar c 254 0


执行ls命令就会发现


globalvar的设备节点


 


然后再建立一个.c文件


如下


 



#include<sys/types.h>


#include<sys/stat.h>


#include<stdio.h>


#include<fcntl.h>


int main()


{


int fd,num;


fd=open("/dev/globalvar",O_RDWR,S_IRUSR|S_IWUSR);


if(fd!=-1)


{


read(fd,&num,sizeof(int));


printf("The globalvar is %d\n",num);


printf("Please input the num written to globalvar\n");


scanf("%d",&num);


write(fd,&num,sizeof(int));


read(fd,&num,sizeof(int));


printf("The globalvar is %d\n",num);


close(fd);


}


else


{


printf("Device open failure\n");


}


}


 


insmod globalvar.ko


./globalvar


就可以测试了


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /3 下一条