嵌入式硬件综合设计课程设计报告Word格式.docx

上传人:b****2 文档编号:819314 上传时间:2023-04-29 格式:DOCX 页数:28 大小:299.80KB
下载 相关 举报
嵌入式硬件综合设计课程设计报告Word格式.docx_第1页
第1页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第2页
第2页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第3页
第3页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第4页
第4页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第5页
第5页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第6页
第6页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第7页
第7页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第8页
第8页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第9页
第9页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第10页
第10页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第11页
第11页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第12页
第12页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第13页
第13页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第14页
第14页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第15页
第15页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第16页
第16页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第17页
第17页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第18页
第18页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第19页
第19页 / 共28页
嵌入式硬件综合设计课程设计报告Word格式.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

嵌入式硬件综合设计课程设计报告Word格式.docx

《嵌入式硬件综合设计课程设计报告Word格式.docx》由会员分享,可在线阅读,更多相关《嵌入式硬件综合设计课程设计报告Word格式.docx(28页珍藏版)》请在冰点文库上搜索。

嵌入式硬件综合设计课程设计报告Word格式.docx

指导教师:

石磊

日期:

2016年5月19日

指导老师评阅成绩表

项目方案(10%)

设计质量(35%)

合作情况(5%)

答辩(20%)

设计报告(30%)

总分

课程答辩记录

教师主要

提问记录

1.编译驱动与编译应用程序有什么区别。

2.wake_up_interruptible(&

key_waitq)函数有什么作用。

3.按键消抖的原理。

学生回答

问题情况

1.编译驱动是依赖于与开发板相同版本的linux源码,而编译应用程序则是依赖操作系统提供的接口,和头文件。

2.唤醒注册在等待队列中的进程。

3.按键在按下之后波形不稳定,延时一段时间看按键是否真的按下,一般延时时间是20ms。

课程答辩成绩评定

答辩成绩

是否同意通过

□同意□不同意

答辩教师签名:

年月日

注:

课程设计类课程答辩不通过则课程考核不通过。

摘要

随着物联网的发展,人们对物联网的认识也越来越深,而物联网分为三个大层:

感知层,传输层,应用层。

而感知层是最下面的那一层,也就是各种传感器,这么多传感器,就少不了传感器的驱动编写,而驱动编写就变得很重要,稳定的驱动,才能提供稳定的服务。

为后面的传输,应用提供保障。

本次课程设计主要完成对S3C2440平台上按键控制LED,定时器的程序设计。

在linux-2.6.28内核中编译S3C2440的LED驱动,按键驱动,然后下载到开发板上,加载之后,再PC机上编写相应的应用程序,然后交叉编译后下载到开发板,完成对LED,定时器的控制。

关键词:

物联网linux-2.6.28驱动内核

目录

1引言1

1.1课题背景1

1.2本课题研究的迫切性1

1.3本课题的研究作用1

1.4本文的主要工作1

2系统功能需求2

2.1系统目标2

2.2开发环境及工具2

2.2.1Ubuntu14.102

2.2.2交叉编译工具2

2.2.3Minicom3

2.2.4Linux源文件5

2.2.5FL2440开发板6

2.3按键电路7

2.4LED电路8

3系统实现8

3.1LED驱动8

3.2按键驱动10

3.3应用程序15

4测试与问题18

结论21

参考文献21

引言

1.1课题背景

随着物联网的发展,嵌入式应用范围越来越广,涉及到人们生活的方方面面,如数字通信、信息家电、工业控制、智能交通等。

嵌入式技术与人们的日常生活联系得越来越紧密,消费电子、计算机、通信一体化趋势日益明显,作为计算机领域的一个重要组成部分,嵌入式系统再度成为研究与应用的热点。

本次课程设计主要针对物联网硬件底层开发的学习,了解开发板与宿主机的开发模式,以及字符设备驱动的开发流程,最终实现按键控制LED、定时器。

1.2本课题研究的迫切性

嵌入式硬件综合设计作为一门实践课,极好的将以前学的理论知识与实际结合起来,帮学生有效的提高了动手能力,了解了底层驱动的开发流程,对以后学习也有积极的作用。

1.3本课题的研究作用

了解了底层驱动的基本开发框架和流程,熟悉linux的开发环境,学习了字符设备驱动的编写,了解了内核的配置,编译,交叉环境的配置,宿主机与开发板的通信方式。

1.4本文的主要工作

