uboot第一阶段
uboot的第一阶段主要是由汇编语言写的,主要做的内容就是系统硬件的初始化以及重定位代码。
1.关看门狗和中断
可参考:https://www.jianshu.com/p/5fff3439e811
什么是看门狗
在嵌入式系统中,不可避免的会碰到系统运行时出错的问题,有时候为了使系统能够自动的进行复位,就引入了看门狗的概念,实际上它就是一个计数器,到了一定的值后就会复位cpu,在程序中我们需要在计数器增加到这个值之前对这个计数器做一个复位清零的工作,俗称喂狗,使程序继续运行
Uboot下为什么要关闭看门狗
1.uboot下跑的是单一进程,主要做的是一些硬件的的初始化相关的工作,所以程序基本不会跑偏(系统运行出错),所以基本不会需要看门狗来照顾的情况,因此,一般做法就是关闭看门狗,避免喂狗的麻烦。
2.如果实在不想关闭看门狗其实也可以,但是需要不断的喂狗,避免系统重启
如何关闭看门狗(CPU内部的看门狗)
#define pWTCON 0x53000000 disable_watchdog: ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] mov pc, lr
关闭中断
当系统初始化还未完成之际,开启中断也没什么作用,因为我们并没有中断处理程序,因此我们需要关闭中断,防止中断影响系统初始化
中断的关闭时通过向中断使能清零寄存器写1来完成的
2.设置时钟
参考:
https://blog.csdn.net/u011916318/article/details/42713729
https://blog.csdn.net/mr_raptor/article/details/6555734
总体来说,系统时钟是整个电路的心脏。而与s3c2440处理器有关的时钟主要有4种:Fin、FCLK、HCLK和PCLK
S3C2440开发板在没有开启时钟前,整个开发板全靠一个12MHz的晶振提供频率来运行,也就是说CPU,内存,UART等需要用到时钟频率的硬件都工作12MHz下,而S3C2440A可以正常工作在400MHz下,两者速度相差可想而知,就好比牛车和动车。如果CPU工作在12MHz频率下,开发板的使用效率非常低,所有依赖系统时钟工作的硬件,其工作效率也很低,比如,我们电脑里面经常提到的超频,超频就是让CPU工作在更高的频率下,让电脑运算速度更快,虽然频率是越高越好,但是由于硬件特性决定了任何一个设备都不可能无止境的超频,电脑超频时要考虑到CPU或主板发热过大,烧坏的危险,同样开发板的主板上的外设和CPU也有一个频率限度,ARM920T内核的S3C2440的最高正常工作频率如下:
| Fin :12MHz(外部晶振的输入频率)
l FCLK:400MHz(主要用于CPU核心)
l HCLK:100MHz(主要用在与AHB总线互连的设备上(存储器控制器、lcd控制器、dma))
l PCLK:50MHz(主要用在与APB总线互连的低速设备上(uart adc 定时器))
既然如此,那么怎样让CPU工作在400MHz,让牛车速度提高到动车的速度呢?
1.系统工作时钟频率
系统时钟在提速之前,先了解Fin、FCLK、HCLK、PCLK这4个是什么东西?
Fin : 外部晶振的时钟频率
FCLK: 主要用于CPU核心ARM920T的工作时钟
HCLK: 主要用于与AHB总线互联的设备上(存储控制器、LCD控制器、DMA)
PCLK: 主要用于与APB总线互联的设备上(uart、adc、定时器)
废话一下:
AHB: advanced high-performance bus 简称高速总线,一般用于连接对时钟速率有较高要求的设备,如存储设备(nand/nor flash, ddr),LCD,CAMERA,DMA。。。
APH:advanced peripherals bus 简称外设(部)总线,一般用于连接外围对时钟速率要求较低的设备,如UART,serial,IIS,IIC。。。
已知的,S3C2440只有12Mhz外部晶振这么一个时钟源,那FCLK、HCLK、PCLK的时钟是哪里来的呢?猜猜看,哪里来的呢?
没错,FCLK、HCLK、PCLK的时钟是由Fin(晶振时钟)经过锁相环(PLL)倍频过来的。锁相环相当于一个时钟变换电路,低频晶振输入即可得到处理器所需的高频时钟输出。
其中,MPLLCON和CLKDIVN是两个控制寄存器,分别用于配置倍频系数和分频系数。
MPLLCON控制FCLK和Fin的比例关系
CLKDIVN控制FCLK、HCLK、PCLK之间的比例关系
此外S3C2440内部还有一个用于为USB设备提供时钟的锁相环UPLL。
S3c2440系统时钟初始化流程如下:
(1) 系统刚上电几毫秒后,FCLK等于外部晶振的振荡频率,即FCLK=Fin
(2) 当复位信号nReset恢复高电平后,锁相环MPLL按照寄存器MPLLCON设定的倍频比例开始生成所需要的时钟频率。从锁相环开始工作到输出新的稳定的频率值需要一定的时间(Lock time 即锁相环的捕获时间),这是因为MPLL输出频率还没有稳定,在这期间FCLK都停止输出,CPU停止工作,经过这段时间后,锁相环输出新的频率值FCLK,然后通过CLKDIVN寄存器设定FCLK、HCLK和PCLK三者的频率比例产生不同总线上所需的不同频率,下面详细介绍开启MPLL的过程:
l 设置LockTime变频锁定时间
l 设置FCLK与晶振输入频率(Fin)的倍数
l 设置FCLK,HCLK,PCLK三者之间的比例
LockTime变频锁定时间由LOCKTIME寄存器(见下表)来设置,由于变频后开发板所有依赖时钟工作的硬件都需要一小段调整时间,该时间计数通过设置LOCKTIME寄存器[31:16]来设置UPLL(USB时钟锁相环)调整时间,通过设置LOCKTIME寄存器 [15:0]设置MPLL调整时间,这两个调整时间数值一般用其默认值即可。
FCLK与Fin的倍数通过MPLLCON寄存器设置,三者之前有以下关系:
MPLL(FCLK) = (2*m*Fin)/(p*2^s)
其中:m = MDIV + 8, p = PDIV + 2, s = SDIV
当设置完MPLL之后,就会自动进入LockTime变频锁定期间,LockTime之后,MPLL输出稳定时钟频率。
通过上述算法比较难以找到合适的PLL值,下表给出了官方推荐的一些MPLL参考设置:
FCLK,HCLK,PCLK三者之间的比例通过CLKDIVN寄存器进行设置,S3C2440时钟设置时,还要额外设置CAMDIVN寄存器,如下表,HCLK4_HALF,HCLK3_HALF分别与CAMDIVN[9:8]对应,下表列出了各种时钟比例:
默认情况下HDIV=0,CPU总线为同步模式,即FCLK=HCLK(synchronous bus mod)。若HDIV设为非0,CPU的总线模式要进行改变,FCLK与HCLK不在相等,那么就需将CPU改为asynchronous bus mod(异步总线模式),可通过下面的汇编代码实现:
__asm{ mrc p15, 0, r1, c1, c0, 0 /* 读取CP15 C1寄存器 */ orr r1, r1, #0xc0000000 /* 设置CPU总线模式 */ mcr p15, 0, r1, c1, c0, 0 /* 写回CP15 C1寄存器 */ }
综上,设置S3C2440时钟:
ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] /* 分频设置:FCLK:HCLK:PCLK=1:2:4 */ mrc p15, 0, r1, c1, c0 orr r1, r1, #0xc0000000 mcr p15, 0, r1, c1, c0, 0 /* 设置为"asynchronous bus mod" */ ldr r0, =MPLLCON ldr r1, =S3C2440_MPLL_200MHZ str r1, [r0] /* 设置时钟频率FCLK */