如何编写驱动程序?

代码:#include<linux/module.h>#include<linux/kernel.h>#include<asm/io.h>#include<linux/miscdevice.h>#include<linux/fs.h>#include<asm/uaccess.h>//流水灯代码#define GPM4CON 0x110002e0#define GPM4DAT 0x110002e4static unsigned long*ledcon=NULL;static unsigned long*leddat=NULL;//自定义write文件操作(不自定义的话,内核有默认的一套文件操作函数)static ssize_t test_write(struct file*filp,const char __user*buff,size_t count,loff_t*offset){int value=0;int ret=0;ret=copy_from_user(&value,buff,4);//底层驱动只定义基本操作动作,不定义功能if(value==1){*leddat|=0x0f;*leddat&=0xfe;}if(value==2){*leddat|=0x0f;*leddat&=0xfd;}if(value==3){*leddat|=0x0f;*leddat&=0xfb;}if(value==4){*leddat|=0x0f;*leddat&=0xf7;}return 0;}//文件操作结构体初始化static struct file_operations g_tfops={.owner=THIS_MODULE,.write=test_write,};//杂设备信息结构体初始化static struct miscdevice g_tmisc={.minor=MISC_DYNAMIC_MINOR,.name=”test_led”,.fops=&g_tfops,};//驱动入口函数杂设备初始化static int __init test_misc_init(void){//IO地址空间映射到内核的虚拟地址空间ledcon=ioremap(GPM4CON,4);leddat=ioremap(GPM4DAT,4);//初始化led*ledcon&=0xffff0000;*ledcon|=0x00001111;*leddat|=0x0f;//杂设备注册函数misc_register(&g_tmisc);return 0;}//驱动出口函数static void __exit test_misc_exit(void){//释放地址映射iounmap(ledcon);iounmap(leddat);}//指定模块的出入口函数module_init(test_misc_init);module_exit(test_misc_exit);MODULE_LICENSE(“GPL”);扩展资料:include用法:#include命令预处理命令的一种,预处理命令可以将别的源代码内容插入到所指定的位置;可以标识出只有在特定条件下才会被编译的某一段程序代码;可以定义类似标识符功能的宏,在编译时,预处理器会用别的文本取代该宏。插入头文件的内容#include命令告诉预处理器将指定头文件的内容插入到预处理器命令的相应位置。有两种方式可以指定插入头文件:1、#include<文件名>2、#include”文件名”如果需要包含标准库头文件或者实现版本所提供的头文件,应该使用第一种格式。如下例所示:#include<math.h>//一些数学函数的原型,以及相关的类型和宏如果需要包含针对程序所开发的源文件,则应该使用第二种格式。采用#include命令所插入的文件,通常文件扩展名是

.h

,文件包括函数原型、宏定义和类型定义。只要使用#include命令,这些定义就可被任何源文件使用。如下例所示:#include”myproject.h”//用在当前项目中的函数原型、类型定义和宏你可以在#include命令中使用宏。如果使用宏,该宏的取代结果必须确保生成正确的#include命令。例1展示了这样的#include命令。【例1】在#include命令中的宏#ifdef _DEBUG_#define MY_HEADER”myProject_dbg.h”#else#define MY_HEADER”myProject.h”#endif#include MY_HEADER当上述程序代码进入预处理时,如果_DEBUG_宏已被定义,那么预处理器会插入

myProject_dbg.h

的内容;如果还没定义,则插入

myProject.h

的内容。