Tiny4412异常处理

发布者:数字梦行最新更新时间:2018-10-14 来源: eefocus关键字:Tiny4412  异常处理 手机看文章 扫描二维码
随时随地手机看文章

#include "regs.h"

void enable_mmu(unsigned long ttb);

void init_ttb(unsigned long *ttb_base);

void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa);

void memset(char *buf, char ch, int size);

void memcpy(char *dst, char *src, int size);

void do_swi(unsigned long regs[]);

void (*printf)(char *, ...) = 0x43e11434;

void main(void)

{    

    unsigned long  vector_base = 0xffff0000;

    unsigned long  tt_base = 0x73000000;

    unsigned long *pdo_swi = 0x75000000;

    extern unsigned long vectors_start, vectors_end;

    memset(tt_base, 0x00, 16 * 1024);

    mmap(tt_base, vector_base, 0x70000000);    

    enable_mmu(tt_base);

    memcpy(vector_base, vectors_start, 0x100);

    *pdo_swi = do_swi;

    

    __asm__ __volatile__ (

        "mov r0, r0\n"            

        "swi 0x7777\n"

        "mov r1, r1\n"

    );

}

void do_swi(unsigned long regs[])

{

    unsigned long *instr = regs[13] - 4;

    printf("swi:  0x%x\n", *instr & 0xffffff);

}

void enable_mmu(unsigned long ttb)

{    

    unsigned long c1_flags;

    init_ttb(ttb);

    c1_flags = 1 | (1 << 3) | ( 1 << 11) | ( 1 << 13) |  (1 << 28);

    __asm__ __volatile__ (

        "mvn r0, #0 \n"            

        "mcr p15, 0, r0, c3, c0, 0\n"

        "mcr p15, 0, %1, c2, c0, 0\n" //configure ttb

        "mrc p15, 0, r0, c1, c0, 0\n"

        "orr %0, r0, %0\n"

        "mcr p15, 0, %0, c1, c0, 0\n" //enable mmu

        :

        : "r" (c1_flags), "r" (ttb)

        : "r0"

    );

}

void init_ttb(unsigned long *ttb_base)

{

    unsigned long va, pa;

    for (va = 0x00000000; va < 0x10000000; va += 0x100000) { //Others

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;    

    }

    for (va = 0x10000000; va < 0x14000000; va += 0x100000) { //SFR

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) |  2;    

    }

    for (va = 0x40000000; va < 0x80000000; va += 0x100000) { //DRAM

        pa = va;

        ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;    

    }

    

}

void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa)

{

    ttb_base[ va >> 20] = (pa & 0xfff00000) |  2;    

}

void memset(char *buf, char ch, int size)

{

    int i;

    for (i = 0; i < size; i ++)

        buf[i] = ch;

}

void memcpy(char *dst, char *src, int size)

{

    int i;

    for (i = 0; i < size; i ++) 

        dst[i] = src[i];    

}

__asm__ (

"vectors:\n"

    "b reset\n"

    "b und\n"

    "b swi\n"

    "b pre_abt\n"

    "b dat_abt\n"

    ".word 0\n"

    "b irq\n"

    "b fiq\n"

"reset:\n"

"und:\n"

    "mov sp, #0x74000000\n"

    "stmfd sp!, {r0-r12, lr}\n"

    "mov r0, sp\n"

    "mov r3, #0x74000000\n"

    "ldr r3, [r3]\n"

    "blx r3\n"

    "mov sp, #0x74000000\n"

    "ldmea sp, {r0-r12, pc}^\n"

"swi:\n"

    "stmfd sp!, {r0-r12, lr}\n"

    

    "mov r0, sp\n"

    "mov r3, #0x75000000\n"

    "ldr r3, [r3]\n"

    "blx r3\n"

    "ldmfd sp, {r0-r12, pc}^\n"

"pre_abt:\n"

"dat_abt:\n"

"fiq:\n"

"irq:\n"

    "mov sp, #0x75000000\n"

    "sub lr, lr, #4    \n"

    "stmfd sp!, {r0-r12, lr}\n"

    

    "mov r0, sp\n"

    "mov r3, #0x75000000\n"

    "ldr r3, [r3]\n"

    "blx r3\n"

    "mov sp, #0x75000000\n"

    "ldmea sp, {r0-r12, pc}^\n"

"EOV:\n"

"vectors_start:\n"

    ".word vectors\n"

"vectors_end:\n"

    ".word EOV\n"

);

===================================================================

Makefile文件:

