嵌入式Linux应用程序开发实验报告期末作业.docx

上传人:b****5 文档编号:6783680 上传时间:2023-01-10 格式:DOCX 页数:14 大小:53.20KB
下载 相关 举报
嵌入式Linux应用程序开发实验报告期末作业.docx_第1页
第1页 / 共14页
嵌入式Linux应用程序开发实验报告期末作业.docx_第2页
第2页 / 共14页
嵌入式Linux应用程序开发实验报告期末作业.docx_第3页
第3页 / 共14页
嵌入式Linux应用程序开发实验报告期末作业.docx_第4页
第4页 / 共14页
嵌入式Linux应用程序开发实验报告期末作业.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

嵌入式Linux应用程序开发实验报告期末作业.docx

《嵌入式Linux应用程序开发实验报告期末作业.docx》由会员分享,可在线阅读,更多相关《嵌入式Linux应用程序开发实验报告期末作业.docx(14页珍藏版)》请在冰豆网上搜索。

嵌入式Linux应用程序开发实验报告期末作业.docx

嵌入式Linux应用程序开发实验报告期末作业

软件学院大作业设计报告

课程名称:

嵌入式Linux应用程丿予开发

目:

基于UP-CUP2440平台的驱动程序开发和QT程序开发

业:

计算机软件

级:

计算机软件

111班

姓名

学号:

鲁飞8000611038

卢惠民8000611021

戚成林8000611032

慕一聪8000611018

刘备8000611006

任课教师:

李岚职称:

副教授

完成时间:

2014年6月11日

一、小组成员分工3

二、实验任务3

三、主要仪器设备及耗材3

四、实验步骤3

一、驱动3

1.基本知识:

4

2.实验原理:

4

3.具体实现:

5

二、QT计算器9

1.QT程序设计10

2.虚拟机下进行编译:

15

3.下载到开发板上运行:

17

六、实验数据及处理结果18

七、思考讨论题或体会或对改进实验的建议18

八、参考资料:

19

、小组成员分工

分工:

鲁飞:

QT设计与设计报告

卢惠民:

QT设计与设计报告

戚成琳:

驱动与设计报告

慕一聪、刘备:

设计报告

、实验任务

1•编写基于UP-CUP2440硬件平台的GPIO驱动程序

必选功能:

使中断按键按下后,开发板上的LED灯能作如下闪动:

a)连续性闪动,跑马灯:

如:

1-2-3-1-2-3…或3-2-1-3-2-1

b)间隔性闪动:

如:

1-3-2-1-3-2…或3-1-2-3-1-2…

进阶功能:

改变中断按键的控制功能,使中断按键按下后,LED灯不断闪亮,再

次按下后,LED灯灭。

2.QT计算器

三、主要仪器设备及耗材

PC,WindowsXp,H-JTAG,H-Flasher,DNW,开发实验箱。

四、实验步骤

一、驱动

思路:

前后台思想:

在中断模块中设置一个计数的变量,每一次中断计数器加一。

然后在GPIO驱动模块的ioctl()函数中分情况使跑马灯按要求闪动或熄灭

1.基本知识:

(1)设备驱动程序可以使用模块的方式动态加载到内核中去。

(2)模块的必需组成部分:

模块加载函数,insmod时调用。

模块卸载函数,rmmod时调用

模块许可证LICENSE说明

(3)数据结构file_operation中定义驱动程序会使用的函数。

(4)在获得了系统分配的设备号之后,必须要通过注册才能实现设备号和驱动程序之间的关联。

(5)打开设备和释放设备,没什么要特别注意的。

(6)读写设备:

把内核空间的数据复制到用户空间去,或者从用户空间复制到内核空间。

read()里面使用copy_to_user()就可以将内核空间的值传到用户空间去。

这一点在本实验的驱动程序的实现中起着至关重要的作用。

(7)ioctl()则是对IO寄存器的控制,在本实验中就要用ioctl()来实现不同的跑马灯亮灭。

2.实验原理:

UP-CUP244O幵熒平含茂置了3个GPIO制的LED.和1个可曲搂产生外酒碇件申師的在:

建.LED别悭用S3C241U/SJC244O的GPL'S,1卍(_乩GPC7(PXA270的LiPKXbGP1CH.GPIO?

