注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

瘋人院

lunatic asylum

 
 
 

日志

 
 

嵌入式系统:体系结构、编程设计  

2009-05-29 17:23:56|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

程序例程和过程可以有不同的段。例如一个程序可以分段,每一段存储在不同的存储器块中。指针(pointer)地址指向存储着一个程序段的开始处,可以使用偏移量(offset)数值来获取段中的存储器地址。也可以将数据分段,每一段存储在不同的块中。与此类似,字符串也可以分段。图2-2(a)给出了在软件设计过程中可能会需要的不同段的类型。一个段可以分为固定大小的部分,称为页(page)。处理器(例如80x86)可以包含段寄存器和偏移量寄存器(参见图2-2(b))。

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-2 (a)示例程序中的段类型和页;(b)80x86中寄存器、CS和EIP使用的示例,用来取回或者写物理存储器地址

注意:

对于函数和过程(任务),存储器中可以有不同的段。这包括用于数据和用于堆栈的段。每一个段都具有开始存储器地址和结束存储器地址。每一个段都具有指针地址和偏移量地址。可以使用偏移量从一个段中取回代码或者数据字。

软件设计方法就是在程序中使用数据集合和数据结构(参见5.4.2节)。因此,对于系统软件设计者来说,理解下面的内容是很重要的。

存储器中可以有不同的数据集合和数据结构。下面是系统处理过程中通常使用的数据结构和数据集合,它们存储在系统中不同的存储器块中。

A. 称为堆栈(stack)的数据结构是程序中的特殊元素。堆栈表示一个分配的存储器块,处理器总是以LIFO(Last In First Out,后进先出)的方式读取其中的每一个数据元素。在过程中可以产生各种堆栈结构。图2-3给出了在嵌入式软件执行的过程中所产生的各种堆栈结构。

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-3 存储器块中的不同堆栈结构的示例。每一个堆栈指针都指向堆栈的栈顶,处理器可以从这里进行读写操作。堆栈中的数据总是以LIFO的模式取回的

(1) 在一个例程的运行过程中,可以调用另外一个例程。为了在被调用的例程执行完后,处理器只返回到发出调用的那个例程,返回的指令地址必须存储到堆栈中。这也可以是嵌套的。意思是说一个例程调用另外一个例程,从被调用的例程总是返回到发出调用的例程。因此,在存储器中就要分配一块存储器地址给堆栈,能够保存嵌套调用的返回地址。

(2) 开始的时候,在RAM中应该有一个输入数据被保存为一个堆栈,以便在后来的LIFO模式中取回。应用程序可以产生运行时的堆栈结构。在不同的存储器块中可以有多数据堆栈(multiple data stack),每一个堆栈都具有单独的指针地址(5.6节中将介绍软件设计者如何使用堆栈数据结构)。

(3) 多任务或者多线程软件设计(参见8.1节)中的每一个任务或者线程都应该有自己的堆栈,其中存储着它们的上下文(context)。当处理器切换到另外一个任务或者线程的时候,需要保存上下文。上下文中包含着程序计数器的返回地址,以便在切换回到任务的时候取回。在存储器中,不同的存储器块可以有不同的上下文有多堆栈(multiple stack),每一个存储器块都具有单独的指针地址。应用程序和监督程序(OS)在单独的存储器块中有单独的堆栈。

每一个处理器至少具有一个堆栈指针,可以使其指向指令堆栈,并协助例程的调用。在8051、68HC11和80196中都有一个堆栈指针。一些高级的处理器具有多个堆栈指针。在80960中有4个堆栈指针,分别是RIP、SP、FP和PFP。MC8010提供了两个堆栈指针,USP(User Stack Pointer,用户堆栈指针)和SPP(Supervisory Stack Pointer,监督堆栈指针)。MC68040提供了4个堆栈指针,USP(User Stack Pointer,用户堆栈指针)、SPP(Supervisory Stack Pointer,监督堆栈指针)、存储器堆栈帧指针和指令堆栈指针。(块也可以称为帧。)当处理器只有一个堆栈指针的时候,OS会分配存储器地址,用作多指令和多数据堆栈的指针。

注意:

