五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用

a&b :相同为1则为1,否则为0
a|b :有1则为1,否则为0
a^b : 有1则为1,否则为0
常用位运算:与、或、非、移位
位与(&) 位或(|) 位非(取反 ~) 移位(左移<< 右移>>)
使用位运算实现功能
1<<3 等于 0b1000,即bit3为1
1<<5 等于 0b100000,即bit5为1
(1<<3)|(1<<5) 等于 0b101000
扩展一下:如何只熄灭中间1颗而点亮旁边2颗
ldr r0, =((0<<3) | (1<<4) | (0<<5))

汇编写代码启动代码之关看门狗
一.什么是看门狗?(以下部分截取自博客园网友,ID:你不要你,侵权删。
  看门狗就好像你家门口的一条狗,我们必须在规定的时间内去喂狗,如果经过了规定的时间,你还不去喂狗的话,它就会咬死你。
  看门狗本质上是一个定时器,首先,你给看门狗设置好一段时间,然后看门狗就开始计时,CPU必须在这段时间过去之前重置看门狗内的时间,好让他重新计时,如果cpu不去重置看门狗内的时间的话,看门狗就会重启整个系统或者产生一个中断,当我们系统正常运行的时候,我们当然不希望重启系统啦,所以,我们就要喂狗(重置它里面的值)。
(2)看门狗的作用:监督,维护好系统,看系统是否正常运转。
  在一些比较恶劣的环境的情况下,当我们的系统坏的时候,我们没有办法人工重启的时候,看门狗就可以帮助我们重启系统。因为,系统坏了,CPU就不会去喂狗,不喂狗,看门狗到了那个时间后,就会触发重启,系统就自动重启了。
(3)为什么要关看门狗?
  因为现在我们人工用着这机器,当然不需要看门狗了,因为,系统崩溃了,我们会自己重启它,所以,我们现在需要关闭看门狗的功能。
(4)看门狗相关的寄存器
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
WTCON:看门狗主要功能的设置,如开/关看门狗(bit5),使能中断,使能重启,设置时钟分频多少等等。
WTDAT:看门狗重载的计数值
WTCNT:看门狗当前的计数值,看门狗计时时的当前值。
WTCLRINT:清中断,写1进去就清除中断

二.汇编写启动代码之设置栈和调用c语言
在ARM中,ATPCS(ARM关于程序应该怎么实现的一个规范)要求使用满减栈,所以不出意外都是用满减栈
结合iROM_application_note中的memory map,可知SVC栈应该设置为0xd0037D80
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
二.汇编程序和C程序互相调用
在start.o中调用c程序:
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
在添加一个led.C文件
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
编译工程:
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
编译报错(实际上是连接阶段报错):undefined reference to `__aeabi_unwind_cpp_pr1'
解决:在编译时添加-nostdlib这个编译选项即可解决。nostdlib就是不使用标准函数库。标准函数库就是编译器中自带的函数库,用-nostdlib可以让编译器链接器优先选择我程序内自己写的函数库。
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
使用DNW工具下载led.bin文件到开发板,即完成了汇编程序和C程序互相调用

三.汇编写启动代码之开iCache
1.什么是cache,有什么用
cache是一种内存,叫高速缓存。
从容量来说:CPU < 寄存器 < cache < DDR
从速度来说:CPU > 寄存器 > cache > DDR
cache的存在,是因为寄存器和ddr之间速度差异太大,ddr的速度远不能满足寄存器的需要(不能满足cpu的需要,所以没有cache会拉低整个系统的整体速度)
整个系统中CPU的供应链由:寄存器+cache+DDR+硬盘/flash四阶组成,这是综合考虑了性能、成本后得到的妥协的结果。
210内部有32KB icache和32kb dcache。icache是用来缓存指令的;dcache是用来缓存数据的。
cache的意义:指令平时是放在硬盘/flash中的,运行时读取到DDR中,再从DDR中读给寄存器,再由寄存器送给cpu。但是DDR的速度和寄存器(代表的就是CPU)相差太大,如果CPU运行完一句再去DDR读取下一句,那么CPU的速度完全就被DDR给拖慢了。解决方案就是icache。
icache工作时,会把我们CPU正在运行的指令的旁边几句指令事先给读取到icache中(CPU设计有一个基本原理:代码执行时,下一句执行当前一句代码旁边代码的可能性要大很多)。当下一句CPU要指令时,cache首先检查自己事先准备的缓存指令中有没这句,如果有就直接拿给CPU,如果没有则需要从DDR中重新去读取拿给CPU,并同时做一系列的动作:清缓存、重新缓存。
2.iROM中BL0对cache的操作
首先,icache的一切动作都是自动的,不需人为干预。我们所需要做的就是打开/关闭icache。
其次,在210的iROM中BL0已经打开了icache。所以之前看到的现象都是icache打开时的现象。
3.汇编代码读写cp15以开关icache
mrc p15,0,r0,c1,c0,0; // 读出cp15的c1到r0中
bic r0, r0, #(1<<12) // bit12 置0 关icache
orr r0, r0, #(1<<12) // bit12 置1 开icache
mcr p15,0,r0,c1,c0,0;
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
五.ARM裸机学习之汇编写启动代码之关看门狗,开iCache,汇编程序和C程序互相调用
4.实验验证
我们来看三种情况下的实验现象:
1 直接使用BL0中对icache的操作
2 关icache
3 开icache
实验结果分析:
结论1:irom中确实是打开了icache的。
结论2:icache关闭确实比icache打开时led闪烁变慢,说明指令执行速度变慢。