default:

    arm-linux-gcc -c test.c  -o test.o

    arm-linux-ld  -Ttext=0x70003000  test.o  -o test

    arm-linux-objcopy  -O binary  test  test.bin

clean:

    rm -f test.o  test  test.bin   *~ 

===================================================================

烧写测试参考:“Tiny4412从SD卡启动u-boot用linux的DNW烧写裸板程序


说明:

    ①系统上电复位后CPU就处于管理模式(svc),执行0地址处的b reset跳转到reset:处继续运行,把相关硬件初始化以后会清掉cpsr后5位并把第四位置1,进入user mode设置栈后运行于用户态(usr),即处理器启动时首先进入管理员模式(svc),此后进入除用户模式之外的其他模式,主要完成各模式的堆栈设置,最后进入用户模式,运行用户程序;当发生swi软中断以后cpu进入svc模式。


    ②swi软中断主要用于usr模式(应用程序通常运行于usr模式)切换到svc模式下。在arm的7种模式当中(已经不止7种了)usr模式是唯一一个非特权模式,其他都是特权模式,比如fiq、und等都是特权模式,他们之间的切换直接更改cpsr寄存器的低5位的模式位或者真的发生fiq、und等异常的时候就可以达到切换的目的;而usr模式不是特权模式没有办法更改cpsr寄存器的低5位进行切换,想切换到特权模式只能调用swi指令,swi指令会帮助它进入到svc模式。

    ③如果原来是svc模式,发生未定义指令异常后进入und(Undefined)模式,这时候要重新设置sp栈指针;如果执行swi指令的时候已经处于svc模式,那么发生swi的软中断之后仍然还是svc模式,这个时候就不用再去设置sp栈指针了(在tiny4412异常实验中因为运行的uboot,已经处于svc模式,故要注意sp指针)。

    ④只有处理swi和und异常的时候lr指向下一条指令,其他的异常发生的时候lr都是指向下两条指令;ARM上的每条指令长度都是32位即4个字节;swi指令也是32位且其后面跟的value值占该指令的低24位,所以在程序里可以得到swi指令的value值,具体如下:

unsigned long *pdo_swi = 0x75000000;

*pdo_swi = do_swi;   //先把中断处理函数do_swi地址放在0x75000000

在发生swi异常的时候程序会自动跳到异常向量入口:"b swi\n"

接着跳转到swi处执行:

"swi:\n"

   "stmfd sp!, {r0-r12, lr}\n"

//保护现场,把usr模式下的相关寄存器入栈,

//存放顺序是先存放lr、r12....r0,最终sp指向r0的地址

"mov r0, sp\n"                   //把上一步中指向usr模式下r0地址的sp传给r0寄存器

"mov r3, #0x75000000\n" 

"ldr r3, [r3]\n"

"blx r3\n"                          //调用中断处理函数do_swi,参数放在r0中

//regs[0] == r0

//regs[1] == r1

//.....

//regs[12] == r12

//regs[13] == lr

void do_swi(unsigned long regs[]) //regs指向usr模式下r0地址

{

    //按照入栈顺序regs[13]为usr模式下lr值,即发生swi异常时下一条指令的地址

    //regs[13] - 4 = lr - 4 ; 即上一条指令的地址也就是swi异常的地址

    unsigned long *instr = regs[13] - 4;

    

    //根据ARM指令是32位的,swi指令也是32位且其后面跟的value值占该指令的低24位得到value值

    printf("swi:  0x%x\n", *instr & 0xffffff);

}


关键字:Tiny4412  异常处理 引用地址:Tiny4412异常处理

上一篇:Tiny4412的MMU映射代码示例
下一篇:Tiny4412的MMU解析

推荐阅读最新更新时间:2024-03-16 16:16

