1、硬件向量表
2、代码如下
(1)、增加一个异常打印函数printException.c。
#include <uart.h>
void printException(unsigned int cpsr, char *str)
{
puts("Exception! cpsr = ");
printHex(cpsr);
puts(" ");
puts(str);
puts("\n\r");
}
(2)、在makefile添加它。
objs = start.o uart.o sdram.o main.o exception.o
(3)、修改start.S
_start:
b reset /* vector 0 : reset */
b do_und /* vector 4 : und */
do_und:
/* 执行到这里之前:
* 1. lr_und保存有被中断模式中的下一条即将执行的指令的地址
* 2. SPSR_und保存有被中断模式的CPSR
* 3. CPSR中的M4-M0被设置为11011, 进入到und模式
* 4. 跳到0x4的地方执行程序
*/
/* 因为cpu一上电是在管理模式下运行,sp_und未设置, 先设置它 */
ldr sp, =0x34000000
/* 在und异常处理函数中有可能会修改r0-r12, 所以先保存 */
/* lr是异常处理完后的返回地址, 也要保存 */
stmdb sp!, {r0-r12, lr}
/* 保存现场 */
/* 处理und异常 */
mrs r0, cpsr
ldr r1, =und_string
bl printException
/* 恢复现场 */
ldmia sp!, {r0-r12, pc}^ /* ^会把spsr的值恢复到cpsr里 */
und_string: /* 定义一个字符串带\n */
.string "undefined instruction exception"
reset:
在调用main函数前调用如下代码
bl uart0_init
bl print1
/* 故意加入一条未定义指令 */
und_code:
.word 0xdeadc0de /* 未定义指令 */
bl print2
(4)、在uart.c添加打印调试的代码进去
void print1(void)
{
puts("abc\n\r");
}
void print2(void)
{
puts("123\n\r");
}
3、程序优化
(1)、防止程序超过4K,所以让他跳转到SDRAM中执行
ldr pc, und_addr /* vector 4 : und */
und_addr:
.word do_und
ldr pc, =sdram
sdram:
bl uart0_init
bl print1
/* 故意加入一条未定义指令 */
und_code:
.word 0xdeadc0de /* 未定义指令 */
bl print2
4、程序的启动执行流程