;>三牛GPIO,披德接判TNT3中勘(PXA27O的GPJO97>

Rcgntor

Adckwi

KW

Dmcriplion

GPCCOM

3x56000020

FVW

S'i艸莎理口鸠ofportC

QnO

GPCDAT

2x56000024

R/W

Tneda^regsterformrtC

Undef,

GROUP

Dx5a0000?

8

R/W

PulkjpdiMUMrHgilfififafpodC

0^0

Reserved

3»i50OOM2t

GPC7

[15;14]

00=Input01=Output

10=LCD^LPCREVB11=Reserved

GPC6

[13:

12]

00=Input01■Output

10=LCDLPCREV11=Reserved

[11:

10]

00=Input01=Output

10=LCD^LPCOE11=Reserved

3•具体实现:

(1)中断驱动模块:

该模块只需在老师给的实例的基础上加以修改就行。

(1)模块初始化函数中,请求中断处理函数:

ret=request_irq(S3C2440_IRQ5,s3c2440_IRQ3_fun,SA_INTERRUPT,"S3C2440_IRQ5",NULL);

中断处理函数为:

s3c2440_IRQ3_fun()

在此中断处理函数中,用一个全局变量count在每一次中断的时候加1,由于我们的开

发板按一次会处理两次,所以计数到7的时候,必须使count恢复到1。

具体实现如下:

intcount=0;

irqreturn_ts3c2440_IRQ3_fun(intirq,void*dev_id,structpt_regs*reg)

{

printk("enterinterrupt5!

\n”);

count++;

if(count==7)

count=1;

}

(2)设备初始化:

staticint__inits3c2440_interrupt_init(void)

{

intret;

intflags;

local」rq_save(flags);

//bysprife

s3c2410_gpio_cfgpin(S3C2410_GPF5,S3C2410_GPF5_EINT5);s3c2410_gpio_pullup(S3C2410_GPF5,1);

//end

set_irq_type(S3C2440_IRQ5,/*IRQT_FALLING*/IRQT_LOW);

local」rq_restore(flags);

ret=request_irq(S3C2440_IRQ5,s3c2440_IRQ3_fun,SA_INTERRUPT,

"S3C2440_IRQ5",NULL);

if(ret){

printk("S3C2440_IRQ5request_irqfailure");returnret;

}printk(DEVICE_NAME"int05initialized\n");

return0;

}

(3)设备退出:

staticvoid__exits3c2440_interrupt_exit(void)

{free_irq(S3C2440_IRQ5,NULL);

printk(DEVICE_NAME"unloaded\n");

}

(4)module」nit()注册设备

(5)module_exit()卸载设备

(6)还有LICENSE必须要设置:

MODULE_LICENSE("GPL");

本模块最需要注意的地方:

因为count是要导出给其他模块用的,所以必须使用EXPORT_SYMBOL_GPL(count);

这就是我出错的地方之一。

(2)GPIO驱动:

(1)结构体file_operation的定义:

structfile_operationsgpio_fops={

.owner=THIS_MODULE,

.open=gpio_open,

.ioctl=gpio_ioctl,

.read=gpio_read,

.release=gpio_release,

};

(2)GPIO的模块加载部分:

必须完成字符设备的注册。

需要调用gpio_setup_cdev(),该函数用于字符设备的创建和注册函数。

首先要定义结构体变量:

staticstructcdevgpio_cdev;

该函数的具体实现:

staticvoidgpio_setup_cdev(structcdev*dev,intminor,structfile_operations*fops){

interr,devno=MKDEV(major,minor);cdev_init(dev,fops);

dev->owner=THIS_MODULE;

dev->ops=fops;

err=cdev_add(dev,devno,1);

if(err)

{

printk(KERN_NOTICE"Error%daddinggpio%d",err,minor);

}

}

(3)intgpio_open(structinode*inode,structfile*filp)打开设备时,就要设置GPIO口的电平。

设置相应的GPIO口为输出模式。

具体代码如下:

intgpio_open(structinode*inode,structfile*filp){

s3c2410_gpio_pullup(S3C2410_GPC5,0);s3c2410_gpio_pullup(S3C2410_GPC6,0);s3c2410_gpio_pullup(S3C2410_GPC7,0);s3c2410_gpio_cfgpin(S3C2410_GPC5,S3C2410_GPC5_OUTP);s3c2410_gpio_cfgpin(S3C2410_GPC6,S3C2410_GPC6_OUTP);s3c2410_gpio_cfgpin(S3C2410_GPC7,S3C2410_GPC7_OUTP);

return0;

}

(4)ssize_ts3c240_gpio_read(structfile*filp,char*buf,size_tcnt,loff_t*f_pos)

该函数要将一count值传到用户空间去,在用户空间里调用ioCtl()函数时就需要count值具体实现:

ssize_ts3c240_gpio_read(structfile*filp,char*buf,size_tcnt,loff_t*f_pos){

interr;

if(err=put_user(count,buf)<0)returnerr;

returncnt;

}

(5)接下来就是实现跑马灯控制的ioctl()了,如果count为1时,则实现按1,2,3顺序不断亮灭。

如果count为3时,则实现按1,3,2跳跃式不断亮灭。

如果count为5时,则关闭所有led灯。

具体代码实现如下:

intgpio_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg){

switch(count)

{

case1:

s3c2410_gpio_pullup(S3C2410_GPC5,0);s3c2410_gpio_pullup(S3C2410_GPC6,1);

s3c2410_gpio_pullup(S3C2410_GPC7,1);mdelay(200);

s3c2410_gpio_pullup(S3C2410_GPC5,1);

s3c2410_gpio_pullup(S3C2410_GPC6,0);

s3c2410_gpio_pullup(S3C2410_GPC7,1);mdelay(200);

s3c2410_gpio_pullup(S3C2410_GPC5,1);

s3c2410_gpio_pullup(S3C2410_GPC6,1);

s3c2410_gpio_pullup(S3C2410_GPC7,0);break;

case3:

s3c2410_gpio_pullup(S3C2410_GPC5,0);

s3c2410_gpio_pullup(S3C2410_GPC6,1);

s3c2410_gpio_pullup(S3C2410_GPC7,1);mdelay(200);

s3c2410_gpio_pullup(S3C2410_GPC5,1);

s3c2410_gpio_pullup(S3C2410_GPC6,1);

s3c2410_gpio_pullup(S3C2410_GPC7,0);mdelay(200);

s3c2410_gpio_pullup(S3C2410_GPC5,1);

s3c2410_gpio_pullup(S3C2410_GPC6,0);

s3c2410_gpio_pullup(S3C2410_GPC7,1);break;

case5:

s3c2410_gpio_pullup(S3C2410_GPC5,1);

s3c2410_gpio_pullup(S3C2410_GPC6,1);

s3c2410_gpio_pullup(S3C2410_GPC7,1);break;

default:

break;

}

}

