历史上的今天
返回首页

历史上的今天

今天是:2024年12月23日(星期一)

正在发生

2021年12月23日 | Tiny4412模式跳转

2021-12-23 来源:eefocus

Tiny4412模式跳转

  ARM体系的CPU有以下7种工作模式:

          1、用户模式(Usr):用于正常执行程序;

          2、快速中断模式(FIQ):用于高速数据传输;

          3、外部中断模式(IRQ):用于通常的中断处理;

          4、管理模式(svc):操作系统使用的保护模式;

          5、数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储以及存储保护;

          6、系统模式(sys):运行具有特权的操作系统任务;

          7、未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件;

  如下图:

 

要进行模式跳转,就需要要有异常事件在触发它进行模式跳转,在ARM中,异常有如下几种:

 

 

  (1)在异常向量表中,需要注意的是未定义指令(undefined),软中断(swi)是发生在译码阶段,其他五种都发生在执行阶段;ARM中的流水线分为:取值,译码,执行,仿存,回写这五步,当一条指令正在执行时,它的下一条指令正在译码,下下一条在取值,pc指向的是正在取值的那条指令,在模式跳转要回去的时候这点需要认真考虑;

  (2)通过上图我们可以看出要是发生undefined,它就会自动跳到0x0000004这个地址去执行,那如果我们在这个地址放一段代码,到时候就可以知道有没有发生异常,是不是跳到0x0000004这个;思想就是这样,但是现在有遇到一个新的问题,因为在这个三星公司将0x00000000—0x00010000为iROM,这个地址是只能读,不能改,因此我们就要需开启mmu,把0x00000004映射到其他空闲的地址上去:


下面是代码:


  1 int (*printf)(char *, ...) = 0xc3e114d8;

  2 void enable_mmu();

  3 void memcpy(unsigned long *dest, unsigned long *source, int len);

  4 void init_table(unsigned long *addr);

  5 unsigned long swi_init();

  6 

  7 int main()

  8 {

  9     unsigned long source = swi_init();

 10     printf("source is %xn", source);

 11 

 12     memcpy(0x60000004, source, 0x1000);    

 13     enable_mmu();

 14 

 15     __asm__ __volatile__ (

 16         ".word 0xffffffffn"

 17     );

 18 

 19     printf("welcom backn");    

 20 }

 21 

 22 unsigned long swi_init()

 23 {

 24     unsigned long addr;

 25     __asm__ __volatile__ (

 26         "ldr %0, =start n"

 27         : "=r" (addr)

 28     );

 29     

 30     return addr;    

 31 }

 32 

 33 void memcpy(unsigned long *dest, unsigned long *source, int len)

 34 {

 35     int i = 0;

 36     for(i = 0; i < len; i++) {

 37         dest[i] = source[i];

 38     }

 39 }

 40 

 41 void enable_mmu()

 42 {

 43     /*构建表*/

 44     unsigned long addr = 0x50000000;

 45     init_table(addr);

 46     /*打开mmu*/

 47     unsigned long mmu = 0;

 48     mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);

 49     __asm__ __volatile__ (

 50          "mov r0, #3n"

 51         "MCR p15, 0, r0, c3, c0, 0n"//设置为管理员

 52         "MCR p15, 0, %0, c2, c0, 0n"//设置表的地址

 53         "MCR p15, 0, %1, c1, c0, 0n"//开启mmu

 54         :    

 55         :    "r" (addr), "r" (mmu)

 56         :

 57     );

 58 

 59 }

 60 

 61 __asm__ (

 62     

 63     "start: n"

 64     "mov sp, #0x47000000n"

 65     "stmdb sp!, {r0-r12, lr}n"

 66 

 67     "ldr r3, datan"

 68     "ldr r0, =str_undn"

 69     "blx r3n"

 70     

 71     /*跳回去代码*/

 72     "mov sp, #0x47000000n"

 73     "ldmdb sp, {r0-r12, pc}^n"//

 74 

 75     "data:n"

 76     ".word 0xc3e114d8n"

 77 

 78     "str_und:n"

 79     ".asciz "this is undefined\n"n"

 80     ".align 2n"

 81 );

 82 

 83 void init_table(unsigned long *addr)

 84 {

 85     unsigned long va = 0;

 86     unsigned long phys = 0;

 87 

 88     //0x40000000-0x80000000 -> 0x40000000-0x80000000    

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

 90         phys = va;

 91         addr[va >> 20] = phys | 2;

 92     }

 93 

 94     //0x10000000-0x14000000 -> 0x10000000-0x140000000    

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

 96         phys = va;

 97         addr[va >> 20] = phys | 2;

 98     }

 99     //0x10000000-0x14000000 -> 0x10000000-0x140000000    

100     for(va = 0x0; va < 0x10000000; va += 0x100000) {

101         phys = va + 0x60000000;

102         addr[va >> 20] = phys | 2;

103     }

