1TMTHEARCHITECTUREFORTHEDIGITALWORLD字符驱动实例2TM2ARM及Thumb指令集本实验电路图4个LED指示灯的接口电路3TM3ARM及Thumb指令集驱动程序#includelinux/kernel.h#includelinux/module.h#includelinux/init.h#includelinux/fs.h#includelinux/cdev.h#includelinux/ioport.h#includeasm-arm/io.h#includelinux/ioctl.h#includelinux/interrupt.h#includelinux/delay.h#includelinux/timer.h#includeasm/irq.h#includelinux/param.h#includelinux/sched.h#includelinux/errno.h#includeasm/signal.h定义request_mem_region所需的头文件定义I/O读写,I/O内存读写所需的头文件定义ioctl函数所需的头文件定义ioctl函数所需的头文件定义延迟与定时器函数所需的头文件定义中断函数所需的头文件4TM4ARM及Thumb指令集#defineCDRIVER_NAMELED_chrdev#defineGPFCON(0X56000050)#defineGPFDAT(0X56000054)#defineGPFUP(0X56000058)staticvoid*gpfcon;staticvoid*gpfdat;staticvoid*gpfup;intCDRIVER_MAJOR=0;intCDRIVER_MINOR=0;intcount=1;定义物理地址定义映射后的虚拟地址指针5TM5ARM及Thumb指令集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,};6TM6ARM及Thumb指令集staticint__initLED_init(void){……if(!request_mem_region(GPFCON,12,CDRIVER_NAME)){printk(KERN_ERRLED: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_ERRLED:ioremapfailed\n);iounmap(gpfcon);return-EINVAL;}申请I/O内存I/O内存映射若映射不成功,释放7TM7ARM及Thumb指令集if(!gpfdat){printk(KERN_ERRLED:ioremapfailed\n);iounmap(gpfdat);return-EINVAL;}if(!gpfup){printk(KERN_ERRLED:ioremapfailed\n);iounmap(gpfup);return-EINVAL;}return0;}若映射不成功,释放若映射不成功,释放8TM8ARM及Thumb指令集intLED_open(structinode*inode,structfile*filp){printk(LEDDeviceisopened\n);writel((readl(gpfcon)&(114)),gpfcon);writel((readl(gpfup)&(17)),gpfup);writel((readl(gpfdat)&(07)),gpfdat);ssleep(1);writel((readl(gpfdat)&(17)),gpfdat);ssleep(1);writel((readl(gpfdat)&(07)),gpfdat);try_module_get(THIS_MODULE);return0;}设为输出端口上拉禁止输出低电平,灯亮输出高电平,灯灭9TM9ARM及Thumb指令集/*Release*/intLED_release(structinode*inode,structfile*filp){printk(LEDDeciceisreleased!\n);writel((readl(gpfcon)&(014)),4);writel((readl(gpfup)&(17)),4);writel((readl(gpfdat)&(07)),4);module_put(THIS_MODULE);return0;}10TM10ARM及Thumb指令集staticvoid__exitLED_exit(void){printk(UnloadingLED_cdevnow...\n);iounmap(gpfcon);iounmap(gpfdat);iounmap(gpfup);cdev_del(LED_cdev);unregister_chrdev_region(LED_dev,count);}释放内存11TM11ARM及Thumb指令集makefileifneq($(KERNELRELEASE),)obj-m:=LED_chrdev.oelseKERNELDIR?=/usr/src/fs2410_2.6.8/PWD:=$(shellpwd)default:$(MAKE)-C$(KERNELDIR)M=$(PWD)endif最终生成LED_chrdev.ko的可执行文件12TM12ARM及Thumb指令集应用程序#includestdio.h#includestdlib.h#includefcntl.h#includeerrno.h#includeunistd.h#includelinux/delay.h#includesys/ioctl.h#defineDEVICE_GPIOTEST/dev/LED_chrdevintmain(intargc,char*argv[]){intfd;fd=open(DEVICE_GPIOTEST,O_RDONLY);提供对文件控制的函数open等提供对I/O控制的函数提供错误号errno的定义,用于错误处理linux/unix的系统调用,包含了许多系统服务的函数原型,例如read,write等函数。13TM13ARM及Thumb指令集if(fd0){perror(cannotopendevice);exit(1);}close(fd);return0;}14TM14ARM及Thumb指令集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最终生成TEST_LED的可执行文件15TM15ARM及Thumb指令集将驱动程序编译进内核在超级终端下将驱动程序LED_chrdev.ko和应用程序TEST_LED下载到/tmp路径下执行Chmod755LED_chrdev.koChmod755TEST_LEDInsmodLED_chrdev.ko./TEST_LED观察灯的情况!16TM16ARM及Thumb指令集将驱动程序编译进内核一.将驱动程序LED_chrdev.c放在相应的目录下,比如对于字符设备,就放置在fs2410/drivers/char/;二.修改drivers/…/Makefile文件三.修改drivers/…/Kconfig配置文件四.重新编译内核,下载17TM17ARM及Thumb指令集将驱动程序放在相应的目录下18TM18ARM及Thumb指令集修改drivers/char/Makefile19TM19ARM及Thumb指令集修改drivers/char/Makefile20TM20ARM及Thumb指令集修改drivers/char/Kconfig这些将出现在内核的编译配置中21TM21ARM及Thumb指令集简化我们的设计对I/O端口定义的简化,加入头文件#includeasm/arch/regs-gpio.h对I/O端口操作的简化,加入头文件#includeasm/arch/hardware.h22TM22ARM及Thumb指令集#includeasm/arch/regs-gpio.h23TM23ARM及Thumb指令集#includeasm/arch/regs-gpio.hI/O端口不同功能的定义对特殊功能寄存器的定义24TM24ARM及Thumb指令集#includeasm/arch/hardware.h在asm/arch/hardware.h中包含了对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中定义25TM25ARM及Thumb指令集/*s3c2410_gpio_cfgpin:设定特定端口的功能*eg:*s3c2410_gpio_cfgpin(S3C2410_GPA0,S3C2410_GPA0_ADDR0);*s3c2410_gpio_cfgpin(S3C2410_GPF7,S3C2410_GPF7_OUTP);*/将GPF7设置成输出端口26TM26ARM及Thumb指令集s3c2410_gpio_cfgpinvoids3c2410_gpio_cfgpin(unsignedintpin,unsignedintf