ARM字符驱动实例最新培训课件(共47张PPT)_第1页
ARM字符驱动实例最新培训课件(共47张PPT)_第2页
ARM字符驱动实例最新培训课件(共47张PPT)_第3页
ARM字符驱动实例最新培训课件(共47张PPT)_第4页
ARM字符驱动实例最新培训课件(共47张PPT)_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

字符驱动(qūdònɡ)实例第一页,共四十七页。本实验(shíyàn)电路图4个LED指示灯的接口电路第二页,共四十七页。驱动程序#include<linux/kernel.h>#include<linux/module.h>#include<linux/init.h>#include<linux/fs.h>#include<linux/cdev.h>#include<linux/ioport.h>#include<asm-arm/io.h>#include<linux/ioctl.h>#include<linux/interrupt.h>#include<linux/delay.h>#include<linux/timer.h>#include<asm/irq.h>#include<linux/param.h>#include<linux/sched.h>#include<linux/errno.h>#include<asm/signal.h>定义(dìngyì)request_mem_region所需的头文件定义I/O读写,I/O内存读写所需的头文件定义ioctl函数所需的头文件定义ioctl函数所需的头文件定义延迟与定时器函数所需的头文件定义中断函数所需的头文件第三页,共四十七页。#defineCDRIVER_NAME"LED_chrdev"#defineGPFCON(0X56000050)#defineGPFDAT(0X56000054)#defineGPFUP(0X56000058)staticvoid*gpfcon;staticvoid*gpfdat;staticvoid*gpfup;intCDRIVER_MAJOR=0;intCDRIVER_MINOR=0;intcount=1;定义(dìngyì)物理地址定义映射后的虚拟地址指针第四页,共四十七页。loff_tLED_llseek(structfile*filp,loff_toff,intwhence);intLED_ioctl(structinode*inode,structfile*filp,unsignedintcmd,unsignedlongarg);intLED_open(structinode*inode,structfile*filp);intLED_release(structinode*inode,structfile*filp);externstructfile_operationsLED_fops;structcdev*LED_cdev;dev_tLED_dev;structfile_operationsLED_fops={.owner=THIS_MODULE,.llseek=LED_llseek,.open=LED_open,.release=LED_release,};第五页,共四十七页。staticint__initLED_init(void){……if(!request_mem_region(GPFCON,12,CDRIVER_NAME)){ printk(KERN_ERR"LED:io%Xisnotfree.\n",GPFCON); return-EBUSY; } gpfcon=ioremap_nocache(GPFCON,4); gpfdat=ioremap_nocache(GPFDAT,4); gpfup=ioremap_nocache(GPFUP,4); if(!gpfcon){ printk(KERN_ERR"LED:ioremapfailed\n");

iounmap(gpfcon); return-EINVAL; }申请(shēnqǐng)I/O内存I/O内存映射假设映射不成功,释放第六页,共四十七页。

if(!gpfdat){ printk(KERN_ERR"LED:ioremapfailed\n");

iounmap(gpfdat); return-EINVAL; } if(!gpfup){ printk(KERN_ERR"LED:ioremapfailed\n");

iounmap(gpfup); return-EINVAL; } return0;}假设(jiǎshè)映射不成功,释放假设映射不成功,释放第七页,共四十七页。intLED_open(structinode*inode,structfile*filp){ printk("LEDDeviceisopened\n"); writel((readl(gpfcon)&(1<<14)),gpfcon); writel((readl(gpfup)&(1<<7)),gpfup); writel((readl(gpfdat)&(0<<7)),gpfdat); ssleep(1);writel((readl(gpfdat)&(1<<7)),gpfdat); ssleep(1);writel((readl(gpfdat)&(0<<7)),gpfdat); try_module_get(THIS_MODULE); return0;}设为输出(shūchū)端口上拉禁止输出低电平,灯亮输出高电平,灯灭第八页,共四十七页。/*Release*/intLED_release(structinode*inode,structfile*filp){ printk("LEDDeciceisreleased!\n"); writel((readl(gpfcon)&(0<<14)),4); writel((readl(gpfup)&(1<<7)),4); writel((readl(gpfdat)&(0<<7)),4); module_put(THIS_MODULE); return0;}第九页,共四十七页。staticvoid__exitLED_exit(void) {printk("UnloadingLED_cdevnow...\n");

iounmap(gpfcon); iounmap(gpfdat); iounmap(gpfup); cdev_del(LED_cdev); unregister_chrdev_region(LED_dev,count); }释放(shìfàng)内存第十页,共四十七页。makefileifneq($(KERNELRELEASE),)obj-m:=LED_chrdev.o else KERNELDIR?=/usr/src/fs2410_2.6.8/ PWD:=$(shellpwd)default: $(MAKE)-C$(KERNELDIR)M=$(PWD)endif最终(zuìzhōnɡ)生成LED_chrdev.ko的可执行文件第十一页,共四十七页。应用程序#include<stdio.h>#include<stdlib.h>#include<fcntl.h>#include<errno.h>#include<unistd.h>#include<linux/delay.h>#include<sys/ioctl.h>#defineDEVICE_GPIOTEST"/dev/LED_chrdev"intmain(intargc,char*argv[]){intfd;fd=open(DEVICE_GPIOTEST,O_RDONLY);提供对文件(wénjiàn)控制的函数open等

