ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:50.05KB ,
资源ID:5288320      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5288320.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(嵌入式程序设计大作业1.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

嵌入式程序设计大作业1.docx

1、嵌入式程序设计大作业1大连理工大学本科实验报告课程名称: 嵌入式程序设计 学院(系): 软件学院 专 业: 嵌入式 2011年 5月 28日 实验3: ARM7/uClinux 驱动设计实验一、 实验目的和要求通过实验了解 uClinux 设备驱动程序模块结构; 通过实验掌握 uClinux 字符设备驱动程序编写; 通过实验了解 Embest EduKit III 44B0核心子板 LED驱动程序原理。二、 实验原理和内容1. uClinux设备驱动程序概述uClinux 设备驱动程序为特定的硬件提供给用户程序的一组标准化接口,它隐藏了设备工作的细节。用户程序通过标准化系统调用,这些调用和特定

2、的硬件是无关的,再由 uClinux内核调用特定的设备驱动程序操作和控制特定的实际的硬件设备。 uClinux 系统的设备分为三种类型,分别是字符设备(character device),块设备(block device)和网络接口(network interface)。字符设备是能够像字节流一样被访问的设备,一般不使用缓存技术。字符设备驱动程序最少应实现 open、close、read 和 write 系统调用。典型的字符设备例子是终端设备(/dev/console)和串口(/dev/ttys0)。2. LED 电路设计三、 主要仪器设备硬件:PC 机,Embest EduKit III 4

3、4B0 核心子板,Embest ARM 标准/增强型仿真器套件; 软件:RedHat 9.0 操作系统、uClinux 交叉编译工具链、flash 烧写工具、超级终端。四、实验步骤与操作方法1. 编译驱动程序当把 LED 设备驱动程序编写好以后,需要把它编译进内核。当用户打开设备时,还需要一个在/dev 目录的设备文件名称,这样驱动程序才能工作。下面分步骤来介绍如何把驱动程序编译进内核以及创建设备文件名称。 (1)在/uClinux-dist/linux-2.4.x/drivers 目录下新建名为 led 的文件夹,把 led 驱动程序和makefile复制到其中。 (2)修改/uClinux

4、-dist/linux-2.4.x/drivers/Makefile 文件,在 Makefile 中添加如下加粗代码。 # Makefile for LED drivers #mod-subdirs := dio hil mtd sbus video macintosh usb input telephony ide message/i2o message/fusion scsi md ieee1394 pnp isdn atm fc4 net/hamradio i2c acpi bluetooth usb/gadget subdir-y := parport char block net s

5、ound misc media cdrom hotplug subdir-y += led subdir-m := $(subdir-y) (3)修改/uClinux-dist/linux-2.4.x/Makefile文件,在“DRIVERS-y :=”之后,添加如下加粗代码,这样在连接 uClinux 内核映像文件时,能把 led.o连接进去。 DRIVERS-n := DRIVERS-y := DRIVERS-$(CONFIG_ACPI_BOOT) += drivers/acpi/acpi.o DRIVERS-$(CONFIG_PARPORT) += drivers/parport/dri

6、ver.o DRIVERS-y += drivers/char/char.o drivers/block/block.o drivers/misc/misc.o drivers/net/net.o DRIVERS-y += drivers/led/led.o(4)修改/uClinux-dist/vendors/Embest/EduKit/Makefile文件, 在”DRIVERS =”后,添加如下加粗代码“led0,c,60,0”。其中 led0 为设备名称,c 代表字符设备,60 为主设备号,最后一个 0 是从设备号。主设备号与驱动程序注册时的主设备号要求一致,否则用户程序用设备文件名称请求

7、打开设备时,内核无法根据主设备号找到对应的设备驱动程序。 DEVICES = tty,c,5,0 console,c,5,1 cua0,c,5,64 cua1,c,5,65 led0,c,60,0 (5)完成以上修改后,重新构造 romfs和内核映像文件,并烧录到开发板的 FLASH上。 (6)最后,启动 uClinux。使用 cp 命令,简单测试一下 LED驱动程序。把任意一个文件复制到 led 设备上,检查是否能点亮其中某个 LED。例如在 uClinux 输入终端执行如下命令: $ cp /bin/init /dev/led0 观察并记录实验现象。 2. 测试驱动程序(1)准备实验环境,

8、使用 Embest EduKit44B0目标开发板附带的串口线分别连接到目标板上的 UART0 和 PC机的串口,将 Embest 仿真器的 JTAG接口与 Embest EduKit的 JTAG 接口相连,仿真器的 PARALLEL 接口与 PC机的并口相连。 (2)在 PC 机上运行 Windows 附件中自带的超级中断串口通信程序(波特率 115200、1位停止位、无检验位、无硬件流控制);或者使用其它串口通信程序。 (3)交叉编译 led 测试程序 test-led。 (4)编译好测试程序后,启动目标板的 uClinux 操作系统,在 PC 机上观察超级终端程序主窗口,可以看到如下界面

9、: Sash command shell (version 1.1.1) / 在 PC 机上运行 tftp 服务端程序,设置好传送文件路径,通过以太网使用 tftp 把test-led 下载到/var目录下。在 uClinux的输入终端里输入如下命令: cd var /var tftp g 192.168.0.101 r ./test-led (此处 IP地址可能不同) (5)修改 test-led 程序的属性,使其拥有可执行属性,然后运行 test-led。观察 test-led点亮目标开发板上的 LED的情况,并描述。 var chmod 777 test-led var ./test-l

10、ed 2. 编写驱动程序 编写测试程序,让各个 LED以人眼能够识别的频率依次闪烁,每个 LED持续闪烁大约3 秒钟,找到编号为 14 的 LED在实验板上的布局,绘制布局图,添加到实验报告中。四、 实验数据记录和处理驱动程序代码:/* linux/deriver/led/ekii-led.c* led driver for Embest EduKit II* Copyright (C) 2005 Embest */#include #include #include #include #include #include / error codes#include / size_t#inclu

11、de / mdelay#include #include #undef DEBUG#ifdef DEBUG#define TRACE(str, args.) printk(led: str, # args)#else#define TRACE(str, args.)#endif/TRACE没用#define LED_MAJOR 60 /设备号#define LED_DEVNAME led /设备名称#define GPC_MASK (38) /掩码.pc8/pc9#define GPF_MASK (35) | (c&0x100)7) | (f&0x10)3) | (f&0x08)3) )/把b

12、、f的值组合为一个8位数据/ 3 2 1 0 / pc8 pc9 pf4 pf3#define SET_DATA(t, c, f) ( c = (t&0x08)5) | (t&0x04)7), f = (t&0x02)3) | (t&0x01)lock); /信号量#define LED_UNLOCK(u) up(&u-lock); /信号量struct unit /定义一个结构类型,成员是整型指针,代表各个口寄存器,以及两个变量 struct semaphore lock; /定义信号量 u32 *PCONC; /* PCONB register */ u32 *PDATC; /* PDAT

13、B register */ u32 *PCONF; /* PCONF register */ u32 *PDATF; /* PDATF register */ u32 *PUPF; /* PUPF register */ u32 c; /* store LED 1 and LED 2 value */ u32 f; /* store LED 3 and LED 4 value */;static char *version = Embest Edukit-II led driver version 1.0 (2005-04-18) n;static struct unit led_unit =

14、 /给结构体变量部分成员赋值 .PCONC = (u32 *)S3C44B0X_PCONC, .PDATC = (u32 *)S3C44B0X_PDATC, .PUPC = (u32 *)S3C44B0X_PUPC, .PCONF = (u32 *)S3C44B0X_PCONF, .PDATF = (u32 *)S3C44B0X_PDATF, .PUPF = (u32 *)S3C44B0X_PUPF,;static void led_set_value(struct unit *unit, u8 val) /设置pc、pf口的值,初始化时用到两次,第一次val是0x0f,第二次是0 u32 t

15、emp; SET_DATA(val, unit-c, unit-f); /第一次:用0x0f 给c、f 赋值为:0、0。点亮4个led /第二次:用0给c、f赋值,使pc8、pc9、pf4、pf3均为1,关闭4个led /写函数还要多次调用本函数 temp = *unit-PDATC; /取pb口状态 temp &= GPC_MASK; /清pb4、pb5 temp |= unit-c; /用新值更新temp *unit-PDATC = temp; /写回pc口 temp = *unit-PDATF; temp &= GPF_MASK; temp |= unit-f; *unit-PDATF

16、= temp;static u8 led_get_value(struct unit *unit) u8 temp = GET_DATA(unit-c, unit-f); return temp;static int led_open(struct inode *inode, struct file *file) TRACE(openn); file-private_data = &led_unit; /这个操作为read服务 MOD_INC_USE_COUNT; return 0;static int led_release(struct inode *inode, struct file

17、*file) TRACE(releasen); MOD_DEC_USE_COUNT; /模块引用计数自减 return 0;static ssize_t led_read(struct file *file, char *buf, size_t count, loff_t *offset) u8 temp; int ret; struct unit *unit = (struct unit *)file-private_data; /使在read函数中可以访问硬件寄存器 TRACE(readn); if(count 1) count = 1; LED_LOCK(unit); /信号量操作 te

18、mp = led_get_value(unit); /读数据 ret = copy_to_user(buf, &temp, count) ? -EFAULT : count; /把数据从内核空间拷贝到用户空间, /copy_from_user、copy_to_user函数返回不能被复制的字节数, /因此,如果完全复制成功,返回值为0。 LED_UNLOCK(unit); /信号量操作 return ret;static ssize_t led_write(struct file *file, const char *buf, size_t count, loff_t *offset) u8 t

19、emp; int ret; struct unit *unit = (struct unit *)file-private_data; /使在write函数中可以访问硬件寄存器 TRACE(writen); if(count 1) count = 1; LED_LOCK(unit); /信号量操作 ret = copy_from_user(&temp, buf, count) ? -EFAULT : count; /把数据从用户空间拷贝到内核空间 if(ret) led_set_value(unit, temp); LED_UNLOCK(unit); /信号量操作 return ret;sta

20、tic struct file_operations led_ops = owner: THIS_MODULE, read: led_read, write: led_write, open: led_open, release: led_release,;/* led device init*/static void _init led_init(struct unit *unit) u32 temp; /* init device lock */ init_MUTEX(&unit-lock); /* init io port */ temp = *unit-PCONC; temp &= (

21、316) | (318); /16、17、18、19均0,表示pf3、pf4输入 temp |= (116) | (1PCONC = temp; temp = *unit-PUPC; temp |= (3PUPC = temp; temp = *unit-PCONF; temp &= (38) | (36); /6、7、8、9均0,表示pf3、pf4输入 temp |= (18) | (1PCONF = temp; temp = *unit-PUPF; temp |= (3PUPF = temp; /* init data and turn on led*/ led_set_value(uni

22、t, 0x0f); /* delay some time */ mdelay(100); /* turn off led */ led_set_value(unit, 0x00);/* module init*/int _init led_init_module(void) int res; TRACE(init_modulen); /* print version information */ printk(KERN_INFO %s, version); /* register led device */ res = register_chrdev(LED_MAJOR, LED_DEVNAM

23、E, &led_ops); if(res 0) printk(ekii-led.o: unable to get major %d for led device.n, LED_MAJOR); return res; /* then call led_init() */ led_init(&led_unit); return 0;/* module cleanup*/void _exit led_cleanup(void) int res; TRACE(cleanupn); /* unregister led device */ res = unregister_chrdev(LED_MAJOR

24、, LED_DEVNAME); if(res 0) printk(ekii-led.o: unable to release major %d for led device.n, LED_MAJOR);module_init(led_init_module);module_exit(led_cleanup);MODULE_DESCRIPTION(EduKit-II led driver);MODULE_AUTHOR(Embest tech&info Co.,Ltd. );MODULE_LICENSE(GPL);测试程序代码:#include #include #include #include

25、 #define LED_NUM 4int main(int argc, char* argv) int i, j, wval, rval, fd; printf(Test LED.n); /* open led device */ fd = open(/dev/led0, O_RDWR); /* test single led */ while(1) for(i=0; i3; i+) for(j=0; jLED_NUM; j+) wval = 1j; write(fd, &wval, 1); read(fd, &rval, 1); printf(Turn on LED%d, readback val = 0x%02Xn, j+1, rval); /* delay 500ms */ usleep(3000*1000); /* close led device */ close(fd); return 0;六、实验结果与分析将驱动程序添加到文件系统,重新编译文件系统和内核映像,将编译好的内核映像烧写到目标板上,重启目标板,使用tftp将驱动测试程序传入到目标板中,运行测试程序,试验箱上的4个LED灯按顺序依次点亮。 七、讨论、建议、质疑1. 考虑到自动匹配不同寄存器的长度,在给寄存器置位时,对数据进行使用取非操作可以自动补齐到寄存器的长度。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1