第五章、Tiny4412 U-BOOT移植五 Nand Flash原理
此篇是半写半抄来的。参考文章查看第一章说明。 Tiny4412中是没有焊接NandFlash的,取而代知的是eMMC芯片,所以这一节我也没有细细的去看,为了自己以后可能会修改这部分代码,我将网友“南山一梦”关于NandFlash基本原样的复制过来了。里面内容基本没有作太多修改。后面我会试着来分析eMMC如何操作。 一、芯片简介 虽然Tiny4412中没有焊接NandFlash,但PCB板上是有这部分电路的,原理图上所用的Flash芯片型号是:K9GAG08U0E 图5-1、Tiny4412 核心板图 查找三星芯片的命名手册,这个网上有PDF名称叫“三星_Nand_Flash_芯片型号命名规则.pdf”,查找K9GA
[单片机]
第五章、<font color='red'>Tiny4412</font> U-BOOT移植五 Nand Flash原理
Tiny4412中断控制器(GIC)之PWM
#include regs.h void enable_mmu(unsigned long ttb); void init_ttb(unsigned long *ttb_base); void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa); void memset(char *buf, char ch, int size); void memcpy(char *dst, char *src, int size); void do_irq(unsigned long regs ); void (*printf)(char *, ...) = 0x
[单片机]
ARM 处理器 ~ 中断与异常
中断与异常 定义 ARM 中的工作模式除 User 和 System 外,均为异常模式,这里的异常是广义的,包含以下三类情况 外部中断(外部中断) 由于 CPU 外部的原因而改变程序执行流程,属于异步事件,可以屏蔽 软件中断(自陷) 通过处理器拥有的软件指令,可预期地使正在执行的程序改变执行流程,以执行特定的程序 显式的事件,无条件执行 属同步事件,且不可屏蔽 例如 Motorola 68000 系列的 Trap 指令、ARM 中的 SWI、Intel 8086 中的 INT 异常 由 CPU 内部的原因(如非法指令)或外部的原因(如访存错误)引起的事件 没有对应的处理器指令 异常发生时,处理器无条件地挂起当前运行的程序,
[单片机]
ARM <font color='red'>处理</font>器 ~ 中断与<font color='red'>异常</font>
ARM的异常中断处理方案
异常就是正在执行的指令,由于各种软件或硬件故障被打断,比如,在读数据或指令时,访问存储器失败、产生了一个外部硬件中断等。当这些情况发生时,在ARM系统里,由异常和中断处理程序做出相应的处理,当处理完成后,要返回到被中止的指令,使被中止的指令能够继续正常执行下去。因此,确定异常和中断处理程序的返回地址是一个非常重要的问题。 下面是中断异常入口、返回指令、返回地址的一个表,ARM R14_x是发生中断时保存到R14的返回地址,pc指的是发生了中断的那条指令的地址。 异常或入口 返回指令 ARM R14_x BL MOV PC,R14 PC+4 SWI MOVS PC,R14_svc PC+4 未定义的指令 MOVS P
[单片机]
ARM中断异常处理的返回的问题
因为ARM指令是三级流水线就是说取指,译指,执行时同时执行的 ,这样说吧,现在PC指向的是正在取指的地址,那么cpu正在译指的指令地址是PC-4(假设在ARM状态下,一个指令占4个字节),cpu正在执行的指令地址是PC-8.也就是说PC所指向的地址和现在所执行的指令地址相差8,尽管以后版本的指令流水线扩展为5级和8级,但是这一特性一直被兼容处理,也即pc(excute)=pc(fetch) - 8,其中:pc(excute)是当前正在执行的指令,就是之前取该指令时候的PC的值;pc(execute):当前指令执行的,计算中如果用到pc,是指此时pc的值。当突然发生中断的时候,保存的是PC的地址。 (1)对于子程序的调用 如
[单片机]
ARM中断<font color='red'>异常</font><font color='red'>处理</font>的返回的问题
ARM寄存器分析以及异常处理方法
ARM 有7个基本工作模式 User : 非特权模式,大部分任务执行在这种模式 FIQ : 当一个高优先级(fast) 中断产生时将会进入这种模式 IRQ : 当一个低优先级(normal) 中断产生时将会进入这种模式 Supervisor :当复位或软中断指令执行时将会进入这种模式 Abort : 当存取异常时将会进入这种模式 Undef : 当执行未定义指令时会进入这种模式 System : 使用和User模式相同寄存器集的特权模式 注意:除User(用户模式)是Normal(普通模式)外,其他6种都是Privilege(特权模式)。 Privilege中除Sys模式外,其余5种为异常模式。 各种模式的切换,可以是程序员通过代
[单片机]
ARM寄存器分析以及<font color='red'>异常</font><font color='red'>处理</font>方法
tiny4412的中断资源连接关系示意图
在tiny4412的设备树中可以发现,中断资源是以树的形式呈现的,下面是我画的一张图,大致描述了tiny4412上中断资源的连接关系。 可以到 http://pan.baidu.com/s/1ge0sz6N 下载。 其中, 红色的表示的是root interrupt controller(中断资源的生产者),无色的表示的是由root interrupt controller引出的普通的interrupt controller(中断资源的消费者和生产者),绿色的表示的是片内外设和板级外设(中断资源的消费者)。
[单片机]
<font color='red'>tiny4412</font>的中断资源连接关系示意图
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved