历史上的今天
返回首页

历史上的今天

今天是:2025年02月06日(星期四)

正在发生

2020年02月06日 | ARM4412中SWI中断

2020-02-06 来源:eefocus

在ARM中的流水线分为:取值,译码,执行,仿存,回写。这五步详细如下:

而主要发生异常情况主要集中在译码以及执行阶段。此次的SWI(软中断)和上次的UND中断都出现在译码阶段,而其他5种中断都发生在执行阶段。


在异常向量表中可以看见对应异常的模式以及SWI异常的描述如图,详细参考ARM架构手册第54以及58页

如下代码,当发生SWI中断异常

1

2

3

4

5

6

7

8

9

10

11

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

 3

 4 int main()

 5 {

 6     __asm__ __volatile__(

 7         "swi #88n"

 8     );

 9

10     printf("welcome backn");

11 }

12

此时,对应地异常向量表。ARM就会到0x00000008这个地址去取指令来处理软异常,和处理UND异常一样,实现跳转模式,处理异常(在这里,我们打印“hello swi”).然后再跳转回来。我们把这处理的指令存到SOURCE地址中,由MEMCOPY函数拷贝到0X60000008地址。然后触发异常,最后打印一句话,如果能打印“welcome back”则代表测试成功。


 1 

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

  3 

  4 void init_ttb(unsigned long *addr);

  5 void enable_mmu(void);

  6 unsigned long swi_init();

  7 void memcopy(unsigned long* dest,unsigned long* source,int len);

  8 

  9 int main()

 10 {

 11     //发生异常时会进入异常模式跳转到0000 0004地址处理异常事件   

 12     unsigned long source_addr=swi_init();

 13     //异常事件处理函数

 14     printf("swi_souce addr is %xn",source_addr);

 15     //将异常处理地址的值放到0x60000004

 16     memcopy(0x60000008,source_addr,0x100);

 17 

 18     enable_mmu();

 19     //内存映射将0x00000004映射到0x6000000004    

 20     __asm__ __volatile__(

 21         "swi #88n"

 22      );

 23     printf("welcome back! n");

 24 

 25 

 26 }

 27 

 28 void memcopy(unsigned long* dest,unsigned long* source,int len)

 29 {

 30     int i=0;;

 31     for(i=0;i 32         dest[i]=source[i];

 33 }

 34 

 35 unsigned long  swi_init()

 36 {

 37     unsigned long source;

 38     __asm__ __volatile__(

 39          "ldr %0, =swi_startn"

 40          : "=r" (source)

 41      );

 42 

 43 

 44     return source;

 45 

 46 }

 47 __asm__(

 48      "swi_start:n"

 49 

 50 

 51     //跳转要分三部:

 52     //1:将PC保存到新模式下的lr中;

 53     //2:将CPSR保存在SPSR中

 54     //3:初始化SP

 55     //前两步由硬件完成,而第三部需要手动完成

 56      "mov sp, #0x66000000n"//初始化SP

 57      "stmfd sp!, {r0-r12, lr}n"//初始化sp,入栈保护寄存器 

 58 

 59     //打印一句话 

 60      "ldr r0, =stringn"

 61      "ldr r2, shown"

 62      "blx r2n"

 63 

 64     //跳回来分两部

 65     //1:将CPSR保存在SPSR中

 66     //2:将PC保存到新模式下的lr中;

 67      "mov sp, #0x66000000n"//

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

 69 

 70 

 71      "loop:n"

 72      "b loopn"

 73 

 74 

 75      "show:n"

 76      ".word 0xc3e114d8n"

 77 

 78      "string:n"

 79      ".asciz "hello SWI\n" n"

 80      ".align 2n"

 81         );

 82 

 83 void init_ttb(unsigned long *addr)

 84 {

 85     unsigned long va = 0;//定义虚拟地址

 86     unsigned long pa = 0;//定义物理地址

 87 

 88     //40000000-------80000000   ====  40000000------80000000

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

 90         pa = va;

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

 92         //|2的目的是将0-2位置为10此时将是小页模式4K

 93     }

 94 

 95     //00000000-------10000000   ====  60000000------70000000

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

 97         pa = va+0x60000000;

 98         addr[va >> 20] = pa | 2;

 99     }

100 

101     //10000000-------14000000   ====  10000000------14000000

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

103         pa = va;

104         addr[va >> 20] = pa | 2;

105     }

106 

107     //30000000-------40000000   ====  50000000------60000000

108     for(va=0x30000000; va<0x40000000; va+=0x100000){

109         pa = va + 0x20000000;

110         addr[va >> 20] = pa | 2;

111     }

112 }

113 

114 void enable_mmu(void)

115 

116 {

117     unsigned long addr = 0x70000000;

118     init_ttb(addr);

119     //step:初始化页表

120 

121     unsigned long mmu = 1 | (1 << 1) | (1 << 8);

122     //将MMU的第0,1,8位置1

123     __asm__ __volatile__(

124         "mov r0, #3n"

125         "MCR p15, 0, r0, c3, c0, 0n"//manager

126         "MCR p15, 0, %0, c2, c0, 0n"//addr  

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

128         :

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

130         : "r0"

131     );

132     printf("MMU is enable!n");

133 }


vim Makefile:

  1 

  2 all:

  3     arm-none-linux-gnueabi-gcc -c mmu.c -o mmu.o

  4     arm-none-linux-gnueabi-ld -Ttext=0x41000000 mmu.o  -o mmu 

  5     arm-none-linux-gnueabi-objcopy  -Ielf32-littlearm -Obinary  mmu mmu.bin

  6 


make

在minicom中dnw 41000000,

在终端中下载dnw 到板子,go 41000000

可以思考一下:怎么将SWI立即数打印出来?

推荐阅读