堆栈是存储器中的特殊数据结构。它具有一个指针地址,总是指向堆栈的栈顶。这个指针地址称为堆栈指针。处理器至少具有一个堆栈指针。堆栈中的数值是以LIFO的模式从存储器中取回的,而数据行、表格或者队列中的数据是以FIFO(First In First Out,先进先出)的模式访问的。每一个过程都应该有单独的栈顶指针,并且在分配的存储器中有一个单独的块。由于嵌入式系统中有多个过程,因此有多个堆栈。

B. 数组(array)数据结构是一个重要的编程元素。让我们来看一个具有30名学生、每个学生的编号为1~30的班级的测试结果。令i代替名单编号作为索引。令名单编号1的测试标志存储在一个可伸缩的整型变量M[0]中。令M[0]、M[1],…,M[28]和M[29] 分别作为名单编号1,2,…,29,30的标志向量。有一个指针指向第一个可伸缩的变量M[0]。它可以保存在一个称为索引指针的寄存器中。这样索引寄存器就可以通过一个循环中的指令从0增加到29,这个指令指向前一个名单编号学生的标志。再来看另外一个例子,表达式yn=Σ(ai×xn-i)的系数为ai。这些系数存储在一个数组中。输入值xi和输出值yk也分别存储在另外两个数组中。在这里,i、j和k都是从–N到N–1变化的整数,N是上限。图2-4给出了存储器块中的一个数组,指针和索引共同指向它的元素。

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-4 (a)存储器块中的一个数组,具有一个基指针,第一个元素的索引为0。可以通过定义指针和索引从某个元素中取回数据。(b)存储器块中的一个队列,具有两个指针,分别指向其第一个和最后一个元素。数据字从队列中是以FIFO的模式取回的。(c)存储器块中的一个循环队列,具有两个指针分别指向其第一个和最后一个元素。(d)管道的存储器块,第一个和最后一个元素分别指向不同的任务

注意:

一维数组是存储器中的特殊数据结构。它具有一个指针地址,总是指向数组的第一个元素。根据第一个元素指针和这个元素的索引,可以产生一个地址,处理器可以使用这个地址访问一个数组元素。索引是一个从0开始的整数。可以从分配给数组的存储器块中的某个元素地址中取回数据。还可以用一个处理器寄存器来保存索引,另外一个寄存器保存数组基指针。

C. 称为队列(queue)的数据结构是另外一个重要的编程元素(队列是一个分配的存储器块,其中的数据元素总是以FIFO的模式取回)。使用队列数据结构,可以将数据通过网络传送到一个文件中或者打印机中。总共需要两个指针。一个用于指向存储器块的一个地址,元素可以从这里插入(写操作)。每次增加元素后这个指针都应该增加,称为队尾指针。另外一个指令用于指向存储器块的一个地址,元素可以从这里删除(读操作)。每次删除元素后这个指针都应该增加。两个指针开始的时候都指向块中的起始存储器地址,称为队首指针。向队列中插入数值通常要比从队列中删除数值快。例如,在打印机的队列中,系统插入数值的速度要比打印的速度快。两个指针的差值是队列的当前长度。4.5节将介绍嵌入式软件设计过程中队列的使用。由于存在尾指针超过存储器块末地址所设定的限制的可能性,当指针超过了存储器块的末边界时,通常会产生一个异常(一种出错指示)。此时继续增加元素会占用其他的存储器块。图2-4(b)给出了具有两个指针的存储器块,分别用来插入和删除元素。

注意:

队列是一种分配了存储器块(缓冲区)的数据结构,其中的数据元素总是以FIFO的模式取回的。它有两个指针,一个指向首,一个指向尾。任何的删除操作都是从有地址开始的,任何插入操作都是在尾地址进行的。当指针超过了块的末边界时,必须产生一个异常(一种出错指示),然后采取适当的处理。

D. 当指针到达一个界限时就会返回到其起始值的队列,称为循环队列(循环队列(circular queue)是分配给队列的一个有边界限制的存储器块,其指针永远都不会超过设定的限制)。循环队列中的数据元素仍然是以FIFO的模式取回的,并且当指针超过了存储器块的界限时不会产生异常。图2-4(c)给出了一个具有循环队列的存储器块,两个指针分别用于插入和删除操作。

注意:

循环队列是一种两个指针都不会超过存储器块(缓冲区)的队列,当指针超过了限制后,会复位到初始值。

E. 当执行插入操作一端的标识与执行删除操作一端的目的标识不同时,通常称这样的队列为管道(pipe)。管道是分配给一个队列的普通存储器块,这个队列中有两个实体以某种方式相连。例如,一个实体用来向队列中写(插入)元素,另外一个实体用来从队列中读(删除)元素。一个管道通常连接两个任务。图2-4(d)给出了具有管道的存储器块。

注意:

管道是一个清楚地定义了源和目的实体的队列。有时候程序员也称管道为队列,反之亦然。

F. 表(table)是一个二维数组(矩阵),是分配了存储器块的一个重要数据集合。表总是有一个基指针。它指向表的第1列第1行的第1个元素。存在两个索引,一个是列索引,一个是行索引。图2-5(a)给出了一个具有表指针的存储器模块。与数组相同,任何元素都可以通过三个地址(表基址、列索引和行索引)取回。当用表中的数值代替指针的时候,指令中使用的数值称为位移(displacement)。位移可以是一行或者一列。

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-5 (a)具有表指针的存储器块;(b)具有哈希表或者查询表指针的存储器块;(c)具有链表指针的存储器块

注意:

表是一个分配了存储器块的数据集合。通过三个地址(表基址、列索引和行索引)可以取回表中的任意一个元素。

G. 哈希表(hash table)是一个键/值数据集合。哈希表的每一列都有一个键或者名字。相应的数值或者对象在第2列。键可以存在于不连续的存储器地址中。查表的过程就像创建散列。如果表的第1列作为键(指向数值的指针),第2列作为数值,我们称这样的表为查询表。图2-5(b)给出了一个具有哈希表指针的存储器块。

注意:

哈希表是一个分配了存储器块的数据集合,通常用作查询表。正如索引标识了数组元素一样,一个哈希键也标识了一个哈希元素。

H. 链表(list)是一个具有多个存储器块的数据结构,每一个元素都有一个存储器块。链表具有顶(头)指针,指向链表开始处的存储器地址。存储器中的每一个链表元素也保存了指向下一个元素的指针。最后一个元素不指向任何地方。链表用来保存存储器中不连续存储的对象。图2-5(c)给出了具有链表指针的存储器块。

注意:

链表是每一个元素都保存了指向链表中下一个元素的指针的数据结构。每个元素都分配了一个存储器块。链表头指针指向它的第一个元素,最后一个元素不指向任何位置。

示例2-11

一个应用程序的函数设计如下所述。其数据集合和数据结构的存储器块分配随后给出。

(1) 对系统或者其他函数的10次递归调用。需要分配一个堆栈数据结构,用来保存返回指令地址,大小为40字节(假设程序计数器地址是4字节)。

(2) 在每次调用的时候,下列内容也保存到堆栈中。(i) 4个指针(每个地址为4个字节)。(ii)4个整数(每个整数为4个字节)和(iii)4个浮点数字(每个为4个字节)。需要分配一个堆栈数据结构,用来保存函数参数,大小为4×4+4×4+4×4=48字节。

(3) 三个数组,通过表达式嵌入式系统:体系结构、编程设计 - N~A - 欢迎计算滤波后的输出序列(参见2.1节)。需要分配三个数组结构,每个大小为20×8=160字节(假设每一个元素都是8字节的双精度浮点数(64位的IEEE 754格式))。

图2-6(a)给出了系统中具有Princeton体系结构时所需要的存储器区域。图2-6(b)给出了系统中具有Harvard体系结构时所需要的存储器区域。

(1) 在Princeton体系结构的情况下,程序中的向量和指针、变量、程序段和保存数据和堆栈的存储器块都具有不同的地址。

(2) 在Harvard体系结构的情况下,程序段和保存数据和堆栈的存储器块具有独立的地址空间。控制信号和读写指令也是分开的(关于段和块,请参见2.5.1节和2.5.2节)。

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-6 (a)Princeton体系结构的存储器映射(b) Harvard体系结构的存储器映射

