嵌入式程序设计大作业1Word格式文档下载.docx

上传人:b****6 文档编号:18269619 上传时间:2022-12-14 格式:DOCX 页数:12 大小:50.05KB
下载 相关 举报
嵌入式程序设计大作业1Word格式文档下载.docx_第1页
第1页 / 共12页
嵌入式程序设计大作业1Word格式文档下载.docx_第2页
第2页 / 共12页
嵌入式程序设计大作业1Word格式文档下载.docx_第3页
第3页 / 共12页
嵌入式程序设计大作业1Word格式文档下载.docx_第4页
第4页 / 共12页
嵌入式程序设计大作业1Word格式文档下载.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

嵌入式程序设计大作业1Word格式文档下载.docx

《嵌入式程序设计大作业1Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《嵌入式程序设计大作业1Word格式文档下载.docx(12页珍藏版)》请在冰豆网上搜索。

嵌入式程序设计大作业1Word格式文档下载.docx

#MakefileforLEDdrivers

#

mod-subdirs:

=diohilmtdsbusvideomacintoshusbinputtelephonyide\

message/i2omessage/fusionscsimdieee1394pnpisdnatm\

fc4net/hamradioi2cacpibluetoothusb/gadget

subdir-y:

=parportcharblocknetsoundmiscmediacdromhotplug

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/driver.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是从设备号。

主设备号与驱动程序注册时的主设备号要求一致,

否则用户程序用设备文件名称请求打开设备时,内核无法根据主设备号找到对应的

设备驱动程序。

DEVICES=\

tty,c,5,0console,c,5,1cua0,c,5,64cua1,c,5,65\

\

led0,c,60,0\

(5)完成以上修改后,重新构造romfs和内核映像文件,并烧录到开发板的FLASH上。

(6)最后,启动uClinux。

使用cp命令,简单测试一下LED驱动程序。

把任意一个文件复制到led设备上,检查是否能点亮其中某个LED。

例如在uClinux输入终端执行如下命令:

$cp/bin/init/dev/led0

观察并记录实验现象。

2.测试驱动程序

(1)准备实验环境,使用EmbestEduKit44B0目标开发板附带的串口线分别连接到目标板上的UART0和PC机的串口,将Embest仿真器的JTAG接口与EmbestEduKit

的JTAG接口相连,仿真器的PARALLEL接口与PC机的并口相连。

(2)在PC机上运行Windows附件中自带的超级中断串口通信程序(波特率115200、1位停止位、无检验位、无硬件流控制);

或者使用其它串口通信程序。

(3)交叉编译led测试程序test-led。

(4)编译好测试程序后,启动目标板的uClinux操作系统,在PC机上观察超级终端程序主窗口,可以看到如下界面:

Sashcommandshell(version1.1.1)

/>

在PC机上运行tftp服务端程序,设置好传送文件路径,通过以太网使用tftp把

test-led下载到/var目录下。

在uClinux的输入终端里输入如下命令:

>

cdvar

/var>

tftp–g192.168.0.101–r./test-led(此处IP地址可能不同)

(5)修改test-led程序的属性,使其拥有可执行属性,然后运行test-led。

观察test-led

点亮目标开发板上的LED的情况,并描述。

var>

chmod777test-led

./test-led

2.编写驱动程序

编写测试程序,让各个LED以人眼能够识别的频率依次闪烁,每个LED持续闪烁大约3秒钟,找到编号为1-4的LED在实验板上的布局,绘制布局图,添加到实验报告中。

四、实验数据记录和处理

驱动程序代码:

/*

*linux/deriver/led/ekii-led.c

*leddriverforEmbestEduKitII

*Copyright(C)2005Embest<

*/

#include<

linux/module.h>

linux/init.h>

linux/sched.h>

linux/kernel.h>

linux/fs.h>

linux/errno.h>

//errorcodes

linux/types.h>

//size_t

linux/delay.h>

//mdelay

asm/uaccess.h>

asm/arch-S3C44B0X/s3c44b0x.h>

#undefDEBUG

#ifdefDEBUG

#defineTRACE(str,args...)printk("

led:

"

str,##args)

#else

#defineTRACE(str,args...)

#endif

//TRACE没用

#defineLED_MAJOR60//设备号

#defineLED_DEVNAME"

led"

//设备名称

#defineGPC_MASK(3<

<

8)//掩码.pc8/pc9

#defineGPF_MASK(3<

3)//掩码.pf3/pf4

#defineGET_DATA(c,f)((u8)(((~c&

0x80)>

5)|((~c&

0x100)>

7)|((~f&

0x10)>

3)|((~f&

0x08)>

3)))

//把b、f的值组合为一个8位数据

//3210

//pc8pc9pf4pf3

#defineSET_DATA(t,c,f)(c=(((~t&

0x08)<

5)|((~t&

0x04)<

7)),f=(((~t&

0x02)<

3)|((~t&

0x01)<

3)))

//给b、f赋值

//t3210

//pc8pc9pf4pf3

#defineLED_LOCK(u)down(&

u->

lock);

//信号量

#defineLED_UNLOCK(u)up(&

structunit{//定义一个结构类型,成员是整型指针,代表各个口寄存器,以及两个变量

structsemaphorelock;

//定义信号量

u32*PCONC;

/*PCONBregister*/

u32*PDATC;

/*PDATBregister*/

u32*PCONF;

/*PCONFregister*/

u32*PDATF;

/*PDATFregister*/

u32*PUPF;

/*PUPFregister*/

u32c;

/*storeLED1andLED2value*/

u32f;

/*storeLED3andLED4value*/

};

staticchar*version="