史海拾趣

Cypress(赛普拉斯)公司的发展小趣事

Cypress在USB技术领域取得了显著的成就。自1996年开始深耕USB产品以来,Cypress逐渐成为了USB领域内的领先者。公司推出的EZ-PD系列产品是业界第一个支持USB PD 3.0供电规范的解决方案,赢得了市场的广泛认可。此外,Cypress还不断推出新的USB产品和技术,推动了USB技术的不断发展和创新。

Electech Electronics公司的发展小趣事

Electech Electronics公司成立于XXXX年,由几位在电子行业有丰富经验的工程师共同创立。起初,公司主要专注于电子元器件的代理和销售,为本地的小型电子产品制造商提供服务。通过不懈的努力和对市场敏锐的洞察力,Electech Electronics逐渐在本地市场中建立了良好的声誉。

Entegris公司的发展小趣事

在晶圆盒传输业务上,Entegris与台湾的家登精密之间发生了一场长达数年的专利侵权诉讼。Entegris最终获得了胜诉,家登被要求赔偿超过3,000万美元。这一胜利不仅保护了Entegris的知识产权,也进一步巩固了其在半导体材料市场的地位。

Easy Magnet Corp公司的发展小趣事

随着市场需求的不断变化,Easy Magnet Corp公司意识到,只有不断创新才能保持竞争优势。因此,公司加大了研发投入,不断推出具有创新性的产品。其中,一款集成了微型化、高性能和高稳定性的磁性传感器,因其独特的优势,在智能手机、平板电脑等电子产品中得到了广泛应用。这一技术突破不仅提升了公司的知名度,也为公司带来了可观的收益。

BOT公司的发展小趣事

广西来宾电厂是中国第一个国家正式批准的BOT试点项目。该项目由法国电力国际和通用电气阿尔斯通公司作为项目公司的主要股东,总投资为6.16亿美元。这个电厂的装机规模为72万千瓦,安装了两台36万千瓦的进口燃煤机组。在长达18年的特许经营期内,该项目为广西地区提供了稳定的电力供应,同时也为项目公司带来了可观的投资回报。随着时间的推移,该项目成为了BOT模式在中国成功应用的典范,为后来的类似项目提供了宝贵的经验。

Aeroflex公司的发展小趣事

广西来宾电厂是中国第一个国家正式批准的BOT试点项目。该项目由法国电力国际和通用电气阿尔斯通公司作为项目公司的主要股东,总投资为6.16亿美元。这个电厂的装机规模为72万千瓦,安装了两台36万千瓦的进口燃煤机组。在长达18年的特许经营期内,该项目为广西地区提供了稳定的电力供应,同时也为项目公司带来了可观的投资回报。随着时间的推移,该项目成为了BOT模式在中国成功应用的典范,为后来的类似项目提供了宝贵的经验。

问答坊 | AI 解惑

变频器结构和故障判断简介

变频器是把工频电源(50Hz或60Hz)变换成各种频率的交流电源,以实现电机的变速运行的设备。如图1所示,其中控制电路完成对主电路的控制,整流电路将交流电变换成直流电,直流中间电路对整流电路的输出进行平滑滤波,逆变电路将直流电再逆变成交流电 ...…

查看全部问答>

电子信息工程的大学四年之感悟

本帖最后由 paulhyde 于 2014-9-15 09:13 编辑 题记: 我平时懒于BBS的灌水,属于潜水一族,也看到很多人在毕业之际写一些心得 体会之类,我本不想写这些东东,自我感觉有点哗众取宠,但终究是写下了。文中 所述,仁者见仁,智者见智,同意或 ...…

查看全部问答>

XL2000步进电机完整版C程序(带正反转与加减速)

#include        //51芯片管脚定义头文件 #include          //内部包含延时函数 _nop_(); #define uchar unsigned char #define uint  unsigned int uchar code FFW[8]={0xf1,0x ...…

查看全部问答>

请问大家谁了解H3C?

大家好 我刚收到H3C的 低端以太网交换机产品管理部 的 offer 本人刚刚毕业 请问有了解这个公司的吗? 该部门怎么样?谢谢 …

查看全部问答>

求助!想选一个大一点的ram,采用什么方案呀!

需求,一次信号周期20ms内采200个点,多路信号,需要把采来的数据存到ram里,一个信号大概需要1m左右的空间,我是初学单片机,刚学完51,现在会用ad采数据,和能过通串口上传数据,但不知道怎么选大点的ram,想用eeprom了,但又感觉他不是太适合,所 ...…

查看全部问答>

WINCE 下怎么显示鼠标图标?

今天看到G3上可以设置轨迹球和鼠标的切换,用户可以选择鼠标箭头操作,想问下这是怎么实现的?…

查看全部问答>

问一个显示模块的问题

你好,一家公司出了道面试题,用的是三星的128S64AA1显示模块, 要求把输出给这模块的中文显示信号转化成英文显示信号。 我不太了解,比如这模块的中文字库是怎么调用的, 谁了解这方面的内容吗,能谈下吗,有这方面的资料吗…

查看全部问答>

wince 编程用哪种环境好

wince  编程用哪种环境好…

查看全部问答>

花了一万元的PCB高级讲座课件(高频电路布线技巧)

这是射频与数模混合类PCB设计教程课件,希望对做高频电路的人们有所帮助 里面主要包括: 射频PCB布局与数模混合类PCB布局      无线终端PCB常用HDI工艺介绍􀂾 信号完整性(SI)的基础概念􀂾 射频PCB与数模 ...…

查看全部问答>

[原创]STM32 HD7279A接口程序

不知道为什么.网上好多人都说STM32 驱动不了7279.而且搜索不到一个例程.其实.对照数据手册.写好时序.这个接口是很容易的…

查看全部问答>