您的位置首页生活快答

如何编写Linux的驱动程序

如何编写Linux的驱动程序

的有关信息介绍如下:

如何编写Linux的驱动程序

}; //IO功能选项,硬件上拉输出 staticunsignedintgpio_cfg_table[]={ S3C2410_GPB5_OUTP,S3C2410_GPB6_OUTP,S3C2410_GPB7_OUTP,S3C2410_GPB8_OUTP,}; //编写一个ioctl函数,这个函数提供给用户端使用(也就是用户态使用) staticintmy_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg){ if(arg>4){ return-EINVAL;} if(cmd==1)//ledON{ s3c2410_gpio_setpin(gpio_table[arg],0);return0;} if(cmd==0)//ledOFF{ s3c2410_gpio_setpin(gpio_table[arg],1);return0;}else{ return-EINVAL;}} //一个和文件设备相关的结构体。 staticstructfile_operationsdev_fops={ .owner=THIS_MODULE,.ioctl=my_ioctl, //.read=my_read,//这个暂时屏蔽,一会我们再加入一个读操作的函数}; //linux中设备的注册结构体staticstructmiscdevicemisc=

{ .minor=MISC_DYNAMIC_MINOR,.name=DEVICE_NAME,.fops=&dev_fops,}; //设备初始化(包括注册)函数staticint__initdev_init(void){ intret;inti; for(i=0;i<4;i++){ s3c2410_gpio_cfgpin(gpio_table[i],gpio_cfg_table[i]);s3c2410_gpio_setpin(gpio_table[i],0);mdelay(500); s3c2410_gpio_setpin(gpio_table[i],1);} ret=misc_register(&misc); printk(DEVICE_NAME"MY_LED_DRIVERinitok\n");returnret;} //设备注销函数 staticvoid__exitdev_exit(void){ misc_deregister(&misc);} //与模块相关的函数module_init(dev_init);module_exit(dev_exit);MODULE_LICENSE("GPL"); MODULE_AUTHOR("blog.ednchina.com/itspy");

MODULE_DESCRIPTION("MYLEDDRIVER"); 到此,上面就完成了一个简单的驱动(别急,下面我们再会稍微增加点复杂的东西),以上代码的可以简单概括为:像自己写51单片机或者ARM的裸奔程序一样操作IO函数,然后再linux系统中进行相关必须的函数关联和注册。为什么要关联呢,为什么注册呢?因为这是必须的,从以下这些结构体就知道了。stuctfile_operations{structmodule*owner;loff_t(*llseek)(structfile*,loff_t,int);ssize_t(*read)(structfile*,char__user*,size_t,loff_t*);ssize_t(*write)(structfile*,constchar__user*,size_t,loff_t*);ssize_t(*aio_read)(structkiocb*,conststructiovec*,unsignedlong,loff_t);ssize_t(*aio_write)(structkiocb*,conststructiovec*,unsignedlong,loff_t);int(*readdir)(structfile*,void*,filldir_t);

unsignedint(*poll)(structfile*,structpoll_table_struct*);int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);long(*unlocked_ioctl)(structfile*,unsignedint,unsignedlong);…} file_operations结构体中包括了很多与设备相关的函数指针,指向了驱动所提供的函数。structinode{structhlist_nodei_hash;structlist_headi_list;structlist_headi_sb_list;structlist_headi_dentry;unsignedlongi_ino;atomic_ti_count;unsignedinti_nlink;uid_ti_uid;gid_ti_gid;dev_ti_rdev;u64i_version;loff_ti_size;…} inode是UNIX操作系统中的一种数据结构,它包含了与文件系统中各个文件相关的一些重要信息。在UNIX中创建文件系统时,同时将会创建大量的inode。通常,文件系统磁盘空间中大约百分之一空间分配给了inode表。 大略了解以上信息之后,我们只需把我们所要实现的功能和结构体关联起来。上例中已经完成IO写操作的函数,现在我们再添加一个读的函数。基于这种原理,我们想实现各种功能的驱动也就很简单了。 //添加读函数示意,用户层可以通过read函数来操作。 staticintmy_read(structfile*fp,char__user*dat,size_tcnt){ size_ti; printk("nowreadthehardware...\n");for(i=0;i

inton;intled_no;intfd;charstr;intcnt=0; fd=open("/dev/MY_LED_DRIVER",0);if(fd<0){ printf("can'topendev\n");exit(1);} printf("readprocess\n");cnt=read(fd,str,10); printf("getdatafromdriver:\n%s\ncount=%d\n",str,cnt);printf("readprocessend\n");cnt=0; printf("running...\n");while(cnt++<1000){ ioctl(fd,0,0);//ledoffioctl(fd,0,1);ioctl(fd,0,2);ioctl(fd,0,3);sleep(1); //printf("sdfdsfdsfdsfds...\n");ioctl(fd,1,0);//ledonioctl(fd,1,1);ioctl(fd,1,2);ioctl(fd,1,3);sleep(1); printf("%d\b",cnt);} close(fd);return0;}