104             

105 }


在开发板运行结果如下:

  总结一下:当一个模式发生跳转是,需要三步:(1)将pc存到lr中,pc->lr;(2)将cpsr存到spsr,cpsr-spsr;(3)初始化sp;第一二步由系统硬件自动完成,第三部需要我们手动完成;

  模式跳回去的时候逆过过来就ok,初始化sp,将lr还给pc,spsr还给cpsr,注意需要同时一起还,73行

  上面代码还有一问题就是,要是几个异常一起发生怎么办,因为我们不能控制它每次执法生一个吧,cpu留给我们处理每个异常的只有4个字节,那么我们就需要进行二级跳转了,下面贴出二级跳转代码:

  1 int (*printf)(char *, ...) = 0xc3e114d8;

  2 void enable_mmu();

  3 void init_table(unsigned long *addr);

  4 void memcpy(unsigned char *dest, unsigned char *src, int len);

  5 extern unsigned long  vector_start;

  6 

  7 int main()

  8 {    

  9     memcpy(0x70000000, vector_start, 0x1000);    

 10     enable_mmu();

 11 

 12     __asm__ __volatile__(

 13         ".word 0x77777777n"    

 14         "mov r3, #3n"

 15         "ldr r0, [r3]n"

 16     );

 17     

 18     printf("welcom backn");

 19 

 20     return 0;

 21 }

 22 

 23 void memcpy(unsigned char *dest, unsigned char *src, int len)

 24 {

 25     int i = 0;

 26     for(i = 0; i < len; i++) {

 27         dest[i] = src[i];

 28     }

 29 }

 30 

 31 void enable_mmu()

 32 {

 33     //step 1: creat ttb

 34     unsigned long addr = 0x50000000;

 35     init_table(addr);

 36     //step 2: enable mmu

 37     unsigned long mmu = 0;

 38     mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);

 39     __asm__ __volatile__ (

 40         "mov r0, #3n"

 41         "MCR p15, 0, r0, c3, c0, 0n"//set manage

 42         "MCR p15, 0, %0, c2, c0, 0n"//set ttb

 43         "MCR p15, 0, %1, c1, c0, 0n"//enable mmu

 44         :    

 45         :    "r" (addr), "r" (mmu)

 46         :

 47     );

 48 

 49 }

 50 

 51 __asm__(

 52 

 53 "vector: n"

 54 "    b resetn"

 55 "    b undn"

 56 "    b swin"

 57 "    b pre_abtn"

 58 "    b data_abtn"

 59 "    .word 0x0n"

 60 "    b irqn"

 61 "    b fiqn"

 62 

 63 "reset:n"

 64 

 65 "und:n"

 66     /*模式跳转进来分三步:

 67      *(1)将pc存到lr,pc->lr

 68     *(2)将cpsr存到spsr

 69     *(3)初始化sp

 70     *前两部系统硬件帮我们完成,第三步需要我们手动配置*/

 71 "    mov sp, #0x47000000n"

 72 "    stmdb sp!, {r0-r12, lr}n"

 73 

 74 "    ldr r3, shown"

 75 "    ldr r0, =str_undn"

 76 "    blx r3n"

 77 

 78     /*回去的时候逆回去就ok*,^表示同时还回去*/

 79 "    mov sp, #0x47000000n"

 80 "    ldmdb sp, {r0-r12, pc}^    n"

 81 

 82 "swi:n"

 83 

 84 "    mov sp, #0x47000000n"

 85 "    stmdb sp!, {r0-r12, lr}n"

 86 

 87 "    ldr r3, shown"

 88 "    ldr r0, =str_swin"

 89 "    blx r3n"

 90 

 91 "    mov sp, #0x47000000n"

 92 "    ldmdb sp, {r0-r12, pc}^    n"

 93 "pre_abt:n"

 94 

 95 "data_abt:n"

 96 

 97 "    mov sp, #0x47000000n"

 98 "    sub lr, lr, #4n"//这句需要好好理解

推荐阅读

史海拾趣

EPT公司的发展小趣事

随着品牌影响力的不断提升,EPT开始积极拓展OEM/ODM业务。公司凭借先进的生产技术和严格的质量管理体系,成功与多家国内外知名企业建立了合作关系。通过为客户提供定制化的产品和服务,EPT不仅实现了业务的快速增长,还为其积累了丰富的行业经验。

BUSSMANN公司的发展小趣事

随着汽车工业的快速发展,对熔断器的需求也急剧增加。Bussmann五兄弟敏锐地抓住了这一市场机遇,开始专注于汽车熔断器的研发和生产。他们深入研究汽车电路的特点,不断优化熔断器的设计和性能,使其能够更好地适应汽车的工作环境。凭借这一创新,Bussmann的汽车熔断器迅速占领了市场,为公司的发展奠定了坚实的基础。

Applied Engineering Products (AEP)公司的发展小趣事

随着国内市场的饱和,AEP公司开始寻求海外市场的拓展。公司通过与国外知名企业建立合作关系,共同研发新产品,成功打开了国际市场的大门。同时,AEP公司还积极参加国际电子展会和技术交流会,与全球同行交流学习,不断提升自身技术水平。在国际合作的过程中,AEP公司的品牌影响力逐渐增强,成为了电子行业中备受瞩目的企业之一。

COILCRAFT公司的发展小趣事

随着电子行业的不断发展,COILCRAFT公司意识到技术创新是保持竞争力的关键。于是,公司加大了对研发团队的投入,不断推出新产品和新技术。其中,射频芯片电感器和功率磁性元件的推出,极大地满足了通信设备、网络设备等领域对高性能磁性元件的需求。此外,COILCRAFT还具备定制磁性元件的能力,能够根据客户的精确要求进行定制生产,这一服务赢得了众多客户的青睐。

Amveco Toroidal Power Products公司的发展小趣事

Amveco Toroidal Power Products公司成立于XXXX年,初始阶段主要专注于环形变压器的研发与生产。创始人凭借对环形变压器技术的深入了解和市场需求的敏锐洞察,带领团队克服了初创期的种种困难,成功开发出了具有高效能、低噪音特点的环形变压器产品,并赢得了客户的初步认可。随着市场口碑的逐渐积累,公司的业务规模开始稳步扩大。

台湾三礼(3L)公司的发展小趣事

近年来,随着环保意识的提升和绿色能源的普及,三礼公司也积极投身于绿色生产领域。2019年,公司在广西南宁开始建设新厂,预定投资3亿元人民币用于厂房及自动化设备的建设。新厂总建筑面积达70,000平方米,将成为公司目前所有生产基地中规模最大的一个。同时,公司还计划全面架设太阳能发电系统,目标是在未来三年内承担公司总需求电量的30%。这一举措不仅有助于降低公司的生产成本,还体现了公司对环保事业的积极贡献。

这五个故事只是三礼公司发展历程中的一部分缩影,但它们却生动地展现了公司在电子行业中的成长轨迹和不懈努力。从北美市场的拓展到中国内地生产能力的扩大,再到技术突破和新产品开发,三礼公司始终保持着敏锐的市场洞察力和强大的创新能力。同时,公司还积极投身于绿色生产领域,为推动电子行业的可持续发展做出了积极贡献。

问答坊 | AI 解惑

一种提高无线局域网传输效率的技术

摘要:随着信息技术的快速发展,无线网络技术的应用越来越广泛,但是无线网络传输的效率一直比较低。针对这 种情况提出了一种提高无线局域网传输效率的技术。先在原理上讨论了使用包融合技术在无线局域网中使用的可 行性,然后通过在NS2 下的模拟 ...…

查看全部问答>

小白跪问 现有ARM9开发板上的RS232口怎么改成RS485的?

我的老师那里有一块开发板,其中J6接口如下图所示: 标号    名称           功能                  说明 J6   &n ...…

查看全部问答>

新手求助

大家好,本人大二,学习了模电和单片机.这个学期想参加电子设计比赛,初赛题要做一个基于fpga的频率计。我已经基本上了解了fpga的含义,但还是有一些问题想请教: 1.fpga的开发板价位从几十到几万…我看很多都是为嵌入式系统做的.如果只是要做频率 ...…

查看全部问答>

汇编高手乱入 关于十进制指令

看指令表有关与十进制指令 DADD.B 将十进制的进位位和源操作数加至目的操作数 语法 DADD.B src, dst 操作 src + dst + C -> dst (十进制) 有点不理解,大侠,斑竹指点 例如: CLRC ;复位进位位 CLR R5 DADD.B #99, R5 那 ...…

查看全部问答>

求助

I/O模拟I2C,假设P2.1接SDA,那么发送过来的8位数据放在什么地方?是P2IN吗?若是的话,8位数据是同时放在P2IN里吗(最高位在P2.7,最低位在P2.0)?但是,用户手册上说“Each bit in each PxIN register reflects the value of the input signal at t ...…

查看全部问答>

三星的eMMC iNAND和DDR3 SDRAM跳楼价甩了

三星的eMMC iNAND(型号KLM2G1DEHE)大概还有50片左右,DDR3 SDRAM(型号K4B2G0846C)大概30片的样子都是BGA封装,冰点吐血价5元每片,照例上图 淘宝小店:http://shop34118588.taobao.com/…

查看全部问答>

CCS5.2中C程序单步过程调用汇编子程序时,反汇编一片空白

点SUSPEND后,可以看到反汇编,也可以继续单步。这是怎么回事?…

查看全部问答>

数字基带编码软件

自己写的数字基带编码软件 征集网友验证程序的正确性, 跟帖给出验证的例子与结果…

查看全部问答>