图2-7给出了80960的外部存储器设备,以及与80960中的端口地址和存储器地址共存的存储器块。系统存储器分配映射(system memory allocation-map)不仅是存储器块中可用地址以及IO设备可以使用的段和地址的反映,也是系统硬件中存储器和IO设备描述的反映。它反映了不同单元中的各种存储器的实际存在性,如EPROM、PROM、ROM、EEPROM、闪存、SRAM(静态RAM)、DRAM(动态RAM)和IO设备。它反映了定位器对程序、数据和IO操作的存储器分配情况。它说明了这些地址上的存储器块和端口(设备)。图2-8(a)和(b)分别给出了68HC11(具有存储器映射的IO体系结构)的存储器和I/O设备存储器的分配映射,以及80x86 PC(具有IP映射的IO体系结构)的分配映射。

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-7 80960的外部存储器设备,以及与端口地址共存的存储器块(还给出了总线信号)

图2-9(a)~(d)给出了4个存储器分配映射的示例。系统I/O设备映射(system I/O device map)可以单独设计。它不仅反映了I/O设备的实际存在性,还反映了各种设备寄存器和端口数据的可用地址(示例设备是定时器。I/O设备是系统的外设单元)。

下面是对图2-9中4个示例系统的定位器的存储器分配映射的介绍。

示例2-12

嵌入式系统示例(借贷卡)的存储器映射需要一个2KB的存储器。它还需要一个256字节的RAM,主要用于堆栈。还需要512字节的EEPROM,用来存储贷方或者借方的余额,以及卡的前一次交易记录。因此这个系统的存储器定位器或者链接脚本程序可以如下定义存储器映射。

1. Memory

2. {ram : ORIGIN = 0x10000, LENGTH = 256

3. eeprom : ORIGIN = 0x20000, LENGTH = 512

4. rom : ORIGIN = 0x00000, LENGTH = 2K

5. }

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-8 (a)68HC11的IO端口、存储器和设备地址空间 (b)基于80x86PC的设备地址

嵌入式系统:体系结构、编程设计 - N~A - 欢迎

图2-9 (a)~(d) 4个示例系统中的4个存储器分配映射及其定位器

示例2-13

嵌入式系统示例(具有加密软件和解密处理的Java嵌入式卡)的存储器映射需要一个32KB的ROM存储器和一个4KB的RAM。它还需要512字节的EEPROM来存储借方和贷方的余额,以及密码关键字和卡的前一次交易记录。因此这个系统的存储器定位器或者链接脚本程序可以如下定义存储器映射。

1. Memory

2. { ram : ORIGIN = 0x10000, LENGTH = 4K

3. eeprom : ORIGIN = 0x20000, LENGTH = 512

4. rom : ORIGIN = 0x00000, LENGTH = 32K

5. }

从上述示例中还可以做出如下重要的判断。不管可用存储器的长度是否非常小,在初始的ROM、RAM和EEPROM之间存在着存储器空间间隔。这个间隔是由硬件设计的设计特征造成的,这样可以在将来不改变存储器和处理器之间的接口译码电路的情况下,对这些存储器进行扩展(参见2.7节)。此外,其软件程序必须做一些小的改动。这些变化只是长度上的。原因是当不存在间隔的时候,起点也要发生变化。这个特征确保了将来程序代码大小和数据大小发生任何变化都没有必要改变定位器代码。定位器也必须有一个特征,使之不必重新定位专用端口的地址,这些专用端口专用于一个特殊的I/O任务或者专用于设备驱动程序的读写操作。在G.2节中介绍了用于设备程序的定位器输出记录的格式。

嵌入式系统设计的最后一个步骤是,在ROM映像中定位引导(复位)程序和数据、初始化数据和标准数据、表或者常量字符串设备驱动程序和数据、各种任务的代码、中断服务例程和操作系统内核(引导程序包含着只有在系统复位时才会执行的指令。引导数据应用的示例是用于堆栈指针的初始化。初始化数据可能用来定义初始状态和系统参数。常量字符串可以用来初始化屏幕显示)。ROM中有一个映像段。在映像段中有初始化数据、常量字符串和启动代码,这些代码在系统开机的时候由影像段复制程序复制到RAM中。当执行开机代码程序的时候,在RAM中就产生了一个从ROM复制来的影像段。RAM还保持了数据(立即数和输出数据)和堆栈。如果系统映射的ROM映像比较长,ROM中存放的是压缩的程序格式。这是因为解压程序和压缩的映像比非压缩的ROM映射需要的存储空间小。开机代码的任务是产生解压缩后的程序代码,并存储到RAM中。处理器从RAM中取回这些代码,并顺序执行。

