嵌入式系统设计课程大作业

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

嵌入式系统设计课程大作业
2012年上学期嵌入式系统设计课程大作业
1、叙述下列相关名词的含义
ARM、xscale、PXA255、RISC、体系结构
答:1)ARM:英国的一家公司;时下流行的一种体系结构。

2)XScale:ARM架构v5TE指令集的CPU。

3)PXA255:XScale的内核版本。

4)RISC:Reduced Instruction Set Computing,即精简指令集,一种CPU 的设计概念;与之相对的是CISC,即复杂指令集
5)体系结构:嵌入式系统硬件与软件的衔接;它确定嵌入式系统设计的部件、部件功能、部件间借口的设计,并集中于嵌入式系统的核心部分——处理器的运算与内存的存取。

2、画出嵌入式硬件系统组成的模块结构图
3、叙述基于linux的嵌入式平台的搭建过程
答:Linux嵌入式平台的搭建符合嵌入式平台搭建的一般过程,但是具体到Linux 嵌入式平台,又有些许不同,其搭建过程如下:
1)处理器以及硬件开发平台的选择
以处理器为主,结合考虑硬件平台的情况。

处理器考虑的问题包括应用类型及I/O接口、主频和功耗、对不同类型存储器的支持、封装等;硬件平台的选择和设计包括内存和外围存储器、输入输出接口以及设备等几项主要内容。

2)操作系统的选择
由于已经选取了Linux操作系统,因此此处主要是内核版本的选取以及对内核功能的裁剪。

3)开发环境的选取
即开发工具的选取,主要是指开发软件的选取,比如常用的minicom。

4)开发实施
首先,Bootloader的烧制。

目的是对硬件系统基本功能的支持,比如串口通信。

其次,内核文件的制作。

接下来,内核文件的拷贝。

此时,可以通过串口或者网口实施传输,能够大幅度提高传输速度。

最后,在主机使用开发软件,完成对硬件系统的开发工作。

包括硬件驱动程序、上层的应用程序、系统的集成与调试等。

4、如下为xscale处理器的内核框图:
简述内核框图中每个模块的名称及指标。

答:1)Instruction Cache:指令Cache;大小32KB,32路,支持线性锁定2)Micro-Processor:微处理器;七级流水
3)Data Cache:数据Cache;最大支持32KB,32路
4)Data Ram:数据Ram;最大支持28KB
5)Mini-Data Cache:迷你数据Cache;大小2KB,2路
6)Branch Target Buffer:分支目标缓存;128入口
7)IMMU/DMMU:指令/数据存储管理单元;32路,全相关,支持锁定
8)Fill Buffer:填充缓存;4~8入口
9)Performance Monitoring:功能显示器
10)Debug:硬件中断断点记录
11)Power Management Control:电源管理控制
12)MAC:乘加单元;40位累加/累乘,16位单指令多数据流操作,16*32
位操作单周期支持
13)Write Buffer:写缓存;8入口,支持合并操作
14)JTAG:边界扫描技术;支持JTAG操作
5、下述英文为BTB模块功能的详细介绍,阅读后说明该模块的作用。

The BTB stores the history of branches that have executed along with their targets. Figure 5-1 shows an entry in the BTB, where the tag is the instruction address of a previously executed branch and the data contains the target address of the previously executed branch along with two
答:分支目标缓存目标地址历史的分支,具体到每个入口(表项),由Tag和数据组成。

Tag是以前执行分支的指令地址,数据包括以前执行分支的目标地址,以及2比特的历史信息。

分支目标缓存取得当前的指令地址,检查这个地址是否是以前执行过的分支。

它用现行指令的位[8:2]来选择分支目标缓存中的标志Tag,并与现行指令的位[31:9,1]进行匹配。

若匹配且历史位指出该分支过去常产生,则分支目标缓存中的数据(目标地址[31:1])作为下一条指令地址送至指令Cache。

6、下面是linux下的一个简单的设备驱动程序,写出linux设备驱动常用的数据结构,同时阅读下面代码,请给出测试程序中的每条语句加以注释。