提供对I/O控制的函数提供错误号errno的定义,用于错误处理linux/unix的系统调用,包含了许多系统效劳的函数原型,例如read,write等函数。第十二页,共四十七页。if(fd<0){perror("cannotopendevice");exit(1);}close(fd);return0;}第十三页,共四十七页。makefileCC=/usr/local/3.3.2/bin/arm-linux-gccLD=/usr/local/3.3.2/bin/arm-linux-ldINCLUDE=/usr/local/3.3.2/include/LIB=/usr/local/3.3.2/lib/TEST_LED:TEST_LED.o $(LD)-rTEST_LED.o-oTEST_LEDTEST_LED.o:TEST_LED.c

$(CC)-O2-Wall-I$(INCLUDE)-L$(LIB)-cTEST_LED.c-oTEST_LED.o最终(zuìzhōnɡ)生成TEST_LED的可执行文件第十四页,共四十七页。将驱动程序编译(biānyì)进内核在超级终端下将驱动程序LED_chrdev.ko和应用程序TEST_LED下载到/tmp路径下执行Chmod755LED_chrdev.koChmod755TEST_LEDInsmodLED_chrdev.ko./TEST_LED观察灯的情况!第十五页,共四十七页。将驱动程序编译(biānyì)进内核一.将驱动程序LED_chrdev.c放在相应的目录下,比方对于字符设备,就放置在fs2410/drivers/char/;二.修改drivers/…/Makefile文件三.修改drivers/…/Kconfig配置文件四.重新编译内核,下载第十六页,共四十七页。将驱动程序放在相应(xiāngyīng)的目录下第十七页,共四十七页。修改(xiūgǎi)drivers/char/Makefile第十八页,共四十七页。修改(xiūgǎi)drivers/char/Makefile第十九页,共四十七页。修改(xiūgǎi)drivers/char/Kconfig这些将出现在内核的编译配置中第二十页,共四十七页。简化我们(wǒmen)的设计对I/O端口定义的简化,参加头文件#include<asm/arch/regs-gpio.h>对I/O端口操作的简化,参加头文件#include<asm/arch/hardware.h>第二十一页,共四十七页。#include<asm/arch/regs-gpio.h>第二十二页,共四十七页。#include<asm/arch/regs-gpio.h>I/O端口不同(bùtónɡ)功能的定义对特殊功能存放器的定义第二十三页,共四十七页。#include<asm/arch/hardware.h>在<asm/arch/hardware.h>中包含(bāohán)了对I/O端口操作的函数externvoids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction);externvoids3c2410_gpio_pullup(unsignedintpin,unsignedintto);externvoids3c2410_gpio_setpin(unsignedintpin,unsignedintto);externunsignedints3c2410_gpio_getpin(unsignedintpin);函数在arch/arm/mach-s3c2410/gpio.c中定义第二十四页,共四十七页。/*s3c2410_gpio_cfgpin:设定(shèdìnɡ)特定端口的功能*eg:*s3c2410_gpio_cfgpin(S3C2410_GPA0,S3C2410_GPA0_ADDR0);*s3c2410_gpio_cfgpin(S3C2410_GPF7,S3C2410_GPF7_OUTP);*/将GPF7设置成输出端口第二十五页,共四十七页。s3c2410_gpio_cfgpinvoids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction){staticvoid*base; unsignedlongmask; unsignedlongcon; unsignedlongflags; base=ioremap_nocache(S3C2410_GPIO_PA_BASE(pin),0x0000004); if(pin<S3C2410_GPIO_BANKB){ mask=1<<S3C2410_GPIO_OFFSET(pin); }else{ mask=3<<S3C2410_GPIO_OFFSET(pin)*2; } local_irq_save(flags); con=__raw_readl(base+0x00); con&=~mask; con|=function; __raw_writel(con,base+0x00); local_irq_restore(flags);}将端口对应的GPnCON存放器进行(jìnxíng)I/O内存映射根据相应的功能对GPnCON存放器的对应位写入相应的值第二十六页,共四十七页。externvoids3c2410_gpio_pullup(unsignedintpin,unsignedintto);/*s3c2410_gpio_pullup**设置(shèzhì)特定端口的上拉**to=1=>disablethepull-up*0=>enablethepull-up**例子:**s3c2410_gpio_pullup(S3C2410_GPB0,0);*s3c2410_gpio_pullup(S3C2410_GPF7,1);*/第二十七页,共四十七页。s3c2410_gpio_getpinunsignedints3c2410_gpio_getpin(unsignedintpin);**设置特定输入(shūrù)端口的值**返回非0=>高电平*0=>低电平**例子:**s3c2410_gpio_getpin