处理器可以为初始化开机记录提前定义存储器位置。例如在80960中,一个记录包含12个字。它们存储在从0xFFFFFF00~0xFFFFFF 的ROM地址中(参见图2-7)。

示例2-14

在存储器分配映射中由许多节(section)。参考一下它在定位器中的描述。嵌入式系统示例2-12中的借贷卡存储器可以做如下的描述。

1. SECTIONS

2. {/* Stack Top Location for 256 B RAM*/

3. _TopOfStack = 0x10100;

4. /* Bottom of Heap */

5. _BottomOfHeap = 0x10080;

6. text rom :

7. {/* Debit-credit card program instructions are at the text file named here*/

8. * (———.txt)

9. }

10. data ram :

11. {

12. /* Shadow Segment for 16 byte of Initialised Data at RAM for a copy from ROM from */

13. _DataStart = 0x10000;

14. /* Debit-credit card shadow segment data at the data file named here*/

15. * (———.data)

16. _DataEnd = 0x1000F;

17. }

18. /* Command for copy into the RAM */

19. > rom

20. bss :

21. {

22. /* Base Segment for 32 byte of Program Variables Data at RAM */

23. _bssStart = 0x10010;

24. /* Debit-credit card base segment data at the base segment data file named here*/

25. * (———.bss)

26. _bssEnd = 0x1002F;

27. }

28. }

示例2-15

参考一下示例2-13中所描述的嵌入式系统—— Java嵌入式卡的存储器分配映射的段。

1. ECTIONS

2. {/* Stack Top Location in 4 KB RAM*/

3. _TopOfStack = 0x11000;

4. /* Bottom of Heap */

5. _BottomOfHeap = 0x10900;

6. text rom :

7. {/* Encrypting Java Card program instructions are at the text file named here*/

8. * (———.txt)

9. }

10. data ram :

11. {

12. /* Shadow Segment for 256 bytes of Initialised Data at RAM for a copy from */

13. _DataStart = 0x10000;

14. /* The card shadow segment data at the data file named here*/

15. * (———.data)

16. _DataEnd = 0x100FF;

17. }

18. /* Command for copy into the RAM */

19. > rom

20. bss :

21. {

22. /* Base Segment for 2 KB Program Variables Data at RAM */

23. _bssStart = 0x10100;

24. /* Java card base segment data at the base segment data file named here*/

25. * (———.bss)

26. _bssEnd = 0x108FF;

27. }

28. }

注意:

在对指针、向量、数据集合和数据结构进行适当的地址分配后,设计出包括设备I/O地址的存储器映射。根据这个映射,很容易设计出定位器。设计者必须记住,如果主存是Harvard结构,程序存储器映射应该是单独的。例如8051通过单独的指令集(输入/输出指令)从存储器中读取数据。

所有的I/O端口和设备都有地址。它们根据系统处理器和系统硬件的配置分配给各个设备。下面的示例阐明了这种情况。下面考虑具有三个不同处理器的系统。

(1) 先来看一个具有80960嵌入式处理器的系统。图2-7说明,设备的地址处于分配给系统处理器地址和过程、例程的系统表、中断向量表的存储器地址之间。

(2) 考虑另外一个具有68HC11微控制器的系统。图2-8(a)说明,设备地址在RAM中,并且与存储器地址截然不同。

(3) 考虑另外一个具有80x86微处理器的系统。图2-8(b)的左边给出了存储器地址。图的右边给出了IBM PC系统分配给定时器、键盘、实时时钟和串口(称为COM2)的端口地址。这个图说明,设备地址可以与存储器地址相同。此外这还依赖于系统硬件配置。

80960和68HC11将I/O设备地址看作是存储器地址的一部分(参见图2-7和图2-8(b))。图2-8(a)给出了一种68HC11配置寄存器位的特殊情况。图中的配置表明,端口A、I/O控制寄存器PIOC、端口C、B和端口控制寄存器的地址在0x0000~0x0004之间。片上RAM的地址被配置为0x003F~0x0040之间。端口地址和片上RAM可以通过68HC11中的配置寄存器位来配置。例如,可以对上述地址进行配置,并分配在0x0100~0x1040之间。另一方面,80516和8019微控制器的内部设备地址是事先分配的,它们是不可配置的。

