一、背景
处理器的工作频率一直都在突飞猛进,但是存储器(包含内存、硬盘等)的工作频率却增长缓慢,其实也可以将程序、数据都存储在处理器内部的存储空间中,但是处理器内部的存储空间可谓寸土寸金,为了在价格和性能之间找到一个平衡,现代计算机一般采用多级存储层次。硬盘是最便宜的,所以可以使用大容量的硬盘,但是速度是最慢的;Cache一般是处理器内部的SRAM,成本最高,可以使用的容量有限,但是速度很快,一般可以在一个时钟周期完成访问;内存位于两者之间,速度上优于硬盘,但不如Cache,成本上优于Cache,但不如硬盘。
在主存和 CPU 通用寄存器之前设置了一类高速的、容量较小的存器,把正在执行的指令地址附件的一部分指令或数据从主存调入这类存储器,供 CPU 在一段时间内使用,这对提高程序的运行速度有很大的作用。这类介于主存和 CPU 之间的高速小容量存储器称作高速 cache(cpu > 寄存器 > icache > 内存 > 硬盘)。
常见的 cache 包括 icache 和 dcache。
系统刚上电时,icache中的内容是无效的,并且 icache 的功能是关闭的,往 CP15 协处理器中的寄存器 1 的 bit[12]写1 可以启动 icache,写 0 可以停止 icache。icache 关闭时,CPU 每次取指都要读主存,性能非常低。因为 icache 可随时启动,越早开 icache 越好。
与 icache 相似,系统刚上电时, dcache 中的内容是无效的,并且 dcache 的功能是关闭的,往CP15协处理器中的寄存器1的bit[2]写1可以启动dcache, 写0可以停止dcache。 因 为 dcache必须在启动 mmu 后才能被启动,而对于裸机而言,没必要开 mmu,所以本教程的程序将不会启动dcache。
如图cp15协处理器的寄存器中的c1寄存器为控制为,所以前面提到控制c1的bit[12]就可以开关icache
二、代码
1、star.S
/*
* 代码:开关icache
* 日期:2020.7.11
* 作者:glass love
*
*/
//要开icache就将 CONFIG_SYS_ICACHE写为1,关则写为0
#define CONFIG_SYS_ICACHE 0
.globl _start
_start:
/**********************关看门狗*******************************/
//通过查阅数据手册知道控制看门狗开关的寄存器是:
//Watchdog Timer Control Register (WTCON, R/W, Address =0xE2700000 )
//WTCON寄存器的bit[0]位是启用或禁用复位信号的看门狗定时器输出位
//1为启用,0为禁止
//因此只需要往WTCON中写入0x0即可
ldr r0, =0x00000000
ldr r1, =0xE2700000
str r0, [r1]
/**********************开icache*********************************/
//打开icache可以提高运行速度
//读出协处理器cp15的c1的值到r0中
mrc p15, 0, r0, c1, c0, 0
#if CONFIG_SYS_ICACHE
//将cp15协处理器的bit[12]置一(开icache)
orr r0, r0, #0x00001000
#else
//将cp15协处理器的bit[12]清零(关icache)
bic r0, r0, #0x00001000
#endif
//将r0中的值写入到cp15协处理器的c1中
mcr p15, 0, r0, c1, c0, 0
/***********************设置栈****************************/
//IROM 里的固定代码设置的 sp 就等于 0xD003_7D80,
//所以我们设置栈一般就指向0xD003_7D80,以调用c函数
ldr sp, =0xD0037D80
/*******************调用c函数点亮LED************************/
bl led_blink
b .
2、Makefile
led_c_icache.bin: start.o led.o
arm-linux-ld -Ttext 0x0 -o led_c_icache.elf $^
arm-linux-objcopy -O binary led_c_icache.elf led_c_icache.bin
arm-linux-objdump -D led_c_icache.elf > led_c_icache_elf.dis
gcc mkv210_image.c -o mk210
./mk210 led_c_icache.bin 210.bin
%.o : %.S
arm-linux-gcc -o $@ $< -c -nostdlib
%.o : %.c
arm-linux-gcc -o $@ $< -c -nostdlib
clear:
rm *.o *.elf *.bin *.dis mk210 -f
3、led.c
4、mkv210_image.c
5、write2sd
结论(实验现象):
通过控制icache的开关,可以明显看到LED灯闪烁速度的快慢发生了变化