(S3C2410_GPB0);*s3c2410_gpio_getpin(S3C2410_GPE8);*/第二十八页,共四十七页。s3c2410_gpio_getpinunsignedints3c2410_gpio_getpin(unsignedintpin){ staticvoid*data; unsignedlongoffs=S3C2410_GPIO_OFFSET(pin); data=ioremap_nocache(S3C2410_GPIO_PA_BASE(pin)+0x04,0x0000004); return__raw_readl(data)&(1<<offs);}将端口对应的GPnDAT存放器进行I/O内存(nèicún)映射读入GPnDAT存放器中对应位的值第二十九页,共四十七页。s3c2410_gpio_setpinexternvoids3c2410_gpio_setpin(unsignedintpin,unsignedintto);/**设置特定输出(shūchū)端口的高/低电平**to=1=>高电平*0=>低电平**例子:**s3c2410_gpio_setpin(S3C2410_GPB0,0);*s3c2410_gpio_setpin(S3C2410_GPF7,0);*/第三十页,共四十七页。对驱动程序的修改(xiūgǎi)……#include<asm/arch/regs-gpio.h>#include<asm/arch/hardware.h>对I/O端口定义的头文件对I/O端口操作的头文件第三十一页,共四十七页。staticint__initLED_init(void){……

s3c2410_gpio_cfgpin(S3C2410_GPF7,S3C2410_GPF7_OUTP);

s3c2410_gpio_pullup(S3C2410_GPF7,1);

s3c2410_gpio_setpin(S3C2410_GPF7,0); return-EINVAL; }第三十二页,共四十七页。intLED_open(structinode*inode,structfile*filp){ printk("LEDDeviceisopened\n");

s3c2410_gpio_setpin(S3C2410_GPF7,0);ssleep(1);s3c2410_gpio_setpin(S3C2410_GPF7,1);ssleep(1);

s3c2410_gpio_setpin(S3C2410_GPF7,0); try_module_get(THIS_MODULE); return0;}第三十三页,共四十七页。/*Release*/intLED_release(structinode*inode,structfile*filp){ printk("LEDDeciceisreleased!\n");s3c2410_gpio_cfgpin(S3C2410_GPF7,S3C2410_GPF7_INP);

s3c2410_gpio_pullup(S3C2410_GPF7,0);

s3c2410_gpio_setpin(S3C2410_GPF7,1); module_put(THIS_MODULE); return0;}第三十四页,共四十七页。中断(zhōngduàn)驱动程序的简化……#include<asm/arch/irq.h>#include<asm/arch/regs-irq.h>对各个中断号的定义对中断存放器定义的头文件第三十五页,共四十七页。asm-arm/arch-s3c2410/irq.hIrq:表示(biǎoshì)所要申请的中断号;中断号在include/asm-arm/arch-s3c2410/irq.h中定义第三十六页,共四十七页。asm-arm/arch-s3c2410/irq.h第三十七页,共四十七页。#include<asm/arch/regs-irq.h>第三十八页,共四十七页。<arch/arm/math-s3c2410/irq.c>在<arch/arm/math-s3c2410/irq.c>中定义有中断操作(cāozuò)的相关函数,可以通过extern语句参加这些函数第三十九页,共四十七页。在<arch/arm/math-s3c2410/irq.c>中定义有中断操作的相关函数s3c_irq_mask(unsignedintirqno)//中断屏蔽(píngbì)s3c_irq_unmask(unsignedintirqno)//中断使能s3c_irq_ack

(unsignedintirqno)//清中断挂起void__inits3c2410_init_irq(void)//中断初始化s3c_irqext_mask(unsignedintirqno)//外部中断屏蔽s3c_irqext_ack(unsignedintirqno)//清外部中断挂起s3c_irqext_unmask(unsignedintirqno)//外部中断使能第四十页,共四十七页。<arch/arm/math-s3c2410/irq.c>函数:s3c_irq_mask(unsignedintirqno)参数:irqno表示中断号作用:屏蔽特定(tèdìng)中断例子:s3c_irq_mask〔IRQ_EINT0〕s3c_irq_mask(unsignedintirqno)

{

unsignedlongmask;

irqno-=IRQ_EINT0;

mask=__raw_readl(S3C2410_INTMSK);

mask|=1UL<<irqno;

__raw_writel(mask,S3C2410_INTMSK);

}

第四十一页,共四十七页。函数(hánshù):s3c_irq_unmask(unsignedintirqno)参数:irqno表示中断号作用:屏蔽特定中断例子:s3c_ir

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论