赞
踩
第一部分:嵌入式系统基础
1.系统响应时间:系统收到处理要求到系统给出应答信号的时间。任务换道时间:任务之间切换使用的时间.中断延迟:计算机接收到中断信号到操作系统作出响应,并完成换道转入中断服务程序的时间。
2.实时操作系统中的任务有四个状态:运行、就绪、挂起、冬眠。①运行:获得CPU的控制权。② 就绪:进入任务就绪(等待)队列,等待通过调度转为运行状态。③挂起:任务发生阻塞,移出任务就绪队列,等待系统实时事件的发生而唤醒,从而转为 就绪 或 运行。④冬眠:任务完成或错误等原因被清除的任务,也可以认为是系统中不存在的任务。
3.实时操作系统的 首要任务是调度一切可利用的资源完成 实时控制任务,其 次才是着眼于系统的使用效率。
第二部分:ARM处理器及系统结构
1.ARM 体系结构与纯粹的 RISC 体系结构的不同点:① 一些特定指令的周期数可变,并不是每条ARM指令都是单周期的。 ② 内嵌的桶形移位器产生了更为复杂的指令,扩展了指令的功能,因此改善了内核的性能。 ③ 支持16位的Thumb指令集,提高了代码密度。 ④ 支持条件执行:每条指令都可以设置一个执行条件,只有条件满足时才执行。 ⑤ 增强指令:一些功能强大的数字信号处理指令被加入到ARM指令集中。
2.ARM9 的 5 级流水线:ARM的5级流水线分别位取指、译码、执行、缓存/数据和回写:
(1)取指:指令从存储器中取出,放入指令流水线;
(2)译码:指令译码,从寄存器堆中读取寄存器操作数;
(3) 执行:把一个操作数移位,产生ALU的结果。如果指令是Load或Store,在ALU中计算存储器的地址;
(4)缓存/数据:如果需要,则访问数据存储器;否则,ALU的结果只是简单地缓冲一个时钟周期,以便使所有指令具有同样的流水线流程;
(5)回写:将指令产生的结果写回到寄存器堆,包括任何从寄存器读出的数据。
3.存储器结构:ARM处理器有的带有指令cache和数据cache,但不带有片内RAM和片内ROM。系统所需的RAM和ROM(包括Flash)都通过总线外接。有的ARM片内还带有存储器管理单元MMU。
4.在异常发生后,ARM内核会作以下工作:
(1) 在适当的LR中保存断点的地址,无论是ARM状态还是Thumb状态,ARM都将当前PC寄存器的值(运行指令地址加4或加8 )复制(取决于异常的类型) 到LR中;
(2)把当前程序状态寄存器(CPSR)中的内容保存到模式私有寄存器SPSR中;
(3)将寄存器CPSR中的MODE域设置为中断(异常)应进入的运行模式;
(4)对CPSR的I位和F位进行相应的设置,以防止再次响应同一个中断请求。
(5)强制PC从相关的异常向量处取指,即到中断向量表中获取中断向量,转向用户所编写的中断(异常)服务程序。
5.未定义指令异常是内部异常中断。当ARM处理器遇到一条自己和系统内任何协处理器都无法执行的指令时,就会发生未定义指令异常,从而进入中断处理程序;软件可使用这一机制,通过仿真未定义的协处理器来扩展ARM指令集。 在仿真未定义的指令后,不管处于哪种处理器操作状态(ARM或Thumb状态),处理器执行下面的指令返回:MOVS PC, R14_und,MOVS指令将R14的值写入PC,CPSR将自动从SPSR寄存器中恢复并返回到未定义指令之后的指令。
6.ARM 推出的 Cortex 系列包括:Cortex-A、Cortex-R 和 Cortex-M 三个系列。 Cortex-A 系列主要应用于复杂的应用中,支持:ARM、Thumb 和 Thumb2 指令集。Cortex-R 系列 是为实时操作系统设计的嵌入式处理器,能带来更 小的芯片面积和低功耗。Cortex-M 适用于高性能、低成本需求的嵌入式应用。 Cortex-M 主要针对 单片机领域
7.ARMv5TEJ 的后缀意义如下: T:支持 16 位 Thumb 指令集; E:扩展表示在通用的 CPU 上提供 DSP 能力; J:增加了 Jazelle 扩展以支持 Java 加速技术。
8.MMU 存储器系统的结构允许对存储器系统实施精细控制,而 MMU 只由 ARM 中协处理器(CP15)控制。
第三部分:ARM编程基础
1.有效立即数immediate可以表示成:<immediate>=immed_8 循环右移(2×rot)。4 bit 移位因子 (0-15)乘于2,得到一个范围在0-30,步长为 2的移位值。因此,将ARM中的立即数称为8位位图。“最后8位移动偶数位”得到立即数。汇编编译器选择使rot数值最小的编码方式。
2.共有6种移位方式: LSL 逻辑左移;LSR 逻辑右移;ASL 算术左移;ASR 算术右移:算术移位的对象是带符号数,移位过程中必须保持操作数的符号不变。如果源操作数是正数,空出的最高有效位用0填充,如果是负数用1填充;ROR 循环右移:移出的字的最低有效位依次填入空出的最高有效位;RRX 带扩展的循环右移:。将寄存器的内容循环右移1位进入c标志位,空位用原来C标志位填充
3.如果指令带有S后缀(除了比较指令以外),同时又以PC为目标寄存器进行操作:在异常模式下:则操作的同时从SPSR恢复CPSR。
4.指令编码中I用于区别立即数(I为1)或寄存器移位(I为0)
5.乘法指令的特点:(1)不支持第2操作数为立即数。(2)结果寄存器不能与第一源寄存器相同。(3)Rd、RdHi、RdLo不能与Rm为同一寄存器。RdHi和RdLo不能为同一寄存器。(4)避免将R15定义为任一操作数或结果寄存器。(5)早期的ARM处理器仅支持32位乘法指令。ARM7版本和后续的在名字中有M的处理器才支持64位乘法指令。
6.杂项指令注意事项:(1)控制域的修改问题:只有在特权模式下才能修改状态寄存器的控制域[7:0],以实现处理器模式转换,或设置开/关异常中断 。(2)T控制位的修改问题:程序中不能通过MSR指令,直接修改CPSR中的T控制位来实现ARM状态/Thumb状态的切换,必须使用BX指令完成处理器状态的切换。(3)用户模式下能够修改的位:在用户模式只能修改“标志位域”,不能对CPSR[23:0]做修改。(4)S后缀的使用问题:在MRS/MSR指令中不可以使用S后缀。
7.ARM 指令代码一般可以分为 5 个域,分别是:条件码域、指令代码域、第 1 个操作数寄存器 Rn、目标或源寄存器 Rd、第二个操作数。
8.将寄存器R0中的数据存储方式转换成另一种存储方式。指令执行前R0中数据存储方式为:R0=A,B,C,D;指令执行后R0中数据存储方式为:R0=D,C,B,A。
- EOR R1,R0,R0, ROR #16 ;R1=A^C,B^D,C^A,D^B
-
- BIC R1,R1,#0xFF0000 ;R1=A^C,0,C^A,D^B
-
- MOV R0,R0,ROR #8 ;R0=D,A,B,C
-
- EOR R0,R0,R1,LSR #8 ;R0=D,C,B,A
9.将内存中从0x400800开始的100个字数据相加,其结果存于R3、R2中(R3中为高32位):
- LDR R0,=0x400800
-
- MOV R1,#100 ;初始化循环次数
-
- MOV R2,#0
-
- MOV R3,#0
-
- loop ;循环体
-
- LDR R4,[R0],#4
-
- ADDS R2,R2,R4
-
- ADC R3,R3,#0 ;或者ADDCS R3,R3,#1
-
- SUBS R1,R1,#1;循环计数器减1,设置条件标志
-
- BNE loop ;循环计数器不为0,跳到loop继续执行
9.编写一个程序,把首地址为DATA_SRC的80个字的数 据复制到首地址为DATA_DST的目标数据块中。
- LDR R1,=DATA_SRC
-
- LDR R0,=DATA_DST
-
- MOV R10,#10
-
- LOOP LDMIA R1!,{R2-R9}
-
- STMIA R0!,{R2-R9}
-
- SUBS R10,R10,#1
-
- BNE LOOP
11.要求编写一个程序,在 Start 数据列表中查找是否包含 NewItem 单元中的数据。如果包含则把该数据在列表中的位置序号(1、2、3、4)存储到 Index 字存储单元中。否则在Index 字存储单元中存储 0xFFFFFFFF
LDR R0,=Start LDR R1,=NewItem LDR R6,=Index LDR R3,[R1] MOV R4,#1 LOOP LDR R2,[R0, #4]! CMP R2,R3 STREQ R4,[R6] ;查找到该数据,将下标存储到Index ADD R4,R4,#1 MOVEQ R4,#5 ;查找到该数据,将R4设置为5,退出循环 CMP R4,#5 BNE LOOP |
AREA mydata,DATA,READWRITE Start SPACE 6 AREA pro7,CODE,READONLY ENTRY LDR R0,=StartOR LDR R1,=Start LDRB R2,[R0] ;将排序个数送到R2 STRB R2,[R1],#1 MOV R3,R2 ;R3为比较次数 SUB R3,R3,#1 OUTLOOP MOV R4,#0 ;外层循环 LDR R0,=StartOR ADD R0,R0,#1 INNERLOOP ;内层循环 LDRB R5,[R0],#1 ;取操作数 LDRB R6,[R0] ;取下一个操作数 CMP R5,R6 STRBCC R6,[R0,#-1] ;R5操作数小于R6操作数时进行交换 STRBCC R5,[R0] ADD R4,R4,#1 CMP R4,R3 ;比较R3次 BNE INNERLOOP LDRB R7,[R0] STRB R7,[R1,R3] SUBS R3,R3,#1 BNE OUTLOOP LDRB R7,[R0,#-1] STRB R7,[R1,R3] StartOR DCB 5,12,36,3,85,67 END |
第四部分:S3C2440嵌入式系统
1.S3C2440A 专用寄存器注释:①在小端模式下,必须使用小端地址;大端模式下,必须使用大端地址②每个特殊寄存器必须按照推荐的方式进行操作;③除了ADC寄存器,RTC寄存器 和 UART寄存器外,其他寄存器都必须以字为单元(
32位)进行读写;④对ADC,RTC,UART寄存器进行读/写时,必须仔细考虑使用的大/小端模式;⑤W:32位寄存器,必须用 LDR/STR 指令或i整型数型指针(int *)进行访问;HW:16位寄存器,必须用 LDRH/STRH 或短整型数指针(short int *)访问;B:8位寄存器,必须用 LDRB/STRB 或字符型指针(char *)访问。
2.中断控制器提供60个中断源的管理是如何实现的?S3C2440将中断源分为两级: 中断源和子中断源(次级中断源): 中断源就是上图32个中断源。而这32个中断源中包含单一中断源和复合中断源。 复合中断源是子中断源(次级中断源)的复合信号。比如:INT_UARTn。这种设计,使S3C2440中断控制器支持60个中断源
3.编写中断服务程序:
(1)s3c2440.s中中断向量以及中断服务程序相关的程序段如下(简化版):
PRESERVE8 AREA RESET, CODE, READONLY Vectors LDR PC, Reset_Addr LDR PC, Undef_Addr LDR PC, SWI_Addr LDR PC, PAbt_Addr LDR PC, DAbt_Addr DCD 0x4000 LDR PC, IRQ_Addr LDR PC, FIQ_Addr Reset_Addr DCD Reset_Handler Undef_Addr DCD Undef_Handler SWI_Addr DCD SWI_Handler PAbt_Addr DCD PAbt_Handler DAbt_Addr DCD DAbt_Handler DCD 0 ; Reserved Address IRQ_Addr DCD IRQ_Handler FIQ_Addr DCD FIQ_Handle |
重新定义的IRQ_Handler中断服务程序。(IRQ_ISR.s)
PRESERVE8 GET 2440addr.inc _ISR_STARTADDRESS EQU 0x301fff00 AREA IRQ_ISR, CODE, READONLY IRQ_Handler PROC EXPORT IRQ_Handler IsrIRQ sub sp,sp,#4 ;reserved for PC ;保留一个堆栈单元,用于存放跳转地址,为出栈到PC做准备 stmfd sp!,{r8-r9} ldr r9,=INTOFFSET ;获取INTOFFSET 寄存器的地址,INTOFFSET 寄存器的值 ;说明了INTPND寄存器中哪一个IRQ模式的中断请求有效 ldr r9,[r9] ldr r8,=HandleEINT0 ;获取自定义IRQ向量表的首地址,即EINT0对应的地址 add r8,r8,r9,lsl #2 ;自定义IRQ向量表的首地址+对应的偏移量 ldr r8,[r8] ;从对应的IRQ向量表中取得中断服务程序入口地址 str r8,[sp,#8] ;把获得的中断服务程序入口地址存入预留的堆栈单元中 ldmfd sp!,{r8-r9,pc} ;出栈操作,恢复r8和r9的原始值,并把中断服务程序入口地址 ;弹入到PC中,转到对应中断服务程序执行。 ENDP ;=============用于自定义IRQ中断向量设置============== ALIGN AREA RamData, DATA, READWRITE MAP _ISR_STARTADDRESS ;IRQ中断向量从_ISR_STARTADDRESS开始存放 HandleEINT0 # 4 HandleEINT1 # 4 HandleEINT2 # 4 HandleEINT3 # 4 HandleEINT4_7 # 4 HandleEINT8_23 # 4 |
这 里 定 义 了 一 个 数 据 段RamData,专门用于存放中断服务程序的跳转地址。HandleEINT0存储单元中存放的就是EINT0中断服务程序的地址。相关地址可以由开发人员自行填充。
void IRQ_init(void) { //下面语句用于把bit8和bit9被清0,其余位保持不变 rEINTMASK &= ~((1<<8)|(1<<9)); //使中断不被屏蔽 pISR_EINT8_23 = (U32)Key_ISR; //中断服务程序 EnableIrq(BIT_EINT8_23); //使能中断 } <2440addr.h>中定义 #define EnableIrq(bit) rINTMSK &= ~(bit) //上面语句用于把INTMSK寄存器中的对应bit清0,使能中断 static void __irq Key_ISR(void) //定义中断服务程序 { if(rINTPND==BIT_EINT8_23) { //INTPND同时只能有一位为1 ClearPending(BIT_EINT8_23); //清SRCPND、INTPND if(rEINTPEND&(1<<8)) { //判断EINT8是否发生中断 rEINTPEND |= 1<< 8; //清EINT8中断 button1press(); } if(rEINTPEND&(1<<9)) { rEINTPEND |= 1<< 9; button2press(); } } 。。。。。 } <s3c2440.h>中定义 #define ClearPending(bit) { SRCPND = bit;INTPND = INTPND; } |
__irq”专门用来声明IRQ中断服务程序。如果用“__irq”来声明一个函数,那么该函数表示一个IRQ中断服务程序,编译器便会自动在该函数内部增加中断现场保护的代码。同样一个函数,如果将关键字“__irq”去掉,那么编译器便不会增加现场保护的代码,而只是作为一个普通函数来处理。 用“__irq” 声明后,进入中断服务器程序时,会使用以下语句保护现场:STMDB R13!, {Rxx, R14}离开程序时,会使用以下语句恢复现场:LDMIA R13!, {Rxx, R14} SUBS PC, R14, #0x00000004
4.SDRAM 刷新模式有两种:自动刷新(AR)与自我刷新(SR),对应 DRAM的两种工作状态。自动刷新,用于正常工作的状态;自我刷新,主要用于休眠模式低功耗状态下的数据保存。
5.外部中断控制寄存器(EXTINTN):24个 外部中断源 可用各种信号来请求。外部中断寄存器为外部中断请求设置了信号 触发方法 ,包括:低电平触发、高电平触发、上升沿触发、下降沿触发和双边沿触发。8个外部中断引脚有一个 数字滤波器(见EINTFLTn),16个引脚EINT[15:0]用作唤醒源。
6.掉电模式 和 I/O口:所有的 GPIO寄存器 的值在掉电模式下 被保存。这在时钟功率管理模块中的掉电模式下提到。EINTMSK 不能禁止从掉电模式唤醒,但是如果 EINTMSK 屏蔽了 EINT[15:4]中的对应位,系统可以被唤醒,但是SRCPND 中的 EINT4_7位 和 EINT8_23位 不会 在唤醒后被 置1。
7.杂项控制寄存器(MISCCR):在休眠方式,数据总线(D[31:0] 或D[15:0])能被设成高阻和0输出。但是,由于I/O引脚的特点,数据总线上拉电阻必须被断开或关闭减少耗电量。D[31:0]引脚上拉电阻可通过MISCCR 寄存器控制。
8.DCLK控制寄存器(DCLKCON):DCLKCON 定义 DCLKn信号,其作为外部源的时钟。寄存器 DCLKCON 仅在CLKOUT[1:0]位 设置为发送 DCLKn信号时 可以操作,具体信息如下:
9.外部中断控制寄存器(EXTINTn):24个外部中断 可以有不同的信号方式请求。EXTINTn 为外部中断请求,配置信号的方式为:电平触发 或者 边沿触发,也可以配置信号极性。为了能检测出电平触发中断,不受噪声滤波器的影响,EXTINTn引脚的有效逻辑电平 至少 要维持 40ns。
10.外部中断屏蔽寄存器(EINTMASK):针对 20个 外部中断(EINT[23:4])的中断屏蔽寄存器(即EINTMASK)。
11.外部中断挂起寄存器(EINTPENDn):外部中断挂起寄存器 EINTPENDn是针对 20个 外部中断(EINT[23:4])的,可以通过向此 EINTPEND 寄存器相应位 写1来清除比特位:
12.简单描述 S3C2440 的 PWM 模块的自动加载模式和双缓冲模式的主要作用。
(1)自动加载模式:自动加载模式使能时,当 TCNTn 的值到 0 时,自动加载操作复 制 TCNTBn 的值到 TCNTn 中。但是如果自动加载模式没有使能, TCNTn 将不进行任何操作。
(2)双缓冲模式:脉宽调制定时器有一个双缓冲功能 ,在这种情况下,改变下次加载值的同时不影响当前定时周期。因此,尽管设置一个新的定时器值,当前定时器的操作将会继续完成而不受影响。
13.假如 CPU 响应 TIMER1 中断进入中断服务程序,为了避免该中断请求信号再次引起中断响应,需要把 SRCPND 和 INTPND 寄存器中相关标志位清除。
汇编程序代码如下:
LDR R1,=0X4A000000 ;读取源挂起寄存器(SRCPND)的地址 LDR R2,[R1] ORR R2,R2,#0x800 ;R2第11位写1清零 STR R2,[R1] LDR R1,=0X4A000010 ;读取中断挂起寄存器(INTPND)的地址 LDR R2,[R1] ORR R2,R2,#0x800 ;R2第11位写1清零 STR R2,[R1] |
C语言程序代码如下:
#define SRCPND (*(volatile unsigned int *)0x4A000000) //定义SRCPND寄存器的地址 #define INTPND (*(volatile unsigned int *)0x4A000010) //定义INTPND寄存器的地址 #define BIT_TIMER1 (1 << 11) // 定义TIMER1中断标志位 void clearTimer1Interrupt() { SRCPND = BIT_TIMER1; // 清除TIMER1中断请求标志位 INTPND = INTPND; // 清除TIMER1中断挂起标志位 } |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。