![嵌入式学习下午led模块驱动实验_第1页](http://file4.renrendoc.com/view/d63b220c1ed4eed28701fac7e8addbf9/d63b220c1ed4eed28701fac7e8addbf91.gif)
![嵌入式学习下午led模块驱动实验_第2页](http://file4.renrendoc.com/view/d63b220c1ed4eed28701fac7e8addbf9/d63b220c1ed4eed28701fac7e8addbf92.gif)
![嵌入式学习下午led模块驱动实验_第3页](http://file4.renrendoc.com/view/d63b220c1ed4eed28701fac7e8addbf9/d63b220c1ed4eed28701fac7e8addbf93.gif)
![嵌入式学习下午led模块驱动实验_第4页](http://file4.renrendoc.com/view/d63b220c1ed4eed28701fac7e8addbf9/d63b220c1ed4eed28701fac7e8addbf94.gif)
![嵌入式学习下午led模块驱动实验_第5页](http://file4.renrendoc.com/view/d63b220c1ed4eed28701fac7e8addbf9/d63b220c1ed4eed28701fac7e8addbf95.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ledled设备驱动编 一 实验内 二 实验原 1、硬件原 2、驱动实 三 源代码分 1、驱动程序分 2、应用程序分 3、Makefile工程文件分 四 实验步 1、获得源 2、修改Makefile规则文 3、编 4、5、测 led UP-CUPIOT6410-II型平台Version:Author:
一、实验内悉驱动的过程。二、实验原1 硬件原LEDLED5LED6410处理器GPQ2~6LEDLED灯灭。管脚寄存主要需要设置的寄存器为GPQCONGPQDAT,如下所示,具体可查看S3C6410X_UM_Rev1.10_080822.pdf2.6.38内核配置管脚函intexternints3c_gpio_cfgpin(unsignedintpinunsignedint头文件:t/gpio-pinto#defineS3C_GPIO_INPUT(S3C_GPIO_SPECIAL(0))#defineS3C_GPIO_OUTPUT(S3C_GPIO_SPECIAL(1))#defineS3C_GPIO_SFN(x)(S3C_GPIO_SPECIAL(x))函数原型:staticinlinevoidgpio_set_value(unsignedgpioint参数:pin为管脚,value函数原型:staticinlineintgpio_direction_output(unsignedgpioint参数:pin为管脚,valuepinIOvalueIO口设置为输出方式,其等同s3c_gpio_cfgpin()gpio_set_value(。2 驱动实设备编MAJOR(dev_tdev)MINOR(dev_t--获得设备在<linux/fs.h>中,主要有register_chrdev_region()和alloc_chrdev_region()unregister_chrdev_region()释放设备编号。name是和该编号范围关联的设备名称,它将出现在/proc/devices文件函数原型:intregister_chrdev_region(dev_tfirst,unsignedintcount,char函数参数:first为第一个设备号,count为申请的设备数量,name为设备名。函数功能:静态分配指定的设备号intalloc_chrdev_region(dev_t*dev,unsignedintfirstminor,unsignedintcount,char*函数参数:该函数需要传递给它指定的第一个次设备号firstminor(一般为0)和要分配的设备数count,以及设备名,调用该函数后自动分配得到的设备号保存在dev中。函数功能:动态申请设备号函数原型:voidunregister_chrdev_region(dev_tfirst,unsignedint头文件:函数参数:first为第一个设备号,count为申请的设备数量函数功能:释放设备号在调用cdev_del()函数从系统注销字符设备之后,应该被调用以释放原先申请的设备号。与释放内核structcdev结构来表示字符设备。在内核调用设备的操作之前,必须分配并一个或多个structcdev。代码应包含<linux/cdev.h>,它定义了structcdevcdev1structcdevstructcdev 2structvoidcdev_init(structcdev*cdevconststructfile_operations*fops)3cdev.owner4、cdevstructcdevintcdev_add(structcdev*p,dev_tdev,unsigned5、从系统中移除一个字符设备:voidcdev_del(structcdev函数原型:intcdev_add(structcdev*dev,dev_tnum,unsignedint头文件:函数参数:devcdev结构num是这个设备响应的第一个设备号count是应当关联到设备的设备号的数目.常常count是1,函数功能:字符设备函数原型:voidcdev_del(structcdev头文件:函数参数:devcdev结构函数功能:注销字符设备驱动和函数staticstructfile_operationsuptech_leds_fops=staticstructfile_operationsuptech_leds_fops= CGNU编译器的一种特殊扩展,Ioctl说ioctl方法来支持。ioctl在用户空间的原型intioctl(intfd,unsignedlongcmd,来定,如果cmd不需要参数,那么...就不会被使用,如果cmd需要参数,则就会使用...char*argp来定义。这里使用...ioctl命令为了方便程序员唯一的创建ioctl命令编号,内核中作了如下规定传输方向。_IOC_NONE(没有数据传输_IOC_READ_IOC_WRITE以及 #define //8#define //8Letanyarchitectureoverrideeitherofthefollowingincludingthis#ifndef //size#define_IOC_SIZEBITS14#ifndefdefine //direction内核中给出了创建ioctl命令的宏/*usedtocreatenumbers#define #define_IOR(type,nr,size) #define_IOW(type,nr,size) #define_IOR_BAD(type,nr,size)_IOC(_IOC_READ,(type),(nr),sizeof(size))#define_IOW_BAD(type,nr,size)_IOC(_IOC_WRITE,(type),(nr),sizeof(size))三、源代码分1 驱动程序分具体驱动实#include /*Dynamicloadingofmodules#include /*Dynamicloadingofmodulesintothekernel#include /*printk()#include /*file_operations#include#include#include<linux/cdev.h>/*cdev结构相关#include #include<asm/irq.h> #include<mach/regs-gpio.h>/*与寄存器相关*/#include< /*与IO配置相关*/#include<linux/gpio.h> /*与IO相关*/#include<linux/slab.h>#include /* /*表式开放源码,在linux/module.h中定义*/#defineDEVICE_NAME #defineDEVICE_MAJOR #define /*IOCTLcommands#define #defineLED_IOC_WR_ON_IOW(LED_IOC_MAGIC0x80,unsignedint)//LEDioctl命令#defineLED_IOC_WR_OFF_IOW(LED_IOC_MAGIC,0x81,unsignedint)//LEDioctl命structcdev*mycdev; structclass*myclass; /*定义class*/dev_tdevno; staticunsignedlongled_table/io列表名称:uptech_leds功能:对应用户空间的ioctl系统调用,对用户空间传递过来 令进行swith判断,并进行相应处理,本函数会对LED 令进行判断,进行相应LED亮灭的控制参数:*filpID,cmdcmd,arg对应用户空0defaultstaticlonguptech_leds_ioctl(structfile*file,unsignedintcmd,unsignedlong{intunsigned /*Checktypeandcommandnumberif(_IOC_TYPE(cmd)!=LED_IOC_MAGIC)//判断是不是针对此驱 return-if(arg>4){return-}buf(unsignedlong*)kmalloc(sizeof(*bufGFP_KERNEL)申请内存if(buf==NULL)return-ret=copy_from_user(buf,&arg,sizeof(unsignedlong));//从用户空间将参数拷贝到//printk("ret=%x\n",ret);if(ret!=0){ return-}switch(cmd)case//printk("kernel:setledoncmdnum:%lx\n",gpio_set_value(led_table[*buf]0);//IOcase//printk("kernel:setledoffcmdnum:%lx\n",gpio_set_value(led_table[*buf],1IO}
return-return}名称:uptech_leds_fopsstaticstructfile_operationsuptech_leds_fops={ 名称:staticvoiduptech_leds_init 函数,通过通过register_chrdev_region函数向系统申请固定设备号通过cdev_add()函数向系统 字符设备(这两个函数在<linux/fs.h>中定义,通过class_create()及device_create()动态创建设备文件*参数:*staticintinituptech_leds_init(void){intintdevno=MKDEV(DEVICE_MAJOR,DEVICE_MINOR);//dev_t号mycdevcdev_alloc();//cdevmycdev->ops=&uptech_leds_fops;//ops初始化mycdev->ownerTHIS_MODULE;//owner初始化err=cdev_add(mycdev,devno,1);//字符设备if(err!=0)printk("s3c6410ledsdeviceregistermyclassclass_create(THIS_MODULE,DEVICE_NAME);//classif(IS_ERR(myclass)){printk("Err:failedincreatingclass.\n");return-1;}AME);//创建设备文件for(i=0;i<5;i++)s3c_gpio_cfgpin(led_table[i],S3C_GPIO_SFN(1));//式}printk(DEVICE_NAME"initialized\n");return0;}staticvoidexit{//class_destroy(myclass);//class}2 应用程序分#include#include#include<stdlib.h>#include#include /*ioctl函数头文件/*IOCTLcommands#define#define _IOW(LED_IOC_MAGIC0x80,unsigned #define _IOW(LED_IOC_MAGIC0x81,unsignedint) intmain(intargc,char{intintintled_number;intfd;if(argc!=3||sscanf(argv[1],"%d",&led_number)!=1||&on)!=1on<0||on>1||led_number<0||led_number>5){fprintf(stderr,"Usage:\n");fprintf(stderr,"\t./ledled_numberon|off\n");fprintf(stderr,"Options:\n");fprintf(stderr,"\tled_numberfrom0to4\n");fprintf(stderr,"\ton:1 off:0\n");}fdopen("/dev/leds0);//打开/dev/ledif(fd<0)perror("opendevice/dev/leds");}if(on==ioctl(fdLED_IOC_WR_ONled_number);//}elseif(on==,,}return}TARGET=PILE=arm-ifeqTARGET=PILE=arm-ifeq#Assumethesourcetreeiswheretherunningkernelwas#YoushouldsetKERNELDIRintheenvironmentifit'selsewhereKERNELDIR?=/home/uptech/kernel/linux-/#Thecurrentdirectoryispassedtosub-makesasargumentPWD:=$(s $(CC)-o$(TARGET)$(MAKE)-C$(KERNELDIR)M=$(PWD)$(MAKE)-C$(KERNELDIR)M=$(PWD)rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c*.symvers*.order===-#calledfromkernelbuildsystem:justdeclarewhatourmodulesareobj-m:=s3c-leds.o,KERNELRELEASE宏的值是否为空。$(KERNELRELEASE)Makefile中定义的一个变量,在第一次读Makefile时,KERNELRELEASE没有被定义。PWD$(spwd)PWD变量进行赋值,作用是将$(spwd)的返回结果(既求得当前的路径)PWD,这个变量在后面指代要编译的驱动程序$(MAKE)-C$(KERNELDIR)M=$(PWD)工作转移到你所指定的位置。“M=”选项的作用是,当用户需要以某个内核为基础编译一个外部模块的话,需要在makemodules命令中加入“M=dir”,程序会自动dirKO文件。.PHONY:modulesmodules_installclean这句话是的作用是保证modules,modules_install,clean这三个命令能正常完成。.PHONY这是一个特殊目标名称obj-ms3c-leds.oobj-$(CONFIG_TCtc.o的语句是用来定义编译的目标,是子Makefile中最重要的部分。编译目标定义那些在本子下,需要编Linux内核中的目标文件列表。为了只在用户选择了此功能后才编译,所有的Kconfig设置变量的判断。Kconfig设置变量取值范围是:y,n,m和空,obj-$(CONFIG_TC)分别对应着obj-y,obj-n,obj-m,obj-CONFIG_TCytc.oobj-y列表。obj-yLinuxvmlinux中的目标文件列表;obj-m为编译成模块的目标文件列表;obj-nobj-中的文件列表被忽略。设置系统就根据这些列表Makefile的执行过程:KERNELRELEASEMakefile中定义的一将执行else之前的内容。执行all这条规则->执行$(TARGET)规则编译生成应用程序->执行modules规则,-C$(KERNELDIR)指明跳转到内核源码下那里Makefile;M=$(PWD)表明然后返回到当前Makefile当从内核源码返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续else之后的内容。else之后的内容为kbuild语四、实验步1 获得源测试程序
[root@localhostuptech]#mkdirdriver_char[root@localhostuptech]#cd[root@localhostdriver_char]#mkdir拷贝源码到通过samba服务将 下的源文件,拷贝到虚拟机fedora系[root@localhostdriver_char]#cddriver_led/[root@localhostdriver_led]#ls 2 修改Makefile规则文[root@localhostdriver_demo]#vi更改KERNELDIR?=/home/uptech/kernel/linux- 为自己的内核源(确保此内核已经编译过一次3 编makecleanmakes3c-leds.ko及应用程test_led,具体步骤如下:rm-rf*.o*~rm-rf*.o*~core.depend.*.cmd*.ko*.mod.c*.symvers*.order.tmp_versions[root@localhostdriver_led]#arm-linux-gccarm-linux-gcc-otest_ledmak
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- Karrikinolide-3-ethyl-ester-生命科学试剂-MCE-7462
- Diammonium-phosphate-15N2-生命科学试剂-MCE-5147
- 1-3-Diheptadecanoyl-glycerol-生命科学试剂-MCE-9470
- 2025年度家居建材送货司机合作协议书
- 二零二五年度绿色能源知识产权共享及资源利用合同
- 2025年度钢筋加工企业节能减排合作协议
- 二零二五年度股权代持协议中的税务影响与筹划策略
- 2025年度药店药品质量检测员劳动合同
- 2025年度养老产业股份转让协议书
- DB 3705T 50-2024设施蝴蝶兰高效栽培技术规程
- 聚合物粘弹性
- 建筑工程施工现场安全资料管理规程解读
- 养老护理员培训老年人日常生活照料
- 黑龙江省哈尔滨市八年级(下)期末化学试卷
- 各种抽油泵的结构及工作原理幻灯片
- 学习弘扬雷锋精神主题班会PPT雷锋精神我传承争当时代好少年PPT课件(带内容)
- 社区获得性肺炎的护理查房
- 体育赛事策划与管理第八章体育赛事的利益相关者管理课件
- 专题7阅读理解之文化艺术类-备战205高考英语6年真题分项版精解精析原卷
- 《生物资源评估》剩余产量模型
- 2022年广东省10月自考艺术概论00504试题及答案
评论
0/150
提交评论