介绍了基于嵌入式Linux平台的按键驱动程序设计与实现的原理和流程,说明了在开发过程遇到的错误以及完成状况。

系统功能需求

系统目标

利用FL2440按键,编写相关驱动程序,实现对Led灯的控制,S1键开启跑马灯,灯亮的时间为0.5秒,每个灯之间的点亮的时间间隔为1s,S2键控制16进制计时器,时钟为2秒,S3在S1与S2的模式下暂停,Led显示为按下时的状态。

开发环境及工具

2.2.1Ubuntu14.10

2.2.2交叉编译工具

什么是交叉编译

在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译。

这个编译过程就叫交叉编译。

简单地说,就是在一个平台上生成另一个平台上的可执行代码。

如keil软件,在keil上编译,但在单片机上运行,典型的交叉编译。

我们在开发板上运行的程序,是在PC机上编译的,所以是交叉编译。

交叉编译器

交叉编译器就是交叉编译的工具,linux2.6.28内核使用的编译器为3.4.1版本,该版本的编译器可以在网上下载,当然FL2440开发板光盘中提供了该编译器。

安装交叉编译器:

只需将该编译器的解压缩文件放在指定的目录下边。

指定目录为:

/usr/local/arm/若local下没有arm文件夹,则需要自己建一个。

在使用的时候有两种方式:

(以编译hello.c程序为例,生成可执行文件hello)

(1)#/usr/local/arm/3.4.1/bin/arm-linux-gcchello.c–ohello

(2)编辑/etc/bash.bashrc文件,

在最后增加路径:

exportPATH=/usr/local/arm/3.4.1/bin:

$PATH,

这样就把/usr/local/arm/3.4.1/bin添加到命令的默认路径,在编译的时候则可直接用如下的命令#arm-linux-gcchello.c–ohello

2.2.3Minicom

Ubuntu的源里有minicom,用下面命令安装minicom。

在终端里输入以下命令:

安装:

sudoget-aptinstallminicom(虚拟机要联网)

配置:

sudominicom-s

会出现图2-1界面:

图2-1

选择Serialportsetup配置如图2-2所示:

图2-2

A选项是选择串口驱动文件,linux不用安装驱动,自己带的有。

如果用的是USB转串口就是上图的这种路径,如果是虚拟机添加的串口就是/dev/ttyS0

E选项波特率和数据停止位设置。

F硬控流,一般设置为NO。

选择Filenamesandpaths,出现图2-3界面:

图2-3

A选项是开发板传到PC机的文件存储路径,可以自己设置。

B选项是PC机下载到开发板的文件存储路径,只有把文件放到这个文件夹,在下载界面才能看到文件。

确定退出之后,选择Savesetupasdfl保存为默认的配置。

之后就会进入minicom的主界面。

按Ctrl+A,再按Z,就能打开图2-4帮助界面:

图2-4

可以看到S是发送文件,R是接收文件。

这些选项都是要按了Ctrl+A之后才可以选择的。

2.2.4Linux源文件

先再根目录下建立一个文件夹FL2440,然后去

http:

//www.kernel.org/pub/linux/kernel/v2.6/下载linux的源码,下载完毕后把压缩包放在刚刚建立的FL2440的文件夹里。

然后用下面命令解压:

tar–jxvflinux-2.6.28.7.tar.bz2

解压后目录下会多一个linux-2.6.28.7目录,然后修改linux-2.6.28.7/Makefile文件的内容。

将ARCH 

?

=$(SUBARCH)

CROSS_COMPILE 

修改为

ARCH 

=arm

=arm-linux-

然后再目录下执行makezImage在/arch/arm/boot生成内核镜像。

2.2.5FL2440开发板

FL2440是由飞凌嵌入式技术有限公司设计生产的一款嵌入式开发平台,它基于三星公司的ARM9处理器S3C2440A,内部带有全性能的MMU(内存处理单元),适用于设计移动手持设备类产品。

FL2440开发板采用核心板+底板设计,性能稳定可靠,具有高性能、低功耗、接口丰富和体积小等优良特性。

目前已成功移植Linux,WINCE等操作系统到FL2440开发板。

S3C2440介绍

体系结构:

—16/32位RISC体系结构和ARM920T内核指令集。

—采用ARM920TCPU内核支持ARM调试体系结构。

系统管理器

—支持大/小端模式。

—8个存储器bank,其中6个适用于ROM、SRAM和其它,另外两个适用于ROM/SRAM和同步DRAM。

