石家庄铁道大学《嵌入式系统》实验报告--实验四LED驱动及控制实验实验者姓名:崔乐乐实验者学号:20122792同组人:孔维春实验者班级:信1201-2所在学院:信息科学与技术学院课程编号:L090211指导教师:刘展威报告完成日期:2015年4月19日1.实验目的♦了解ARM设备外围电路结构与接口原理♦熟悉Linux系统下硬件驱动编程♦编程实现对嵌入式设备上LED灯的控制2.实验内容♦阅读UP-Magic6410平台硬件文档,熟悉ARM处理硬件外围接口电路♦编程实现UP-Magic6410平台设备上LED驱动及应用测试程序3.实验环境♦硬件:UP-Magic6410型嵌入式实验平台,PC机Pentium500以上,硬盘40G以上,内存大于256M♦软件:VmwareWorkstation+FedoraCore8+MiniCom/Xshell+ARM-LINUX交叉编译开发环境4.实验原理4.1硬件接口原理♦UP-Magic6410魔法师实验套件LED硬件接口UP-Magic6410魔法师实验套件上共有5个LED显示灯,分别接在S3C6410X处理器的GPQ2、GPQ3、GPQ4、GPQ5、GPQ6上。5个LED显示灯分别共阳极3.3V电压,因此相应GPIO低电平点亮,高电平熄灭。如图4.1.1所示:♦S3C6410处理器GPIO寄存器S3C6410X处理器的GPIO作为控制I/O要进行必要的设置才能对外设进行正确控制,此实验将相应I/O设置为输出模式,并向相应I/O数据寄存器进行写入数据便可控制LED的开关。如下表4.1.2给出的S3C6410XGPIO寄存器配置:GPQIO寄存器列表:GPQ配置寄存器:GPQ数据寄存器:4.2关键代码分析Linux系统下,应用程序不可直接操作底层硬件寄存器,必须经过驱动层来完成对硬件的操作。♦驱动程序分析:#includelinux/module.h#includelinux/kernel.h#includelinux/fs.h#includelinux/init.h#includelinux/miscdevice.h#includelinux/delay.h#includeasm/irq.h#includeasm/arch/regs-gpio.h#includeasm/hardware.hMODULE_LICENSE(GPL);#defineDEVICE_NAMEleds//驱动名称#defineDEVICE_MAJOR231//驱动主设备号#defineDEVICE_MINOR0//驱动次设备号//声明字符设备类结构structcdev*mycdev;structclass*myclass;dev_tdevno;//LEDGPIO列表staticunsignedlongled_table[]={S3C_GPQ2,S3C_GPQ3,S3C_GPQ4,S3C_GPQ5,S3C_GPQ6,};//LEDGPIO输出类型配置列表staticunsignedintled_cfg_table[]={S3C_GPQ2_OUTP,S3C_GPQ3_OUTP,S3C_GPQ4_OUTP,S3C_GPQ5_OUTP,S3C_GPQ6_OUTP,};//LEDIOCTRL处理函数,主要完成从用户空间传递数据进行GPIO引脚设置功能staticintuptech_leds_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg){switch(cmd){case0:case1:if(arg6){return-EINVAL;}//LEDGPIO设置函数接口s3c_gpio_setpin(led_table[arg],!cmd);return0;default:return-EINVAL;}}//驱动层file_operations接口函数初始化staticstructfile_operationsuptech_leds_fops={.owner=THIS_MODULE,.ioctl=uptech_leds_ioctl,};//驱动程序入口初始化函数,设置LEDGPIO、向内核注册设备。staticint__inituptech_leds_init(void){intret;inti;//注册LED设备devno=MKDEV(DEVICE_MAJOR,DEVICE_MINOR);//获取设备号mycdev=cdev_alloc();cdev_init(mycdev,&uptech_leds_fops);//初始化字符设备err=cdev_add(mycdev,devno,1);//向系统添加LED设备if(err!=0)printk(s3cledsdeviceregisterfailed!\n);myclass=class_create(THIS_MODULE,leds);if(IS_ERR(myclass)){printk(Err:failedincreatingclass.\n);return-1;}//建立LED设备节点class_device_create(myclass,NULL,MKDEV(DEVICE_MAJOR,DEVICE_MINOR),NULL,DEVICE_NAME,DEVICE_MINOR);//LEDGPIO配置初始化for(i=0;i5;i++){s3c_gpio_cfgpin(led_table[i],led_cfg_table[i]);s3c_gpio_setpin(led_table[i],1);}printk(DEVICE_NAMEinitialized\n);return0;}//驱动卸载函数staticvoid__exituptech_leds_exit(void){//注销LED驱动设备unregister_chrdev(LED_MAJOR,DEVICE_NAME);}//声明驱动程序入口函数module_init(uptech_leds_init);//声明驱动程序出口函数module_exit(uptech_leds_exit);♦应用程序分析:#includestdio.h#includestdlib.h#includeunistd.h#includesys/ioctl.hintmain(intargc,char**argv){inti;inton;intled_number;intfd;/*根据命令行参数内容,进行控制。将命令行参数1设置成LEDnumber,参数2设置成LED点亮熄灭状态on*/if(argc!=3||sscanf(argv[1],%d,&led_number)!=1||sscanf(argv[2],%d,&on)!=1||on0||on1||led_number0||led_number5){fprintf(stderr,Usage:\n);fprintf(stderr,\t./ledled_numberon|off\n);fprintf(stderr,Options:\n);fprintf(stderr,\tled_numberfrom0to4\n);fprintf(stderr,\ton:1off:0\n);exit(1);}//打开LED设备节点fd=open(/dev/leds,0);if(fd0){perror(opendevice/dev/leds);exit(1);}//调用驱动层ioctrl接口,实现对LED控制ioctl(fd,on,led_number);for(i=0;i100;i++)usleep(1000);//关闭LED设备接口close(fd);return0;}5.实验步骤♦实验目录:/UP-Magic6410/SRC/kernel/linux-2.6.21//UP-Magic6410/SRC/exp/diver/02_leds/♦在内核中添加LED设备模块驱动1、进入宿主机中UP-UP6410-II型光盘内核目录:[root@localhost~]#cd/UP-Magic6410/SRC/kernel/linux-2.6.21/2、运行makemenuconfig命令配置内核对LED模块的相关支持选择DeviceDrivers---选项,如图进入Characterdevices---菜单选择MS3CLEDsDriver模块方式编译LED驱动,如图:退出保存配置:3、重新编译内核,运行make命令[root@localhostlinux-2.6.21]#makescripts/kconfig/conf-sarch/arm/KconfigCHKinclude/linux/version.hSYMLINKinclude/asm-arm/arch-include/asm-arm/arch-s3cmake[1]:`include/asm-arm/mach-types.h'isuptodate.CHKinclude/linux/utsrelease.hCHKinclude/linux/compile.h…………最终在内核源码目录的drivers/char/目录下生成LED驱动程序s3c-leds.ko[root@localhostlinux-2.6.21]#lsdrivers/char/s3c-leds.kodrivers/char/s3c-leds.ko[root@localhostlinux-2.6.21]#备注:以上在内核中添加对LED设备的支持的步骤,在UP-Magic6410设备出厂自带内核中已经默认添加进入了,用户可以省略以上步骤。以上步骤在于重现系统的构造。LED相应驱动已经在本实验目录的driver目录下给出。♦编译LED应用测试程序1、进入实验目录:[root@localhost~]#cd/UP-Magic6410/SRC/exp/driver/02_leds/[root@localhost02_leds]#lsMakefiledriverled.cled.oled.shtest_led[root@localhost02_leds]#2、清除中间代码,重新编译[root@localhost02_leds]#makecleanrm-ftest_led*.elf*.gdb*.o[root@localhost02_leds]#[root@localhost02_leds]#makearm-linux-gcc-c-oled.oled.carm-linux-gcc-otest_ledled.o–lm[root@localhost02_leds]#lsMakefiledriverled.cled.oled.shtest_led[root@localhost02_leds]#当前目录下生成可执行程序test_led。♦NFS挂载实验目录测试1、启动UP-Magic6410实验系统,连好网线、串口线。通过串口终端挂载宿主机实验目录。[root@UP_6410yaffs]#mountnfs192.168.1.145:/UP-Magic6410/mnt/nfs/2、进入串口终端的NFS共享实验目录。[root@UP_6410yaffs]#cd/mnt/nfs/SRC/exp/driver/02_leds/[root@UP_641002_leds]#lsMakefiledriverled.cled.oled.shtest_led[root@UP_641002_leds]#3、加载LED驱动程序。[root@UP_641002_leds]#insmoddriver/s3c-leds.koledsinitialized[root@UP_641002_leds]#此时会在UP-Magic6410型设备的/dev目录下产生/dev/leds设备节点。4、执