控制器的设置与调试(协处理器指令开启ICache代码示例)
控制器的设置与调试(协处理器指令开启ICache代码示例)mrc mov r1 r0 结果是r0 =传给=> r1我们需要引入协处理器指令CP15管理cache mmu 我们启动cache需要操作CP15 协处理器指令 先看硬件结构CP15中也有许多寄存器 C0 ~ C15 启动C7’ 是备份寄存器现在主CPU中某一个值R0传给CP15中的某一个寄存器
来源:百问网_嵌入式Linux wiki_jz2440 新1期视频维基教程 (视频文字版)
作者:韦东山
本文字数:2403,阅读时长:2.5分钟
CPU中还有许多协处理器来协助主处理功能 比如2440有CP0 ~ CP15一共16个协处理器
CP15管理cache mmu 我们启动cache需要操作CP15 协处理器指令 先看硬件结构
CP15中也有许多寄存器 C0 ~ C15 启动C7’ 是备份寄存器
现在主CPU中某一个值R0传给CP15中的某一个寄存器
我们需要引入协处理器指令
mrc
mov r1 r0
结果是r0 =传给=> r1
mrc
c coprocessor =传给=> register
mcr 是把主处理器的值发给协处理器 register =传给=> coprocessor 查看一下语法格式 在2440中搜索mrc
得到语法格式
<MCR|MRC>{cond} p# <expression1> Rd cn cm{ <expression2>}
举个例子
mcr P15 0 r1 c1
把主处理器的值发给协处理器
expression1 值设置为0,表示用不到
r1 是主cpu寄存器里面的值
c1 是cp15寄存器里的值
cm 用不到,写为c0
expression2 值设置为0,表示用不到
cm和expression2用来区分哪一个c1,一般写为c0 0
这条命令表示主cpu中r1 值写入 协处理器cp15 中的c1寄存器
反过来要从cp15寄存器读到主cpu寄存器
mrc p15 0 r1 c1 c0 0
这条命令表示协处理器cp15 c1寄存器的值读出来写入主cpu的r1寄存器
2410手册中有讲cp15寄存器的作用
其中寄存器1控制寄存器 下图为介绍控制寄存器1的功能
bit12位是控制cache指令的开启或者关闭,我们等下把bit 12设置为1
c7里面有许多不同的寄存器,对应不同的功能
寄存器7表示用来操作cache,根据语法规则cm{ <expression2>} 来区分选择哪个c7
接下来写程序使能cache 注意2440里有data cache和指令cache 其中data cache要启用地址映射才可以使用,只能使用指令cache
打开start.s
reset:
/* 关闭看门狗 */
ldr r0 =0x53000000
ldr r1 =0
str r1 [r0]
/* 设置MPLL FCLK : HCLK : PCLK = 400m : 100m : 50m */
/* LOCKTIME(0x4C000000) = 0xFFFFFFFF */
ldr r0 =0x4C000000
ldr r1 =0xFFFFFFFF
str r1 [r0]
/* CLKDIVN(0x4C000014) = 0X5 tFCLK:tHCLK:tPCLK = 1:4:8 */
ldr r0 =0x4C000014
ldr r1 =0x5
str r1 [r0]
/* 设置CPU工作于异步模式 */
mrc p15 0 r0 c1 c0 0
orr r0 r0 #0xc0000000 //R1_nF:OR:R1_iA
mcr p15 0 r0 c1 c0 0
/* 设置MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0)
* m = MDIV 8 = 92 8=100
* p = PDIV 2 = 1 2 = 3
* s = SDIV = 1
* FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
*/
ldr r0 =0x4C000004
ldr r1 =(92<<12)|(1<<4)|(1<<0)
str r1 [r0]
/* 一旦设置PLL 就会锁定lock time直到PLL输出稳定
* 然后CPU工作于新的频率FCLK
*/
/*
使能icache
*/
bl enable_icache
/* 设置内存: sp 栈 */
/* 分辨是nor/nand启动
* 写0到0地址 再读出来
* 如果得到0 表示0地址上的内容被修改了 它对应ram 这就是nand启动
* 否则就是nor启动
*/
mov r1 #0
ldr r0 [r1] /* 读出原来的值备份 */
str r1 [r1] /* 0->[0] */
ldr r2 [r1] /* r2=[0] */
cmp r1 r2 /* r1==r2? 如果相等表示是NAND启动 */
ldr sp =0x40000000 4096 /* 先假设是nor启动 */
moveq sp #4096 /* nand启动 */
streq r0 [r1] /* 恢复原来的值 */
bl sdram_init
//bl sdram_init2 /* 用到有初始值的数组 不是位置无关码 */
/* 重定位text rodata data段整个程序 */
bl copy2sdram
/* 清除BSS段 */
bl clean_bss
/* 复位之后 cpu处于svc模式
* 现在 切换到usr模式
*/
mrs r0 cpsr /* 读出cpsr */
bic r0 r0 #0xf /* 修改M4-M0为0b10000 进入usr模式 */
bic r0 r0 #(1<<7) /* 清除I位 使能中断 */
msr cpsr r0
/* 设置 sp_usr */
ldr sp =0x33f00000
ldr pc =sdram
sdram:
bl uart0_init
bl print1
/* 故意加入一条未定义指令 */
und_code:
.word 0xdeadc0de /* 未定义指令 */
bl print2
swi 0x123 /* 执行此命令 触发SWI异常 进入0x8执行 */
//bl main /* 使用BL命令相对跳转 程序仍然在NOR/sram执行 */
ldr lr =halt
ldr pc =main /* 绝对跳转 跳到SDRAM */
halt:
b halt
如何使能icache 打开2410芯片手册
enable_icache:
/* 设置协处理器使能icache */
mrc p15 0 r0 c1 c0 0
orr r0 r0 #(1<<12) /* r0 = r0 or (1<<12) */
mcr p15 0 r0 c1 c0 0 //吧修改好的r0写给cp15的c1寄存器
mov pc lr
刷屏效率变快
「新品首发」STM32MP157开发板火爆预售!首批仅300套