—支持各种型号的ROM引导(NOR/NANDFLASH、EEPROM,或其它)。

DNANDHFLASH启动引导

—支持从NANDFLASH存储器直接启动。

—采用4KB内部缓冲器进行启动引导。

—启动之后NAND存储器仍然可作为外部存储器使用

中断控制器

—60个中断源(1个看门狗定时器,5个定时器,9个UARTs,24个外部中断,4个DMA,2个RTC,2个ADC,1个IIC,2个SPI,1个SDI,2个USB,1个LCD,1个电池故障,1个NAND和2个摄像头)1个AC97。

—支持电平/边沿触发模式的外部中断源。

—可编程的边沿/电平触发模式选择。

—支持为紧急中断请求提供快速中断(FIQ)服务。

通用I/O端口

—24个外部中断端口。

—多功能输入/输出端口。

看门狗定时器

—16位看门狗定时器。

—在定时器溢出时发生中断请求或系统复位。

工作电压

—内核:

1.2V,最高300MHz。

1.3V,最高400MHz。

—存储器:

1.8V/2.5V/3.0V/3.3V。

—IO口:

3.3V。

按键电路

FL2440有四个按键,接的IO口分别是GPF0,GPF2,GPF3,GPF4。

对应的中断为ENIT0,EINT2,EINT3,EINT4。

按键没有按下,IO口为高电平,按下后IO口为低电平。

电路图如图2-5所示

图2-5

LED电路

FL2440有四颗LED,分别接的IO口为:

GPB5,GPB6,GPB8,GPB10。

当IO口为低电平时点亮LED。

电路图如图2-6所示

图2-6

系统实现

LED驱动

LED驱动框架如图3-1。

图3-1

驱动代码:

从图2-6中可以看出,LED是共阳极。

IO口输出低电平点亮。

由于LED只需要控制,所以在驱动程序员里只用ioctl就可以了,不用写read,write等函数。

IO控制函数,应用程序调用ioctl的时候就会调用这个函数,控制LED。

cmd:

1:

LED点亮0:

LED熄灭。

从电路图看出IO口0点亮,在应用程序里我们一般认为1是点亮,所以在驱动程序里把cmd取反了。

arg:

LED的个数,由于板子上有四个LED,所以输入大于4,返回错误。

staticints3c2440_leds_ioctl(

structinode*inode,

structfile*file,

unsignedintcmd,

unsignedlongarg)

{

switch(cmd)

{

case0:

case1:

if(arg>

4)

{

return-EINVAL;

}

s3c2410_gpio_setpin(led_table[arg],!

cmd);

return0;

default:

return-EINVAL;

}

}

设备结构体,当应用程序调用相应的系统调用后,就会调用驱动里对应的函数。

staticstructfile_operationss3c2440_leds_fops={

.owner=THIS_MODULE,

.ioctl=s3c2440_leds_ioctl,

};

按键驱动

按键驱动框架如图3-2。

图3-2

在这里,按键采用中断的方式,不占用处理器的资源。

OPEN函数,在这个函数里实现了IO口的配置,中断的申请,中断的注册,初始化按键的初始状态,初始化了三个按键消抖定时器。

staticintkeys_open(structinode*inode,structfile*file)

inti;

intret;

for(i=0;

i<

KEY_COUNT;

i++)

s3c2410_gpio_cfgpin(key_irq[i].pin,key_irq[i].pin_set);

set_irq_type(key_irq[i].irq,IRQ_TYPE_EDGE_FALLING);

ret=request_irq(key_irq[i].irq,keys_interrupt,IRQF_DISABLED,key_irq[i].name,(void*)i);

if(ret)

{

break;

}

key_status[i]=KEY_UP;

setup_timer(&

key_timers[i],keys_timer,i);

if(ret)

i--;

for(;

i>

=0;

i--)

disable_irq(key_irq[i].irq);

free_irq(key_irq[i].irq,(void*)i);

return-EBUSY;

return0;

读取函数,返回三个按键的状态。

staticintkeys_read(structfile*file,char__user*buf,size_tcount,loff_t*offp)

unsignedlongret;

if(!

rd_flag)

if(file->

f_flags&

O_NONBLOCK)

return-EAGAIN;

}else

wait_event_interruptible(key_waitq,rd_flag);

rd_flag=0;

ret=copy_to_user(buf,(void*)key_status,min(sizeof(key_status),count));