设备驱动程序Keypad.c的源代码:
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/rtc.h>
#include <linux/delay.h>
#include <asm/hardware.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#define LEDnKEY_MAJOR 251
#define KEYPAD_NAME "X-Hyper250 Keypad"
#define KEYPAD_VERSION "Version 0.1"
#define EXT_KEY_CS EXT_PORT2
#define EXT_LED_CS EXT_PORT3
#define LED_SHOW 10
/*EXT_KEY_CS 为向外部LED进行数值设定,它定义在其它头文件里*/
void led_off_on() /**/
{
int i;
EXT_LED_CS = 0xff;
for(i =0 ; i<8;++i)
{
EXT_LED_CS = ~((1 << i) & 0xff); /*点亮相应LED灯*/
udelay(30000);
}
EXT_LED_CS = 0xff;
}
/*应用程序用open来打开设备文件,实际上调用驱动的lednkey_open()函数*/
int lednkey_open(struct inode *inode, struct file *filp) /*打开设备文件*/
{
MOD_INC_USE_COUNT;/*内核提供的一个宏,检查使用驱动程序的用户数*/
return (0); /* success */
}
int lednkey_release(struct inode *inode, struct file *filp) /*释放设备文件*/
{
led_off_on();
MOD_DEC_USE_COUNT;
return (0);
}
ssize_t lednkey_read(struct file *filp, char *Putbuf, size_t length, loff_t *f_pos) /*按键读取函数*/
{
unsigned short BottonStatus;
unsigned char Bottontmp = 0;
int i;
BottonStatus = ( EXT_KEY_CS & 0xff ); /*按键状态*/
for(i = 0 ; i < 8; ++i) /*判断哪个按键按下*/
{
if( ((BottonStatus >> i) & 1) == 0 )
Bottontmp = (i+1);
}
copy_to_user( Putbuf, &Bottontmp, length); /*将数据从内核态拷贝到用户态,这是由定义在<asm/uaccess.h>里的特殊函数实现在不同的空间传输任意字节的数据*/ return length;
}
ssize_t lednkey_write(struct file *filp, const char *Getbuf, size_t length, loff_t *f_pos)
{
int num;
unsigned char UsrWantLed;
copy_from_user( &UsrWantLed, Getbuf, length);/*将数据从用户态拷贝到核心态*/
num = ( (UsrWantLed) & 0xff );/*确定哪一位要进行设定*/
EXT_LED_CS = ~(1 << (num-1)); /*点亮相应LED灯*/
return (0);
}
int lednkey_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)/* lednkey_ioctl 接口函数,主要用于获取或者改变正在运行的设备参数*/
{
switch(cmd)
{
case LED_SHOW: /*如果要点亮LED灯*/
{
if(arg)
led_off_on();
break;
}
}
return 0;
}
/*以下这些驱动函数是与用户的应用程序里对设备文件操作的函数相对应的*/
struct file_operations lednkey_fops = {
open: lednkey_open,
read: lednkey_read,
write: lednkey_write,
ioctl: lednkey_ioctl,
release: lednkey_release,
};
static int _init xhyper250_keypad_init(void) /*初始化设备函数,在函数名之前加上这个属性之后,系统会在初始化完成之后丢弃初始化函数,收回它所占用的内存,以减小内核所占用的内存空间,它只对内建的驱动起作用*/
{
int result;
result = register_chrdev(LEDnKEY_MAJOR, "lednkey", &lednkey_fops);/*向操作系统注册一个主号为251,设备名为"lednkey",并传递设备驱动程序的指针为lednkey_fops(全局变量),其中register_chrdev ()是内核提供的函数,作用是完成注册新的字符设备*/
printf("%s %s initialized.\n",KEYPAD_NAME, KEYPAD_VERSION);
led_off_on();
return 0;
}
static void _exit xhyper250_keypad_exit(void) /*向操作系统卸载设备函数*/
{
unregister_chrdev( LEDnKEY_MAJOR, "lednkey" );
led_off_on();
}
module_init(xhyper250_keypad_init); /*显式声明初始化设备函数*/
module_exit(xhyper250_keypad_exit); /*显式声明卸载设备函数*/
/*通过上述两个声明内核知道驱动程序的进入点*/
测试文件的源代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define LED_SHOW 10
int fd;
static char *dev_name = "/dev/keypad";
int main(int argc, char **argv)
{
int data = 0, pre_data;
fd = open( dev_name , O_RDWR );
if( !(fd >=0) )
{
printf("%s file open failed\n", dev_name );
exit(-1);
}
printf("\nkeypad App : press the push button see show led - Exit Ctrl-C \n",dev_name);
ioctl(fd,LED_SHOW,1);
while(1)
{
do
{
pre_data = data;
read( fd, (char * )&data, sizeof(data) );
data = (data & 0xff);
}while(data == 0);
if( pre_data == 0)
{
printf("Write %d LED\n",data);
write( fd, (const char *)&data, sizeof((const char )data) );
}
}
close( fd );
return 0;
}
1)数据结构
struct file_operations
{
struct module *owner;
loff_t (*llseek)(struct file *, loff_t, int);
ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
ssize_t (*aio_read)(struct kiocb *, char __user *, size_t, loff_t);
ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
ssize_t (*aio_write)(struct kiocb *, const char __user *, size_t, loff_t);
int (*readdir)(struct file *, void *, filldir_t);
unsigned int (*poll)(struct file *, struct poll_table_struct *);
int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
int (*mmap)(struct file *, struct vm_area_struct *);
int (*open)(struct inode *, struct file *);
inode_operations。

int (*flush)(struct file *);
int (*release)(struct inode *, struct file *);
int (*fsync)(struct file *, struct dentry *, int datasync);
int (*aio_fsync)(struct kiocb *, int datasync);
int (*fasync)(int, struct file *, int);
int (*lock)(struct file *, int, struct file_lock *);
ssize_t (*readv)(struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*writev)(struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*sendfile)(struct file *, loff_t *, size_t, read_actor_t, void *);
ssize_t (*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
int (*check_flags)(int);
int (*dir_notify)(struct file *filp, unsigned long arg);
int (*flock)(struct file *, int, struct file_lock *);
}
2)程序注释
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define LED_SHOW 10
int fd;
static char*dev_name="/dev/keypad";
int main(int argc,char**argv)
{
int data=0,pre_data;
//使用函数open打开设备keypad
fd=open(dev_name,O_RDWR);
//打开失败,显示出错信息
if(!(fd>=0))
{
printf("%s file open failed\n",dev_name);
exit(-1);
}
//打开成功,提示用户输入
printf("\nkeypad App:press the push button see show led-Exit Ctrl-C\n",dev_name);
//循环显示LED,看LED是否正常
ioctl(fd,LED_SHOW,1);
while(1)
{
//采用忙等待方式扫描用户输入,传递给write函数
do
{
pre_data=data;
//使用函数read从设备keypad读取数据
read(fd,(char*)&data,sizeof(data));
data=(data&0xff);
}while(data==0);
if(pre_data==0)
{
printf("Write%d LED\n",data);
//使用函数write写入数据,即向外部LED传输数据
write(fd,(const char*)&data,sizeof((const char)data));
}
}
//使用函数close关闭设备keypad
close(fd);
return 0;
}。

相关文档
最新文档