EmbestEdukit-IIleddriverversion1.0(2005-04-18)<

\n"

;

staticstructunitled_unit={//给结构体变量部分成员赋值

.PCONC=(u32*)S3C44B0X_PCONC,

.PDATC=(u32*)S3C44B0X_PDATC,

.PUPC=(u32*)S3C44B0X_PUPC,

.PCONF=(u32*)S3C44B0X_PCONF,

.PDATF=(u32*)S3C44B0X_PDATF,

.PUPF=(u32*)S3C44B0X_PUPF,

staticvoidled_set_value(structunit*unit,u8val)

{//设置pc、pf口的值,初始化时用到两次,第一次val是0x0f,第二次是0

u32temp;

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口

PDATF;

=~GPF_MASK;

f;

PDATF=temp;

}

staticu8led_get_value(structunit*unit)

{

u8temp=GET_DATA(unit->

returntemp;

staticintled_open(structinode*inode,structfile*file)

TRACE("

open\n"

);

file->

private_data=&

led_unit;

//这个操作为read服务

MOD_INC_USE_COUNT;

return0;

staticintled_release(structinode*inode,structfile*file)

release\n"

MOD_DEC_USE_COUNT;

//模块引用计数自减

staticssize_tled_read(structfile*file,char*buf,size_tcount,loff_t*offset)

u8temp;

intret;

structunit*unit=(structunit*)file->

private_data;

//使在read函数中可以访问硬件寄存器

read\n"

if(count>

1)

count=1;

LED_LOCK(unit);

//信号量操作

temp=led_get_value(unit);

//读数据

ret=copy_to_user(buf,&

temp,count)?

-EFAULT:

count;

//把数据从内核空间拷贝到用户空间,

//copy_from_user、copy_to_user函数返回不能被复制的字节数,

//因此,如果完全复制成功,返回值为0。

LED_UNLOCK(unit);

//信号量操作

returnret;

staticssize_tled_write(structfile*file,constchar*buf,size_tcount,loff_t*offset)

//使在write函数中可以访问硬件寄存器

write\n"

ret=copy_from_user(&

temp,buf,count)?

//把数据从用户空间拷贝到内核空间

if(ret)

led_set_value(unit,temp);

staticstructfile_operationsled_ops={

owner:

THIS_MODULE,

read:

led_read,

write:

led_write,

open:

led_open,

release:

led_release,

*leddeviceinit

staticvoid__initled_init(structunit*unit)

/*initdevicelock*/

init_MUTEX(&

unit->

/*initioport*/

PCONC;

=~((3<

16)|(3<

18));

//16、17、18、19均0,表示pf3、pf4输入

temp|=((1<

16)|(1<

//16、18为1,所以pc8、pc9都是输出口

//pconc8、pconc9:

01表示输出

PCONC=temp;

PUPC;

temp|=(3<

8);

//8、9置高,pc8、pc9无上拉

PUPC=temp;

PCONF;

8)|(3<

6));

//6、7、8、9均0,表示pf3、pf4输入

8)|(1<

//6、8为1,所以pf3、pf4都是输出口

PCONF=temp;

PUPF;

3);

//4、3置高,pf3、pf4无上拉

PUPF=temp;

/*initdataandturnonled*/

led_set_value(unit,0x0f);

/*delaysometime*/

mdelay(100);

/*turnoffled*/

led_set_value(unit,0x00);

*moduleinit

int__initled_init_module(void)

intres;

init_module\n"

/*printversioninformation*/

printk(KERN_INFO"

%s"

version);

/*registerleddevice*/

res=register_chrdev(LED_MAJOR,LED_DEVNAME,&

led_ops);

if(res<

0){

printk("

ekii-led.o:

unabletogetmajor%dforleddevice.\n"

LED_MAJOR);

returnres;

}

/*thencallled_init()*/

led_init(&

led_unit);

*modulecleanup

void__exitled_cleanup(void)

cleanup\n"

/*unregisterleddevice*/

res=unregister_chrdev(LED_MAJOR,LED_DEVNAME);

0)

unabletoreleasemajor%dforleddevice.\n"

module_init(led_init_module);

module_exit(led_cleanup);

MODULE_DESCRIPTION("

EduKit-IIleddriver"

MODULE_AUTHOR("

Embesttech&

infoCo.,Ltd.<

"

MODULE_LICENSE("

GPL"

测试程序代码:

unistd.h>

stdio.h>

stdlib.h>

linux/fcntl.h>

#defineLED_NUM4

intmain(intargc,char**argv)

inti,j,wval,rval,fd;

printf("

TestLED...\n"

/*openleddevice*/

fd=open("

/dev/led0"

O_RDWR);

/*testsingleled*/

while

(1)

{

for(i=0;

i<

3;

i++)

for(j=0;

j<

LED_NUM;

j++)

{

wval=1<

j;

write(fd,&

wval,1);

read(fd,&

rval,1);

printf("

TurnonLED%d,readbackval=0x%02X\n"

j+1,rval);

/*delay500ms*/

usleep(3000*1000);

}

/*closeleddevice*/

close(fd);

六、实验结果与分析

将驱动程序添加到文件系统,重新编译文件系统和内核映像,将编译好的内核映像烧写到目标板上,重启目标板,使用tftp将驱动测试程序传入到目标板中,运行测试程序,试验箱上的4个LED灯按顺序依次点亮。

七、讨论、建议、质疑

1.考虑到自动匹配不同寄存器的长度,在给寄存器置位时,对数据进行使用取非操作可以自动补齐到寄存器的长度。

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

当前位置:首页 > 人文社科 > 设计艺术

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

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