在80x86中,I/O设备地址不是存储器地址的一部分(参见图2-8(b))。

第3.1节和第3.2节将详细介绍I/O和其他的设备。设备地址是提供给驱动程序(driver)处理使用的(参见第4章)。一个设备具有一个地址,这个地址通常是根据系统硬件分配的,也可能是处理器分配的。这些地址分配给如下的设备:

(1) 设备数据寄存器(device data register)或者RAM缓冲区。

(2) 设备控制寄存器(device control register)。它保存控制位,也可以保存配置位。

(3) 设备状态寄存器(device status register)。它保存标志位作为设备的状态。一个标志位可以反映服务请求,并表示发生了设备中断。

每一个设备,也就是每一个设备寄存器必须在存储器映射中分配地址。有一点非常重要,在大多数情况下,每个IO设备地址空间都是由系统硬件确定的。定位器或者加载器不能够将它们重新分配给另外的地址空间。另外一点需要记住的就是,根据设备不同,在一个设备地址上可以有一个或者多个设备寄存器。物理或者虚拟设备可以通过配置与接收输入或者发送输出连接或者断开。设备地址也可以像一个文件,使之只读或者只写,或者可读可写。

示例2-16给出了一个I/O设备(串行设备(也称为UART设备))地址的详细介绍。

示例2-16

串行设备(serial line device)具有如下的设备寄存器地址(参见第3.1节的图3-1(b)了解关于UART信号和串行I/O格式的详细内容)。在使用80x86处理器的系统中,这些地址是由其UART端口接口电路硬件配置决定的。在PC中处于COM1,地址是从0x2F8~0x2FE。

(1) (A)两个I/O数据缓冲寄存器(一个用来接收,另外一个用来发送)具有一个公共的地址——0x2F8。假设地址0x2FB上的控制位为0,(i)在从这个地址读取的过程中,处理器访问设备的RBR(Receiver Data Buffer Register,接收数据缓冲寄存器);(ii)在向这个地址写的过程中,处理器访问设备的TRH(Transmitter Holding Register,发送保持寄存器)。RBR和TRH的地址都是0x2F8。(B)假设地址0x2FB的控制位为1,除数锁存器(devisor latch)的两个字节的数据具有不同的地址——0x2F8(LSB)和0x2F9(MSB)。除数锁存器保持了一个16位的数值,用来对系统时钟进行分频。这样就选择了串行发送的速率(然而当编写设备驱动程序的时候,要记住2FB上另外一个寄存器(控制寄存器)的一个位将0x2F8从IO寄存器(RBR或者TRH)改变为除数锁存寄存器的低字节。参见第4.3节的示例)。

(2) 在写操作的过程中,设备的三个控制寄存器分别具有不同的地址—— 0x2FA、0x2FB和0x2FC。这些寄存器如下所述。(i)IER(Interrupt Enabling Register,中断使能寄存器)。它控制设备中断。(ii)LCR(Line Control Register,线路控制寄存器)。它定义了有多少位以及这些位在线路上的情况。(iii)MCR(Modem Control Register,调制解调器控制寄存器)。它定义了调制解调器如何进行“握手”和通信。

(3) 在读操作的过程中,设备的三个状态寄存器分别具有不同的地址—— 0x2FA、0x2FD和0x2FE。这些寄存器如下所述。(i)0x2FA 上的IIR(Interrupt Identification Register,中断识别寄存器)。它具有标志位。标志位在设备中断的时候置位,当对相应的设备中断服务和系统复位的时候复位。(ii)0x2FD上的LCR。它定义了有多少位以及这些位在线路上的情况。(iii)0x2FE上的MCR。它定义了调制解调器如何进行握手和通信。

注意:

每一个I/O设备都具有不同的地址。每一个设备都有三个寄存器组:数据(缓冲)寄存器、控制寄存器和状态寄存器。在一个设备地址上可以有一个或者多个设备寄存器。设备的地址取决于系统处理器和系统硬件配置。多数的处理器采用相同的指令处理存储器设备和其他设备。设计者必须记住,80x86处理器使用不同的指令集(输入-输出指令集)处理这些设备。

 

引用:http://book.csdn.net/bookfiles/59/100591718.shtml

  评论这张
 
阅读(431)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017