Linux裸机开发2——S3C2440时钟体系
声明:以下知识与图片全部来自韦东山裸机开发视频
一、芯片启动流程
1、复位芯片等待电源稳定后,进行复位
2、锁存器锁存OM[3:2](时钟选择器)的值,进入LOCK TIME, CPU停止运行
3、LOCK TIME结束后,PLL得到新的时钟,晶振起振 ,CPU在新的时钟下运行
二、时钟体系
1、MPLL为主时钟
2、FCLK通过MPLL得到后一方面供给CPU时钟,
另一方面通过HDIV分频给HCLK以及通过PDIV分频给PCLK
三、编程提高时钟
1、目标时钟的设置
FCLK = 400MHZ
HCLK = 100MHZ
PCLK = 50MHZ
1、设置LOCK TIME(用于锁存时间)
在此期间,CPU不工作,直到PLL输出稳定。
2、设置CLKDIVN:
使HCLK = FCLK/4
PCLK = FCLK/8
2、设置CPU工作于异步模式(协处理器相关,直接拷贝即可)
/* 设置CPU工作于异步模式 */
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
3、设置FCLK(MPLL):
由手册可得查表,
但FCLK = 400MHZ时,MDIV = 92,PDIV = 1,SDIV = 1
设置MPLLCON:
将MDIV ,PDIV ,SDIV 写入对应的寄存器位中(使用位操作)
一旦设置PLL,就会锁定lock time直到PLL输出稳定
然后CPU工作于新的频率FCLK
2、编写汇编开始文件
.text
.global _start
_start:
//关闭看门狗
mov r0, #0x53000000
mov r1, #0
str r1, [r0]
/* 先设置时钟 FCLK:HCLK:PCLK = 400:100:50 */
//先设置lock time
ldr r0, =0x4C000000
ldr r1, =0xFFFFFFFF
ldr r1, [r0]
//设置HCLK= FCLK/4 与PCLK = FCLK/8
ldr r1, =0x4C000014
ldr r0, =0x5
ldr r0, [r1]
//设置PLL之前先设置异步模式
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
//设置PLL
ldr r0, =0x4C000004
ldr r1, =(92<<12)|(1<<4)|(1<<0)
ldr r1, [r0]
//根据nand与nor的特性自动辨认nor启动与nand启动
//nor flash可读不可写
mov r1, #0x0 //r1 = 0
ldr r0, [r1] //将0地址的数值保存在r0中
str r1, [r1] //向0地址中写入0
ldr r2, [r1] //取出0地址的值
cmp r1, r2 //比较r1与r2的值,相等则为nand,否则为nor
ldr sp, = 4096+0x4000000
moveq sp, #4096 //r1 = r2,nand启动
streq r0, [r1] //恢复0地址原来的值
/*调用main函数*/
//传参,点亮灯一
mov r0, #0x01
//跳转到main
bl led_delay
/*调用延时函数*/
//将要传递的参数放入r0寄存器中
mov r0, #0x8000
//跳转的delay函数
bl delay
//传参,点亮灯二
mov r0, #0x02
//跳转到main
bl led_delay
/*死循环*/
halt:
b halt
3、编写C语言执行文件
//主函数
int led_delay(volatile int which)
{
//定义方向寄存器以及数据寄存器的地址
unsigned int *GPDCON = (unsigned int *)0x56000010;
unsigned int *GPDDAT = (unsigned int *)0x56000014;
//传入参数
if(which == 0x01){
*GPDCON = 0x400;
}else if(which == 0x02){
*GPDCON = 0x1000;
}
*GPDDAT = 0;
return 0;
}
//延时函数
void delay(volatile int times)
{
while (times --);
}