(6)卸载模块

(7)LICENSE设置

(3)测试代码的实现:

打开GPIO设备

若打开成功则在while

(1)循环里调用read(),再调用ioctl().具体代码如下:

#include

#include

#include

#include

#include

#includeintmain(void)

{fd=open("/dev/gpio",O_RDWR|O_NONBLOCK);

if(fd<0)

{

perror("open/dev/gpioerror!

\n");

exit

(1);

}printf("open/dev/gpiosucessfully!

\n");

while

(1)

{

read(fd,&count,1);

ioctl(fd,0,0);

}

return0;

}

(四)两个模块的Makefile:

只需分别修改一下Targe,生成的模块名,和可执行文件就行。

2.操作过程:

(1)先make中断模块,生成int.ko

(2)insmodint.ko

(3)然后makeGPIO,生成gpio.ko

(4)Insmodgpio.ko然后分配一个设备号241

(5)生成结点:

mknod/dev/gpioc2410

(6)再回到int目录下,也生成结点。

mknod/dev/intc2400

(7)可以lsmod/dev/XX看是否成功安装设备驱动

(8)交叉编译test.c

(9)运行驱动测试程序./test,按键进行测试。

二、QT计算器

QT计算器的开发环境主要是VMware下的编译、xp下的超级终端、以及win7下的qt-creator的程序的编译和调试。

1.QT程序设计

由于qt-creator在win7下具有调试功能,编写程序相对比较容易

主要用到的软件是qt-creator:

界面如下:

计算器界面设计如下:

为按钮添加槽函数:

在calculor.h函数中自动生成相应的函数,如下:

再在calculor.cpp函数中为每个函数实现相应的代码功能:

对于数字按键的处理类似,如下:

主要调用trans函数:

对于符号的函数处理类似,如下:

主要调用cal函数进行计算:

 

清零函数:

回退函数:

 

等号的处理函数:

正负号的处理函数:

优点:

可以实现回退、正负号逻辑处理,保留两位小数精度、可以实现混合运算(连加、或连乘灯)在操作的过程中有一点需要注意,是按完数字键以后再按正负号。

2.虚拟机下进行编译:

需要注意的是,一定要用QtEmbeddec下进行编译,否则在开发板端将不能运行将可执行程序拷到NFS共享目录下:

在test_QT下修改批处理程序:

保存退出即可,在开发板端执行的时候就直接执行test.sh文件

 

3•下载到开发板上运行:

首先需要对开发板进行初始化配置,即执行校准文件及其之后的一些配置,具体见实验九

执行校准文件:

D2

Lv-1tich:

/Mni/nfs/Frolletech/binled..ID:

Couildniop^ntslibconfigfile:

Nosuchfileordirec(ory

ls_config:

11seekttydf

ui0-1:

/mit/nts/1rol1etechNed..

Lip-tAch:

/MntHI辭

123SRC曰sthello!

ptyz2It^ul

k,cttynf

4'」

ui>-tech:

/iRM/nfs**cdTrolltech/up-tech:

Znnt/nfs/Troiltech-*ls

up-tccti:

/imt/nfs/TrolltechNedQtfvt)9dded-fi6R-jri■/

tn-tach:

/■nt/nf5/TrQlltech/fltFubedded-*.k.fl-ar»^RxpfjriQTDIR=宇PHD

<0IFKihH^k)f»d(.44).-ir»

tv)-[ech:

/Hnt/nF^/lrDlltedi/DLtabedded-4.4.0-drntteMporiLAHG*zh_CNkV-tedi:

/Hit/nfs/Tr

/*irt/nf^/Trollt9ch/fltE*iw

tiiidkeis_calibratets_printis_tesl

up-tech:

/pnt/hf^/Trnl1trrli/Qtrubfrddrd-i4.e-or»/binIt./ts_calibrnicCbuldntloadnodulepthrtsthrd"lesloaded

Is_cchli9Sikc^sjs

uo・Ltiih:

Fwit/nfs/Trollicch/€tEiib

(i・4,&.0-ar^FbinH_

Hexport盹叩ortMex^grtHexportHexportHexporIHoxportHtj-xhortHexuort

LilLIBftmPRTH=tPHD/libTSLIB-ISDEVICE=/deu/ewnWTSITR_PIJCTNUFR-(PWD/lib/ts1SIIECONSO.FDIVTCF-ntnp1SL1BCUWFlLE-tPHD/eWixconfPOINiTERCRLFlLE=*PWD/«tc/ts-callb.confQMSMOUSEPftOTO=tslib:

/dcv/cventDTUBCftLlBFlLE=tPWD/etc/ts-caIib.ccnf01QUSFONTDIMCPHD/lih/F«)ts

I?

■!

|U€Wireoi-fl-KL

rr

TMtrdQixi.Lfa馨如MKik±IbA

|*

*4-Sift啊定

电总

 

最后执行批处理程序:

六、实验数据及处理结果

见实验步骤

七、思考讨论题或体会或对改进实验的建议

本次实验经过反复进行,最终还是有收获的,从一开始什么都不懂,到最后掌握了设备驱动程序的结构,以及实现过程中一些要注意的问题。

我们搜索了大量资料,并且通过同学的帮助,了解了许多额外的但必须要用到的知识:

1.extern:

引用其他文件里的变量必须使用。

2.put_user(),get_user()

copy_to_user()

copy_from_user()

在内核空间和用户空间交换数据时,get_user和put_user是两个两用的函数。

相对于copy_to_user和copy_from_user将在另一篇文中分析),这两个函数主要用于完成一些简单类型变量(char、int、long等)的拷贝任务,对于一些复合类型的变量,比如数据结构或者数组类型,get_user和put_user函数还是无法胜任

,这两个函数内部将对指针指向的对象长度进行检查,在arm平台上只支持长度为1,

2,4,8的变量。

copy_to_user--Copyablockofdataintouserspace.copy_from_user--Copyablockofdatafromuserspace.get_user--Getasimplevariablefromuserspace.put_user--Writeasimplevalueintouserspace.

3.系列函数的定义在arch/arm/mach-s3c2410/gpio.c,相关的宏定义在include/asm-arm/arch-s3c2410/regs-gpio.h

(1)voids3c2410_gpio_setpin(unsignedintpin,unsignedintto);

设置相应GPIO口的输出值,例如:

pin=S3C2410_GPG2,to=0,则设置S3C2410_GPG2的输出值为0;pin=S3C2410_GPG2,to=1,则设置S3C2410_GPG2的输出值为1。

(2)unsignedints3c2410_gpio_getpin(unsignedintpin);

获取相应GPIO口的值。

3)voids3c2410_gpio_cfgpin(unsignedintpin,unsignedintfunction);

设置相应GPIO口的工作模式,输入、输出、中断等。

(4)unsignedints3c2410_gpio_ge

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

当前位置:首页 > 医药卫生 > 基础医学

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

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