1.从计算机应用的角度定义“嵌入式系统”:以应用为中心、以计算机技术为基础,软、硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统。嵌入式系统是应用于特定环境下执行面对专业领域的应用系统,其特点为:系统内核小,可裁剪;专业性强;系统精简;通常要求有高实时性的操作系统;嵌入式系统开发需要专门的开发工具和环境;一旦进入市场,就具有较长的生命周期。
2.嵌入式系统与通用计算机系统相比,具有系统内核小、专用性强、系统精简、专用的开发工具与环境、软件固化等特点。
3.在嵌入式系统应用领域,说明RTOS和BSP/HAL的含义:
RTOS(real time operatring system):实时操作系统,它是一个能够在指定或确定时间内完成系统功能,即对外部事件在同步或异步时间内作出响应的系统。一般只有最高优先级的任务才能占有CPU的控制权;BSP(板级支持包, Board Support Package)是介于硬件和操作系统之间的硬件抽象层的一种具体实现。
4.在嵌入式系统的软硬件架构中,硬件抽象层(HAL)或板级支持包(BSP)的作用是什么?
在嵌入式系统的架构中,硬件抽象层(HAL)位于操作系统内核与硬件电路之间的接口,其主要目地是将硬件抽象化,即可以通过程序来控制所有硬件电路的操作,这就使得系统的设备驱动程序与硬件设备无关,从而大大提高了系统的可移植性。
板级支持包(BSP)是介于主板硬件和操作系统中驱动层程序之间的一层,一般认为它属于操作系统的一部分,主要是实现对操作系统的支持,为上层的驱动程序提供访问硬件设备寄存器的函数包,使之能故更好的运行于硬件主板。
5.嵌入式处理器的存储体系结构有冯诺依曼体系机构和哈佛体系结构,他们有何区别,ARM7系列的嵌入式处理器属于哪一种?
冯诺依曼体系结构:采用将程序指令存储器和数据存储器合并在一起的存储器结构,程序指令存储地址和数据存储地址指向同一个指向同一个存储器的不同存储物理位置。因此,程序指令和数据的宽度相同。
哈佛体系结构:使用两个独立的存储器模块,分别存储指令和数据,每个存储模块都不允许指令和数据并存,以便实现并行处理。使用独立的两条总线,分别作为CPU与每个存储器之间的专用通信路径,这两条总线之间毫无关联。
ARM7是冯·诺依曼体系,ARM9是哈佛结构
6.嵌入式系统的基本组成要素是硬件系统及软件系统。硬件系统包括存储器,运算器,控制器;软件系统包括输入设备,输出设备,设备驱动及应用程序。
7.嵌入式系统的开发通常要经过5个阶段,它们分别是系统需求分析、系统总体结构设计、硬/软件协同设计、系统集成与调试和系统测试。
8.设计一个完整的BSP需要做的两部分工作是嵌入式系统初始化和编写硬件相关的设备驱动程序,而嵌入式系统初始化包括哪些基本内容?
初始化异常向量表(中断向量表),初始化存储系统,初始化堆栈,初始化有特殊要求的端口和设备,初始化应用程序的运行环境,调用主应用程序。
9.对实时系统中“实时”如何理解,实时系统与分时系统的区别
实时系统它是一个能够在指定或确定的时间内完成系统功能,即对外部事件在同步或异步时间内作出响应的系统,一般只有最高优先级的任务才能占有CPU的控制权。
分时系统,强调系统资源利用率,不要求响应的实时性,适合于通用系统。
10.处理器的系统机构有CISC和RISC。RISC结构处理器有电路简单、速度快、芯片面积小、开发周期短等特点,便于采用流水线技术。ARM处理器的系统结构式RISC系统结构。
11.CISC:复杂指令集(Complex Instruction Set Computer)①具有大量的指令和寻址方式,②指令长度不统一,高性能的VLSI实现难度大,③CISC多采用微指令技术,④增加指令系统的功能,简化了目标软件的设计,但增加了硬件(微程序)复杂度,⑤程序执行时间不一定短,⑥CISC大多使用微码ROM进行指令译码(存储逻辑型)。
12.RISC:精简指令集(Reduced Instruction Set Computer)①只包含最有用的指令,②确保数据通道快速执行每一条指令,③使CPU硬件结构设计变得更为简单,④RISC指令格式和长度固定,指令类型少,功能简单,寻址方式少,译码控制器可采用规则的硬布线逻辑(组合逻辑型。
20%与80%:20%的简单指令利用率达到80%,80%的复杂指令的使用概率只有20%
13.ARM微处理器共有37个32bits寄存器。其中R13(SP),LR(R14),R15(PC),R16(CPSR)的有何用途,SPSR有何用途
R13是一个32位的通用寄存器,通常用作堆栈指针寄存器。
R14是一个32位的通用寄存器,亦称连接寄存器,用于保存子程序的返回地址。
R15程序计数器,控制程序的执行顺序。
CPSR是当前程序状态寄存器,用于保存条件码标志,中断标志和运行模式控制位。
SPSR是CPSR的备份寄存器,用于保存CPSR的值。
14.从编程的角度看,ARM微处理器的工作状态一般有ARM状态和Thumb状态,ARM状态时处理器执行32位的字对齐指令,而Thumb状态时处理器执行的是16位的半字对齐指令,ARM微处理器的工作状态的转换可以通过BX指令来实现。
15.ARM处理器支持7种运行模式分别为:用户模式,快速中断模式(fiq),中断模式(irq),管理模式(svc),中止模式(abt),未定义模式(und)和系统模式。
16.在ARM嵌入式处理器系列中,有ARM7TDIMI,ARM9TDMI的CPU核,解释其中 TDMI的含义。
T支持16位的Thumb指令集,D支持偏上Debug,M片内嵌有硬件乘法器,I嵌入式在线上仿真ICE
17.ARM嵌入式处理器的指令系统采用RISC体系,RISC有何主要特点:
①采用固定长度的指令格式,指令规整、简单 ②使用单周期指令 ③大量使用寄存器
18.ARM嵌入式处理器支持7种异常,对于复位异常,ARM嵌入式处理器是如何处理的,复位异常向量地址是什么?
复位异常通常是由系统加电或硬件强制使处理器的复位引脚出现负跳变而产生的,当处理器复位引脚出现负跳变时,当前程序运行程序跳转到复位处理程序处执行,并将连接寄存器LR的值减去相应的偏移量后送到PC中,将SPSR复制回CPSR中,若在进入异常处理时设置了中断禁止位,要在此清除。
复位向量地址是0x0000 0000开始的连续4个字节。
19.嵌入式系统实验中用的硬件平台是以EP7312微处理器为核心的实验系统,EP7312是ARM7微处理器家族中的一种,其内嵌JTAG,ICE,MMU,Cache,说明其含义与用途。EP7312的CPU核是什么?
JTAG是一种国际标准测试协议,主要用于芯片内部测试及系统进行仿真、测试。
ICE是In-Circuit Emulator
MMU指存储管理单元,用于实现虚拟地址空间到屋里存储空间的映射,存储器访问权限的控制,设置虚拟存储空间的缓冲特性。
Cache称高速缓冲存储器,主要用来提高存储系统的性能,数据的告诉读/写。
EP7312的CPU核是ARM720T
20.以ARM处理器为核心的嵌入式系统的程序设计中要遵守ATPCS,解释ATPCS。
ATPCS最早是为方便ARM程序与Thumb程序之间相互调用规定的一些(包括寄存器使用,数据栈使用,参数传递)规则,而ATPCS的扩充版还规定了C语言与汇编语言之间相互调用的规则。
21.什么是函数的可重入特性,它对多任务调度有何影响,如何将非重入函数改写为重入函数?
如果一个函数任何时候都可被中断,一段时间后又可以运行,而相应的数据不会丢失,该函数具有可重入性。可重入函数可以被一个以上的任务调度,而不必担心数据被破坏。对于非重入函数,将其中的全局变量改为局部变量或使用信号量技术,可使其具有可重入性。
22.ARM处理器的数据存取格式有大端格式和小端格式,它可以通过外围引脚的点平高低来设置。
23.ARM处理器IRQ和FIQ的响应与否是由CPSR的I位和F位值决定的。
24.UC/OSII的任务有5个状态,画出UC/OSII的任务状态装换图
休眠态:任务仅驻留在程序空间,还没有交给mC/OS-II管理;就绪态:任务一旦建立,这个任务就进入就绪态,准备运行;运行态:任何时刻只能有一个任务处于运行态;等待状态:正在运行的任务可能需要等待某一事件的发生或将自己延迟一段时间;中断服务态:正在运行的任务是可以被中断的,除非该任务将中断关闭;被中断了的任务进入了中断服务态。
25.UC/OSII移植是指使UC/OSII内核能在其他的处理器上运行,简述UC/OSII的移植过程
①设置OS_CPU.H中与处理器和编译器有关的代码:与编译器有关的数据类型;中断屏蔽OS_ENTER_CRITICAL()和退出中断屏蔽的宏定义OS_EXIT_CRITICAL();栈增长方向标志OS_STK_GROWTH。
②用汇编在OS_CPU_A.S文件中编写与微处理器相关的函数:调用优先级最高的就绪任务函数OSStartHighRdy();任务级的任务切换函数OSCtxSw();中断级的任务切换函数OSIntCtxSw()。
③用C语言编写6个和操作系统有关的函数(OS_CPU_C.C中)OSTaskStkInit()(这个必须移植,初始化任务堆栈用),OSTaskCreateHook(),OSTaskDelHook(),OSTaskSwHook(),OSTaskStatHook(),OSTimeTickHook()
26.UC/OSII是可移植的,制度的,占先式的多任务实时内核,能同时管理多达64个任务。所谓的移植是指一个操作系统经少量修改后,可以在某个处理器或微控制器上运行。
27.UC/OSII控制下的任务状态有5个,他们分别是,睡眠状态,准备就绪,运行状态,中断状态和挂起状态。
28.在嵌入式系统运行中,为何要设置临界段,UC/OSII中实现临界段设置的两个函数是什么?
为了保证默写关键代码在运行时不被中断,需要将其设置为临界段,系统在进入临界段之前要关中断,而临界段代码执行完以后要立即开中断。UC/OSII中实现临界段设置的两个函数是OS_ENTER_CRITICAL()和0S_EXIT_CRITICAL().
29.在UC/OSII移植中,除了需要对UC/OSII文件中的OS_CPU.H、OS_CPU_A.ASM、和OS_CPU.C三个文件修改外,还要对配置有关的OS_CFG.H和INCLUDES.H文件修改。
30.嵌入式操作系统有RTOS何DTOS之分,说明RTOS的实时性含义:
RTOS指实时操作系统。RTOS的实时性并非是简单的要求嵌入式操作系统响应速度快,而是要求嵌入式操作系统对外部事件和软件任务请求的响应事件具有严格的确定性。
31.UC/OSII的文件结构包括哪3部分内容,与CPU有关的代码文件有哪些?
32.在多任务系统中,实现资源共享要避免竞争和数据的破坏,必须保证没任务在处理共享数据时互斥。满足互斥条件的方法有哪些?
33.在实时操作系统中,硬实时操作系统与软实时操作系统有何区别?
软实时系统仅要求事件响应是实时的,并不要求限定某一任务必须在多长时间内完成;而在硬实时系统中,不仅要求任务响应要实时,而且要求在规定的时间内完成事件的处理。通常,大多数实时系统是两者的结合。
34.为了实现共享资源的互斥访问,常用哪些方法?
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。2、互斥量:为协调共同对一个共享资源的单独访问而设计的。
3、信号量:为控制一个具有有限数量用户资源而设计。
4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。
35.在多任务调度中,常常用到信号量,说明信号量的概念。
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。
21.对异常的响应过程:
当一个异常出现以后,ARM微处理器会执行以下几步操作①将下一条指令的地址(PC)存入相应连接寄存器LR_mode,以便程序在处理异常返回时能从正确的位置重新开始执行。②将CPSR复制到相应的SPSR中。③根据异常类型,强制设置CPSR的运行模式位。④强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。
异常处理完毕之后,ARM处理器会执行以下几步操作从异常返回:①将连接寄存器LR_mode的值减去相应的偏移量后送到到PC中。②将相应的SPSR复制回CPSR中,以恢复异常出现前的状态。③若在进入异常处理时设置了中断控制位,要在此时清除。
20.用ARM指令和C语言编写一个完成两个64位二进制数相加的程序(加法子程序用汇编语言,主程序用C语言)
#include <stdio.h>
#include <string.h>
Extern void add_asmsub( int a ,int b , int c , int d);
Void main()
{ char *as,*bs,*cs;
long int a=111111; /*加数高位 */
long int b=12222; /*加数低位 */
long int c=211111;/*被加数高位*/
long int d=22222; /*被加数低位*/
add_asmsub (a,b,c,d);
as=isalnum(a);
bs=isalnum(b);
strcat(as,bs);
printf("%s\n",as);
}
AERA add_asm, code,readonly
EXPORT add_ asmub
add_asmsub
ADDS R1,R1,R3
ADCS R0.R0,R2
MOB PC,LR
END
1.程序示例:数据块复制: 本程序将数据从源数据区src复制到目标数据区dst。复制时,以8个字为单位进行。对于最后所剩不足8个字的数据,以字为单位进行复制。(这时程序跳转到Copywords处执行)在进行以8个字为单位的数据复制时,保存了所用的8个工作寄存器。
AREA Block,CODE,READONLY ;
unm EQU 20 ;
ENTRY;
Start
LDR r0,=src ;
LDR r1,=dst ;
MOV r2;#unm ;
MOV sp,#0x400 ;
Blockcopy
MOVS r3,r2,LSR #3 ;
BEQ copywords ;
STMFD sp!,{r4-r11};保存工作寄存器
Octcopy
LDMIA r0!,{r4-r11};
STMIA r1!,{r4-r11};
SUBS r3,r3,#1 ;
BNE Octcopy ;
LDMFD sp!,{r4-r11} ;
Copywords
ANDS r2,r2,#7 ;
BEQ Stop ;
Wordcopy
LDR r3,[r0],#4 ;
STR r3,[r1],#4 ;
SUBS r2,r2,#l ;
BNE Wordcopy ;
Stop ;程序退出
MOV r0, #0x18
AREA BlockData ,DATA,READWRITE ;
Src DCD 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4 ;
Dst DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
END ;结束汇编
2. 利用跳转表实现程序跳转: 跳转表中存放的是各子函数的地址,选择不同子程序的参数是该子程序在跳转表中的偏移量。r3寄存器中存放的是跳转表的基地址.r0寄存器的值用于选择不同的子程序。
AREA Jump,CODE,READONLY ;设置本段程序的名称 (Jump)及属性
num EQU 2 ;跳转表中的子程序个数
ENTRY ;程序执行的入口点
Start
MOV r0,#0 ;设置3个参数,然后调用于程序arithfunc,进行算术运算
MOV r1,#3
MOV r2,#2
BL arithfunc ;调用子程序arithfunc
Stop ;程序退出
MOV r0, #0x18
LDR r1,=0x20026
SWI 0x123456
Arithfunc ;子程序arithfunc入口点
CMP r0,#unm ;判断选择子程序的参数是否在有效范围之内
MOVHS pc,lr ;若不在,则直接返回
ADR r3,JumpTable ;读取跳转表的基地址
LDR pc,[r3,r0,LSL #2] ;根据参数r0的值跳转到相应的子程序
JumpTable
DCD DoAdd
DCD DoSub
DoAdd ;子程序DoAdd执行加法操作
ADD r0,r1,r2
MOV pc,lr
DoSub ;子程序DoSub执行减法操作
SUB r0,r1,r2
MOV pc,lr
END ;结束汇编
3.进行状态切换的程序示例, ARM到Thubm状态;Thumb到ARM状态
AREA AddReg,CODE,READONLY
ENTRY
Main
ADR r0,ThumbProg+1 ;将ThumbProg+1地址值读取到r0
BX r0 ;跳到ThumbProg,程序切换到Thumb状志
CODE16 ; CODE16指示编译器后面的为Thumb指令
ThumbProg
MOV R2,#2
MOV R3,#3
ADD R2,R2,R3
ADR r0,ARMProg
BX r0 ;跳转到ARMProg,程序切换到ARM状态
CODE32 ;CODE32指示编译器后面的为ARM指令
ARMProg
MOV r4, #4
MOV r5, #5
ADD R4,R4,R5
Stop
MOV r0,#0x18
LDR R1,=0x20026
SWI 0x12345
END ;结束汇编
4. 混合编程中需遵循一定的ATPCS规则: 汇编程序的设计要遵守ATPCS,保证程序调用时参数的正确传递。在汇编程序中使用EXPORT伪操作声明本程序,使得本程序可以被别的程序调用。在C语言程序中使用extern关键词声明该汇编程序。
#include<stdio.h>
extern void strcopy(char d,const char *s);//使用关键字extern声明strcopy
int main()
{
const char *srcstr=“First string - source”;char dststr[]=“second string - destination”;
printf(“Before copying:\n”); printf(“%S\n%S\n” srcstr,dststr);
strcopy(dststr,srcstr);//调用汇编,将源串和目标串地址传递给 strcopy,dststr是第1参数,srcstr是第2参数 ATPCS规则 printf(“After copying:\n”);Printf(“%s\n%s\n”,srcstr,dststr);return(0); }
AREA scopy CODE, READONLY
EXPORT strcopy ;使用EXPORT伪操作声明本汇编程序
Strcopy ;寄存器RO中存放第1个参数,即dststr, 寄存器R1中存放第2个参数,即srcstr
LDRB R2,[R1],#1 ;读一个源字符
STRB R2,[R0],#1 ;写一个字符于目的地
CMP R2, #0 ;0为字符串结束标志
BNE strcopy
MOV PC,LR ;返回
END
5. 汇编程序调用C程序示例:汇编程序的设计要遵守ATPCS,保证程序调用时参数的正确传递 ,在汇编程序中使用IMPORT伪操作声明将要调用C程序。
//c程序g()返回5个整数的和
int g(int a, int b, int c, int d ,int e) //5个参数
{ return a + b + c + d + e; }
EXPORT f ;声明符号f可被其他文件引用
AREA f, CODE,READONLY
IMPORT g ;使用伪操作IMPORT声明C程序g()
STR lr,[sp,#-4]! ;保存返回地址
ADD r1,r0,r0 ;假设进入程序f时,r0中值为i,r1值设为2×i
ADD r2,r1,r0 ;r2值设为3×i
ADD r3,r1,r2 ;r3值先设为5×i
STR r3,[sp,#-4]! ;第五个参数通过数据栈传递
ADD r3,r1,r1 ;r3值设为4×i
BL g ;调用C程序g()
ADD sp,sp,#4 ;调整数据栈指针,准备返回
LDR pc,[sp],#4 ;返回
END
6.用ARM汇编语言指令和C语言编写一个完成64位二进制数相加的程序(加法子程序用汇编语言编写,主程序用C语言编写)
#include<stdio.h>
#include<string.h>
Extern void add-asmsub(int a, int b, int c,int d);
Void main()
{
Char *as, *bs, *cs;
Long int a=111111;
Long int b=12222;
Long int c=211111;
Long int d=22222;
Add-asmsub(a,b,c,d);
As=isalnum(a);
Bs=isalnum(b);
Stacat(as, bs);
Printf(“%s\n”,as);
}
AERA add-asm, CODE ,READONLY
EXPORT add=asmsub
Add-asmsub
ADDS R1,R1,R3 ;低32bit相加,和送往R1
ADCS R0,R0,R2 ;高32bit带进位相加,和送往R0
MOV PC,LR
END
7. EXAMPLE 求两个整数的最大公约数
; int gcd (int a ,int b)
; {
; while (a!=b)
; {
; if (a>b)
; a=a-b;
; else
; b=b-a;
; }
; return a;
; }
AREA gcd, CODE, READONLY ALIGN=3
ENTRY
start CMP R0,R1
BEQ stop
BLT less
SUB R0,R0,R1
B start
less SUB R1,R1,R0
B start
stop NOP
END
AREA gcd, CODE, READONLY ALIGN=3
ENTRY
start CMP R0,R1
SUBGT R0,R0,R1
SUBLT R1,R1,R0
BNE start
END
BL SUB1 /*调用子程序SUB1*/
reAdd: /*返回地址*
SUB1: STMFD SP!, {<regs>, LR}/*将寄存器列表和R14存入堆栈*
LDMFD SP, {<regs>, PC} /*完成子程序返回 */
或 MOV PC, LR /*R14→R15,即LR→PC*/
或 BX LR /*跳转指令 LR→PC*/
8. 以下指令序列完成两个128位数的加法,第一个数存放在寄存器R7~R4,第二个数存放在寄存器R11~R8,运算结果存放在寄存器R3~R0:
ADDS R0,R4,R8 ; 加低端的字
ADCS R1,R5,R9 ; 加第二个字,带进位
ADCS R2,R6,R10 ; 加第三个字,带进位
ADC R3,R7,R11 ; 加第四个字,带进位
SUB R0,R1,R2 ; R0 = R1 - R2
SUB R0,R1,#256 ; R0 = R1 - 256
SUB R0,R2,R3,LSL#1 ; R0 = R2 - (R3 << 1)
以下指令序列实现64减法(R1,R0)-(R3,R2)
SUBS R0,R0,R2
SBC R1,R1,R3
下列指令实现64位数据的负数
RSBS R2,R0,#0
RSC R3,R1,#0
OSCtxSw();
Stmfd sp!, {lr}
Stmfd sp!, {r0-r12,lr}
Mrs r4!, cpsr
Stmfd sp!, {r4}
Mrs r4!, spsr
Stmfd sp!, {r4}
Ldr r4, =OSPrioCur
Ldr r5, =OSPrioHighRdy
Ldrb r6, [r5]
Strb r6, [r4]
Ldr r4, =OSTCBCur
Ldr r5, [r4]
Str sp, [r5]
Bl OSTaskSwHook
Ldr r6, = OSPrioHighRdy
Ldr r6, [r6]
Ldr sp, [r6]
Str r6, [r4]
Ldmfd sp!, {r4}
Msr SPSR-cxsf, r4
Ldmfd sp!, {r4}
Msr CPSR-cxsf, r4
Ldmfd sp!, {r0-r12, lr, pc}
STMFD SP!, {<regs>, LR}
LDMFD SP, {<regs>, PC}