嵌入式复习资料Word文档格式.docx
《嵌入式复习资料Word文档格式.docx》由会员分享,可在线阅读,更多相关《嵌入式复习资料Word文档格式.docx(24页珍藏版)》请在冰豆网上搜索。
5.简单的嵌入式系统与复杂的嵌入式系统
简单嵌入式系统
系统的软、硬件复杂度都很低,硬件集成度低、系统资源种类少,没有操作系统的支持;
如单片机系统和DSP系统等。
复杂嵌入式系统(目前所说的嵌入式系统)
系统的软、硬件复杂度都很高,硬件集成度高(32位SoC为核心)、系统资源种类多(外部接口丰富),需要操作系统的支持(可实现多任务调度,支持TCP/IP协议等)。
6.嵌入式的发展趋势
⏹嵌入式系统硬件集成发展---SoC
⏹嵌入式操作系统得到快速发展
⏹软件开发环境集成化、智能化和图形化
⏹与网络及通信的结合成为必然趋势
⏹Linux和JAVA技术对嵌入式软件的发展产生深远的影响。
7.处理器的分类
嵌入式微控制器,嵌入式微处理器,嵌入式数字信号处理器,嵌入式片上系统
8.嵌入式的组成
嵌入式系统(指包括操作系统的嵌入式平台)可分为嵌入式硬件系统和嵌入式软件系统
硬件抽样层的作用:
提高了系统的独立性和可移植性。
硬件组成:
嵌入式微处理器,存储器,输入输出设备,通信与扩展接口。
第二章
1.嵌入式处理器及体系结构(哈佛,冯诺依曼)
冯.诺依曼结构计算机系统以存储程序原理为基础,由一个中央处理单元(CPU)和一个存储器组成。
这个存储器存储全部的数据和指令,并且可以根据所给的地址(直接寻址方式)对其进行读写操作。
数据和指令都存在一个存储器中的计算机被称为冯.诺依曼结构计算机,数据和指令是混合存储在计算机的存储器中
特征:
(1)使用单一处理部件来完成计算、存储及通信工作
(2)使用一维线性组织的定长存储单元存储程序,且不区别指令集跟数据。
(3)存储空间各单元有唯一定义的地址,访问采用直接寻址方式。
(4)使用二进制机器语言,编程完成基本操作码的简单操作。
(5)按指令在存储器中存放的次序顺序执行,程序分支有转移指令实现。
哈佛体系结构的处理器:
指令和数据空间是独立的,使用两个独立的存储器模块,分别存储指令和数据,主要指在单一的主存储器情况下,通过使用分离的指令高速缓存和数据高速缓存实现指令空间与数据空间的分离,通过这种方式,CPU可以在一个时钟周期内同时读取指令和操作数,实现并行处理,避免了数据与指令的存储器访问冲突,提高了运行效率。
2.复杂指令系统计算机CISC
⏹靠增强指令的功能,增加指令系统的复杂程度来提高计算机系统的性能。
。
⏹特点:
1指令系统复杂庞大,指令数目一般有200~300条。
2.指令格式多,指令字长不固定,使用多种不同的寻址方式。
3.可访存指令不受限制。
4.各种指令的执行时间和使用频率相差很大
RISC机与CISC机相比的主要优点
⑴充分利用了VLSI芯片的资源。
⑵结构简单,有利于处理器的优化设计⑶便于设计,降低了开发成本,提高了可靠性⑷可以使流水线能高效地执行.
3.ARM微处理器系列
ARM7微处理器系列、ARM9微处理器系列、ARM9E微处理器系列、ARM10E微处理器系列、//SecurCore微处理器系列、//4StrongARM微处理器系列、Xscale处理器
4.处理器工作状态
有两种工作状态,并可在两种状态之间切换。
ARM状态:
处理器执行32位的、字对齐的ARM指令。
Thumb状态:
处理器执行16位的、半字对齐的Thumb指令
5.7种处理器模式
●用户模式(USR):
ARM处理器正常程序执行的模式;
●快速中断模式(FIQ):
用于高速数据传输或通道处理;
●外部中断模式(IRQ):
用于通用的中断处理;
●特权模式或管理员模式(SVC):
操作系统使用的保护模式;
●数据访问中止模式(ABT):
用于虚拟存储器和存储保护;
●未定义指令中止模式(UND):
用于支持硬件协处理器的软件仿真;
●系统模式(SYS):
运行具有特权的操作系统任务。
6.ARM寄存器
ARM处理器共有37个寄存器
●31个32位的通用寄存器(包括程序计数器PC);
●6个32位状态寄存器(1个专用于记录当前状态,5个用于备份记录状态切换前的状态),在32位中目前只使用12位
7.异常
异常是内部或外部源产生的、引起处理器处理的一个事件
8.XScale体系结构的特点
(1)支持DSP指令集,适合需要高速数字信号处理场合。
(2)6级超级流水线(3)支持32为的高速AMBA总线接口(4)支持VFP10浮点处理器协处理器(5)全性能MMU支持(6)支持数据高速缓存和指令高速缓存,具有更高的指令和数据处理能力(7)内嵌并行读写操作部件。
第三章
1.嵌入式中常见的C语言现象
宏定义
采用宏定义可以减少程序中重复书写某些字符串的工作量;
有助于防止出错,提高程序的可读性和可移植性。
宏代换在预处理阶段完成
volatile关键字,非优化
如果变量被用volatile关键字修饰,就是告诉编译器不要对该变量的读写以及多个volatile变量读写的先后顺序进行优化;
对其存取时不能使用寄存器中的备份,每次读必须重新访问相应的内存地址,每次写也须将结果立即写回。
2.常见的嵌入式操作系统
(1)VxWorks
特点:
高可靠性、高实时性和可裁减性。
微内核结构,面向对象方法,开发工具功能强大、它支持多种处理器,如x86、i960、SunSparc、MotorolaMC68xxx、MIPS、PowerPC
(2)uC/OS-II作为一个实时操作系统,uC/OS-II的进程调度是按抢占式、多任务系统设计的,即它总是执行处于就绪队列中优先级最高的任务。
uC/OS-II将进程的状态分为5个:
就绪状态(Ready)、运行(Running)、等待(Waiting)、休眠(Dormant)和中断ISR。
uC/OS-II不支持时间片轮转调度法,所以赋予每个任务的优先级必须是不同。
优先级号越低,任务的优先级越高。
它的基本代码尺寸不到5KB,对存储器容量要求低,满足了嵌入式系统对体积苛刻的要求,uC/OS-II应用面覆盖了诸多领域,如照相机、医疗器械、音响设备、发动机控制、高速公路电话系统、自动提款机等。
uCOS-II的不足之处:
⏹只有多任务调度的简单内核
⏹内存管理过于简单,几乎没有动态内存管理功能
⏹文件系统和图形界面需要外挂
⏹对于设备驱动程序没有专门统一的接口
(3)WindowsCE
WindowsCE是微软公司为开发各类通信息设备而开发出来的一个嵌入式弱实时操作系统。
WindowsCE的内核提供内存管理、抢先多任务和中断处理功能。
内核的上面是图形用户界面GUI和桌面应用程序。
多线程、完整优先权、多任务的操作系统。
适合作为可裁减的32位嵌入式操作系统。
WinCE既适用于工业设备的嵌入式控制模块,也适用于消费类电子产品。
允许每个进程有256个优先级,采用抢占式优先权调度法。
WindowsCE内核至少约为200KB的ROM
(4)linux主要特点:
⏹开放源代码,不存在黑箱技术。
⏹内核小、功能强大、运行稳定、效率高。
⏹开放源代码的操作系统易于定制裁减,在价格上极具竞争力。
⏹不仅支持X86CPU,还可支持其他数十种CPU芯片。
⏹有大量的且不断增加的开发工具和开发环境。
⏹沿用了Unix的发展方式,遵循国际标准,可方便的获得众多第三方软硬件厂商的支持。
⏹Linux内核的结构在网络方面是非常完整的,提供了对十兆、百兆、千兆以太网、无线网络、令牌网、光纤网、卫星等多种联网方式的全面支持。
此外在图像处理、文件管理及多任务支持诸多方面也都非常出色。
常见的嵌入式操作系统还有QNX、NucleusEmbedded、ThreadX、eCos、PalmOS、Symbian等等。
第四章
1.嵌入式Linux简介
(1)自制嵌入式Linux系统:
就是在Linux标准内核源码的基础上,根据所选定的硬件平台和所需要的功能,对标准内核进行适当的裁剪、修改,并制作相应的文件系统以构成自制嵌入式Linux系统的基础;
再将设计或下载的应用程序移植到制作好的嵌入式Linux中,就构成了完整的自制嵌入式Linux软件系统。
(2)商业版嵌入式Linux
有专门的系统软件开发商技术支持,其软件更丰富、技术文档更多、软件更新和错误问题解决也更快,但费用相对较高。
Linux的内核版与发行版:
Linux为内核版+许多应用程序=发行版
Linux操作系统结构
⏹Linux的源代码一般在/usr/src/Linux-*.*.*(*.*.*代表内核版本,如2.4.20)。
目标板的移植好的内核源码在XSBase270/Kernel。
3.Linux的目录树结构
在Linux下只有一个根目录,系统启动后,磁盘上的所有文件系统被加载安装到以“/”为根目录的文件树上,在linux中,所有的目录,文件和硬件都以文件形式挂接在树上。
这个特点简化了文件的访问,所有的文件目录都可以从树根”/”查找到。
4.Linux的启动过程:
主要是引导加载程序,linux内核,文件系统挂载这3方面。
即操作系统的启动为后面应用程序的运行打下基础
嵌入式Linux主要分4个层次:
引导加载程序,linux内核,文件系统,用户应用程序。
Linux的启动过程是指上电到系统的第一个进程建立起来的整个过程。
5.驱动程序(就是内核模块)的编写----驱动程序放于内核的Driver中
内核模块结构
1、dri_arch.c模块加载实验
编写实验代码
#include<
linux/string.h>
linux/module.h>
//声明是一个模块
linux/fs.h>
linux/init.h>
linux/types.h>
staticint__initdri_arch_init_module(void)//加载本驱动是执行
{printk("
Thisisasimpledriver-module!
\r\n"
);
return0;
}
staticvoid__exitdri_arch_cleanup_module(void)//卸载驱动时执行
Goodbyedriver-module!
module_init(dri_arch_init_module);
module_exit(dri_arch_cleanup_module);
编译make
使用Makefile文件
CC=/opt/xscalev1/bin/arm-linux-gcc
INCLUDEDIR=/XSBase270/Kernel/linux-2.4.21-51Board_EDR/include
CFLAGS=-D__KERNEL__-DMODULE-Wall-O2
CFLAGS+=-I..-I$(INCLUDEDIR)
DEBUG=
TARGET=dri_arch
OBJS=$(TARGET).o
SRC=dri_arch.c
All:
dri_arch.o
dri_arch.o:
dri_arch.c
$(CC)$(CFLAGS)$(DEBUG)-c-odri_arch.odri_arch.c
clean:
rm-rf*.o
下载目标代码到目标板,具体的操作参考使用手册相关部分
挂载目标代码,并查看输出调试信息,本次相关操作均要求到下载的当前目录(含dri_arch.o)
$insmoddri_arch.o(挂载dri_arch)
$lsmod(查看当前已挂载模块,会看到dri_arch)
$dmesg(查看模块输出信息:
)
$rmmoddri_arch(卸载dri_arch)
$lsmod(查看当前已挂载模块,不再看到dri_arch)
编写一个简单的字符设备驱动程序。
要求该字符设备包括scull_open(),scull_write(),scull_read(),scull_ioctl()和scull_release()5个基本操作,还应再编写一个测试程序来测试用户所编写的字符设备驱动程序。
1、驱动程序模块源代码chrdev.c
linux/kernel.h>
#include<
linux/slab.h>
#include<
linux/ioctl.h>
asm/uaccess.h>
structscull_dev
{void*data;
intquantum;
//当前容量的大小。
intqset;
//当前数组的大小。
unsignedlongsize;
unsignedintaccess_key;
//由sculluid和scullpriv使用的存取字段。
unsignedintusage;
//当字符设备正使用时加锁。
unsignedintnew_msg;
structscull_Dev*next;
//指向下一字符设备
};
structscull_devscull;
MODULE_LICENSE("
GPL"
staticintscull_open(structinode*inode,structfile*file)
{MOD_INC_USE_COUNT;
//增加该模块的用户数目
printk("
Thischrdevisinopen!
\n"
return0;
}
staticssize_tscull_write(structfile*file,char*buf,size_tcount,loff_t*offset)
{if(count<
0)return-EINVAL;
if(scull.usage||scull.new_msg)return-EBUSY;
scull.usage=1;
kfree(scull.data);
//<
linux/malloc.h>
要用<
代替
scull.data=kmalloc(sizeof(char)*(count+1),GFP_KERNEL);
if(!
scull.data){return-ENOMEM;
copy_from_user(scull.data,buf,count+1);
//用户空间至内核空间
scull.usage=0;
scull.new_msg=1;
returncount;
staticssize_tscull_read(structfile*file,char*buf,size_tcount,loff_t*offset)
{intlength;
if(count<
if(scull.usage)return-EBUSY;
if(scull.data==0)return0;
length=strlen(scull.data);
if(length<
count)count=length;
copy_to_user(buf,scull.data,count+1);
scull.new_msg=0;
}
#defineSCULL_MAJOR42
#defineSCULL_MAGICSCULL_MAJOR
#defineSCULL_RESET_IO(SCULL_MAGIC,0)//重置数据
#defineSCULL_QUERY_NEW_MSG_IO(SCULL_MAGIC,1)//检查新的消息
#defineSCULL_QUERY_MSG_LENGTH_IO(SCULL_MAGIC,2)//获取消息长度
#defineIOC_NEW_MSG1
staticintusage,new_msg;
//控制标志
staticchar*data;
staticintscull_ioctl(structinode*inode,structfile*file,unsignedlongintcmd,unsignedlongarg)
{intret=0;
switch(cmd){
caseSCULL_RESET:
kfree(data);
data=NULL;
usage=0;
new_msg=0;
break;
caseSCULL_QUERY_NEW_MSG:
new_msg=scull.new_msg;
if(new_msg)
returnIOC_NEW_MSG;
caseSCULL_QUERY_MSG_LENGTH:
data=scull.data;
if(data==NULL){return0;
}
else{returnstrlen(data);
break;
default:
return-ENOTTY;
returnret;
staticintscull_release(structinode*inode,structfile*file)
{MOD_DEC_USE_COUNT;
//该模块的用户数目减1
printk("
Thischrdevisinrelease\n"
staticstructfile_operationsscull_fops=
{.owner=THIS_MODULE,
.read=scull_read,
.write=scull_write,
.ioctl=scull_ioctl,
.open=scull_open,
.release=scull_release,
};
staticint__initscull_init_module(void)
{intret;
printk("
ScullcharDriver.\n"
ret=register_chrdev(42,"
chrdev"
&
scull_fops);
//注册设备,主设备号为42
if(ret<
0){printk("
Unabletoregistercharacterdevice!
\n"
}
deviceregisteredwithmajor%d\n"
ret);
return0;
staticvoid__exitscull_cleanup_module(void)
ret=unregister_chrdev(42,"
if(ret<
0)printk("
Unabletounregistercharacterdevice!
elseprintk("
ScullTestDriverunloaded!
"
module_init(scull_init_module);
module_exit(scull_cleanup_module);
2、编译make
CC=gcc
INCLUDEDIR=/usr/src/linux-2.4.20-8/include
3、加载模块,并创建文件节点,以便用户程序使用,命令如下
Insmodchrdev.o
Mknod/dev/chrdevc420
dmesg
4、编写测试的用户程序源代码如下:
(1)chrdev头文件
#ifndef_DYNCHAR_DEVICE_H
#define_DYNCHAR_DEVICE_H
l