嵌入式linux学习笔记--20200222--JZ2440V3 S3C2440 时钟树分析以及修改时钟的代码

今天要学习一下S3C2440 的时钟体系

这个是整体的时钟框图 其中的USB 和camera 的时钟是一个单独的分频器分频出来的  只是给这两个外设用  我们暂且不去讨论。

主要的时钟就是  F_CLK 、HCLK、 PCLK、这三个时钟。

其中 FCLK 只是提供给CPU(ARM920T 核心) 用  也就是我们常说的CPU的主频

HCLK () 主要是提供给 AHB(Advanced High performance Bus) 总线上的设备使用的时钟,这一部分类似于电脑中的内存频率 虽然速度不如CPU快 但是也是属于仅次于CPU的主频了(比如我们电脑 DDR4 一般是2400 M  2666 M   大约2.6GHz) 在S3C2440 中允许 内核工作在异步模式下,就像是  电脑的主频可以高于内存的主频一样, ARM920T的 内核频率也可以高于外部的AHB总线。 HCLK 是提供给 内存控制器、 USB nandflash控制器等等的速度相对较快的设备

PCLK  是速度最慢的时钟,大多都是连接在一些低速的外设 P是peripheral   在时钟树图中我们可以看到这部分是连接单  WDT  PWM  I2S  I2C  GPIO 等等的 低速设备上。

上图中的黄色时钟代表的就是说  当CPU 工作于同步模式下的时候 CPU 时钟和 AHB总线共用 HCLK

大致的时钟分配就是这样。  为了提高整个系统的性能我们大多会让ARM920T的arm核工作在异步模式下,也就是CPU 频率远高于 内存频率的这样一种情况下。这种情况对应于四个基本模式(normal 、IDLE、 SLOW、SLEEP)的normal 模式

这是四种模式的介绍

这两个锁相环 我们暂且不讨论 USB 用到的哪一个

这里提到了 一上电在正式的向 MPLLCON寄存器写入有效值之前,整个系统的时钟都是来自于 外部时钟,未经处理!

我们的时钟是第一种来源  无源晶振 12MHZ

配置比例选择的是 50MHz:200MHz:400MHz

时钟部分 可以配置的寄存器 及其作用

这个寄存器控制着锁死的时间 这段时间是 定时器的 PLL参数修改之后等待的周期数,默认就是最大,可以充分确保 频率稳定下来

最后程序是这样的  程序来自韦东山老师的视频


.text
.global _start

_start:

	/* 关闭看门狗 */
	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
	 */
	
	

	/* 设置内存: 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 main

halt:
	b halt
	

最后总结就是  我的水平还是不到, 能看懂为什么这么设置,但是你要是让我自己写程序却是不知道要 按照怎样的顺序去设置。

发布了35 篇原创文章 · 获赞 30 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41534481/article/details/104439586
今日推荐