arm linux 时钟源 信息,Linux学习——ARM芯片时钟体系

跟着视频学习了ARM芯片时钟体系,信息量有点大,做个笔记梳理梳理。

1.时钟体系的结构图

f114731edf079d8e00c30baebf2c8aa6.png

b7385d0cfa5739a83d2d5077ed917e29.png

38a38991edd0bc56cb2591cc15351240.png

有很多外设,一些工作在AHB总线,一些工作在APB总线

CPU工作在FCLK,AHB总线工作在HCLK,APB总线工作在PCLK

根据数据手册,我们可以知道FCLK、HCLK、PCLK的时钟频率,时钟源由12MHz的晶振经过锁相环PLL得到这些时钟频率

7d3157878e5ac5aeeaebcd2f6e6347f3.png

2.时钟示意图

77db4ec41dda4f75da8260d8b376aa6f.png

OM[3:2]是选择器,选择时钟源,根据数据手册,若为00,则两个时钟源(CPU用、USB用)都选择为晶振

8ba9ff7dc6f325efadd3cd387ae55506.png

MPLL(main PLL):给CPU时钟用的PLL,使用MPLLCON寄存器控制输出频率(见4)

UPLL(USB PLL):给USB时钟用的PLL,使用UPLLCON控制输出频率(见4)

由图可知,经过MPLL得到一个时钟,作为FCLK提供给CPU,FCLK经过HDIVN得到HCLK,经过PDIVN得到PCLK

HCLK提供给AHB总线,并由AHB总线提供给挂载在AHB总线上的其他各种高速设备作为时钟

PCLK提供给APB总线,并由APB总线提供给挂载在APB总线上的其他各种低速设备作为时钟

3.时钟选择过程

327bc93d369c71cb05089ac58b23346b.png

先来看下上电之后时钟的设置过程:

1.上电之后等待电源稳定,复位芯片输出高电平给S3C2440的复位引脚(对应nRESET那里的一小段低电平时间)

2.根据OM[3:2]的值(默认为00),FCLK = 晶振(12MHz),一上电FCLK就开始起振,但此时CPU还没开始运行(对应The logic ...)

3.PLL锁存OM[3:2]的值,此时CPU才开始运行(对应PLL can operate ...)

4.设置PLL(对应Lock Time),此时FCLK不起振,CPU停止工作

5.在Lock Time时,PLL工作

6.等待Lock Time结束,PLL输出稳定,FCLK = PLL输出的新时钟频率,CPU开始工作

4.设置寄存器

1)LOCKTIME数值寄存器:设置LOCK TIME的时间,一般使用默认值

88b3c9cf443619f52f37bf372d524931.png

2)PLL控制寄存器(附常用参考值)

508c27290007ec08f1e5b77bd43ec8ca.png

661e6dd932ec4f3f2ad347a00517c284.png6416f1a20ed1cacfb872dccd0f57aff2.png

计算公式以及参数表格

3)时钟分频控制寄存器:决定分频系数、HCLK、PCLK的时钟频率

a92df9f8d579d8f49e34edfed5dcea29.png

4)注意事项

a20fd7b7f3dec5c644365138446a1c2a.png

如果HDIV不为0,则必须设置CPU工作位异步模式,否则CPU会选择HCLK为时钟

写入#R1_nF:0xc0000000

5.代码实现CPU工作于FCLK = 400MHz

1)汇编代码

.text

.global _start

_start:

/* 关闭看门狗 */

ldr r0, =0x53000000

ldr r1, =0;

str r1, [r0]

/* 设置LOCALTIME */

ldr r0, =0x4c000000

ldr r1, =0xFFFFFFFF

str r1, [r0]

/* 设置分频系数HDIVN、PDIVN,使得FCLK:HCLK:PCLK = 400M:100M:50M */

ldr r0, =0x4c000014

ldr r1, =0x5

str r1, [r0]

/* 设置CPU工作于异步模式 */

mrc p15,0,r0,c1,c0,0

orr r0,r0,#0xc0000000

mcr p15,0,r0,c1,c0,0

/* 设置MPLLCON,使得FCLK=400MHz */

ldr r0, =0x4c000004

ldr r1, =( (92<<12)|(1<<4)|(1) ) // 根据公式得到以下数值

str r1, [r0]

/* 一旦设置PLL,就会锁定localtime,直到PLL输出稳定,CPU才会开始工作 */

/* 设置内存: sp 栈 */

/* 分辨是nor/nand启动

* 方法:写0至0地址,再读出

* 如果为0,则为nand启动(nand0地址对应片内RAM,可随意更改)

* 否则为nor启动(nor相当于硬盘,要更改需要先发数据格式)

*/

mov r1, #0

ldr r0, [r1] /* 读出原来的值备份 */

str r1, [r1] /* 将0写入0地址 */

ldr r2, [r1]

cmp r0, r2 /* r1==r2? 相等表示从NAND启动 */

ldr sp, =0x40000000+4096 /* 先假设nor启动 */

moveq sp,#4096 /* 若r1==r2,执行该语句,即从nand启动 */

streq r0, [r1]

/* 调用main */

bl main

halt:

b halt

2)C代码和之前一样

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值