returnret?

-EFAULT:

min(sizeof(key_status),count);

驱动中的轮询。

这个与应用程序的select使用相对应。

staticunsignedintkeys_poll(structfile*file,structpoll_table_struct*wait)

unsignedintmask=0;

poll_wait(file,&

key_waitq,wait);

if(rd_flag)

mask|=POLLIN|POLLRDNORM;

returnmask;

关闭函数,在应用程序调用close()关闭文件时调用。

staticintkeys_close(structinode*inode,structfile*file)

del_timer(&

key_timers[i]);

disable_irq(key_irq[i].irq);

free_irq(key_irq[i].irq,(void*)i);

设备操作结构体的定义,由于按键是输入设备,所以没有write,因为程序中要实时监测哪个键按下,所以这里用poll来在内核中遍历,来提供给应用程序的select判断资源是否可读取。

staticstructfile_operationskeys_fops=

.open=keys_open,

.release=keys_close,

.read=keys_read,

.poll=keys_poll,

按键中断处理函数。

用request_irq()将相应的中断和中断处理函数关联起来,当有按键按下进入这个函数,然后启动一个消抖定时器。

staticirqreturn_tkeys_interrupt(intirq,void*dev_id)

intkey=(int)dev_id;

if(key_status[key]==KEY_UP)

key_status[key]=KEY_UNCERTAIN;

key_timers[key].expires=jiffies+KEY_TIMER_DELAY1;

add_timer(&

key_timers[key]);

returnIRQ_RETVAL(IRQ_HANDLED);

定时器中断处理函数。

消抖之后进入这里,再读取按键的状态,如果按下,就把可读标志置1。

staticvoidkeys_timer(unsignedlongarg)

intkey=arg;

intup=s3c2410_gpio_getpin(key_irq[key].pin);

up)

if(key_status[key]==KEY_UNCERTAIN)

key_status[key]=KEY_DOWN;

rd_flag=1;

wake_up_interruptible(&

key_waitq);

key_timers[key].expires=jiffies+KEY_TIMER_DELAY2;

}else

key_status[key]=KEY_UP;

应用程序

编写用户程序过程中,通过open函数打开设备,通过调用相应的函数控制设备。

程序流程如图3-3

图3-3

应用程序与驱动调用关系如图3-4。

图3-4

程序代码:

跑马灯线程函数

void*ledpth(void*arg)

int*p=(int*)arg;

intfd=*p;

while

(1)

ledshow(fd);

主函数,创建两个线程。

分别是LED线程是16进制定时器线程。

intmain()

err=pthread_create(&

ledtid,NULL,ledpth,&

ledfd);

timetid,NULL,timepth,&

time);

{ret=select(keyfd+1,&

rds,NULL,NULL,NULL);

if(FD_ISSET(keyfd,&

rds))

ret=read(keyfd,key_status,sizeof(key_status));

if(ret!

=sizeof(key_status))

printf(“readfail\n”);

else

if(key_status[KEY1]==0)

{

ledflag=1;

}

if(key_status[KEY2]==0)

timeflag=1;

if(key_status[KEY3]==0)

if(ledflag==1)

ledflag=0;

if(timeflag==1)

timeflag=0;

}}}}}

测试与问题

加载驱动

图4-1

图4-2

建立设备文件节点

先cat/proc/devices驱动的主设备号

图4-3

然后在/dev目录下建立节点

图4-4

按下S2,跑马灯开启

图4-5

图4-6

按下S3,输出2s定时信息

图4-7

按下S4,定时输出暂停,跑马灯暂停,并且灯的状态就是暂停的那个状态

图4-8

图4-9

再按下S2,跑马灯启动

图4-10

再按下S3,输出2s定时信息

图4-11

结论

本设计经过一个多月的努力,基本实现了题目的要求。

实现了按键控制跑马灯开启与暂停,并且暂停跑马灯是暂停的那个状态。

按键暂停定时2s等功能。

在编写驱动期间,学习到很多课堂上没有的知识,还积累了很多实践经验,增强了动手能力和解决实际问题的能力。

在此之前,对于驱动和其他的编程知识只是略知皮毛,都没有编过驱动程序,对驱动也没有深入了解。

在短短两个月时间里,认真的学习了linux下字符驱动的编写,还有在驱动中申请中断,以及内核空间向用户空间传递数据等相关的编程知识,初步认识到驱动程序对于应用程序的重要性,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2