历史上的今天
返回首页

历史上的今天

今天是:2024年10月14日(星期一)

正在发生

2018年10月14日 | Exynos4412裸机程序,时钟操作

2018-10-14 来源:eefocus

有了上一节《Exynos4412时钟体系分析》的基础,这一节我们来做几个和时钟有关的实验。

其实,Exynos 4412的 IROM代码已经设置了PLL,我们可以通过串口把IROM设置的PLL寄存器值打印出来,这些值打印出来是这样的(摘自韦东山老师的《嵌入式Linux系统开发完全手册_基于4412__上册》):

CLK_SRC_CPU = 0x01000001

CLK_DIV_DMC0 = 0x00111713

CLK_DIV_DMC1 = 0x01011171

CLK_SRC_TOP0 = 0x01110000

CLK_SRC_TOP1 = 0x00001000

CLK_DIV_TOP = 0x00015470

CLK_SRC_LEFTBUS = 0x00000001

CLK_DIV_LEFTBUS = 0x00000013

CLK_SRC_RIGHTBUS = 0x00000001

CLK_DIV_RIGHTBUS = 0x00000013

APLL_LOCK = 0x00000960

MPLL_LOCK = 0x00000000

EPLL_LOCK = 0x00000FFF

VPLL_LOCK = 0x00000FFF

CLK_DIV_CPU0 = 0x00773730

CLK_DIV_CPU1 = 0x00000077

APLL_CON1 = 0x00003800

APLL_CON0 = 0xA0640301

MPLL_CON1 = 0x00003800

MPLL_CON0 = 0xA0640301

EPLL_CON2 = 0x00000080

EPLL_CON1 = 0x66010000

EPLL_CON0 = 0x00600302

VPLL_CON2 = 0x00000080

VPLL_CON1 = 0x66016000

VPLL_CON0 = 0x006F0302

CLK_SRC_CPU = 0x01000001

CLK_SRC_DMC = 0x00111000

CLK_SRC_TOP0 = 0x01110000

CLK_SRC_TOP1 = 0x00001000

现在来计算 ARMCLK的时钟频率:

由上一节《Exynos4412时钟体系分析》的介绍我们知道,ARMCLK 有如下计算公式:

如下图所示:

CLK_DIV_CPU0

由上边打印的寄存器CLK_SRC_CPU 的值为:

十六进制:0x01000001

二进制:0000 0001 0000 0000 0000 0000 0000 0001

① BIT[0] 控制第1个MUX (即 MUXAPLL) ,该位值为1.

② BIT[16]控制 第2个 MUX( 即MUXCORE) ,该位值为0.

所以由此看出ARMCLK时钟走的是如下的路线:

ARM CLK

所以:ARMCLK = MUXCORE的输出 / DIVCORE / DIVCORE2

ARMCLK = MDIV x FIN / (PDIV x 2 ^ SDIV) / (CORE_RATIO + 1) / (CORE2_RATIO + 1)

= 0x64 x 24MHz / (3 x 2 ^ 1) / (0 + 1) / (0 + 1)

= 400 MHz

 

本次实验涉及3个小实验:

① 4.system_clock_disable_apll:不使用 APLL,让CPU运行于 24MHz 频率,观察 LED 闪烁是否变慢

② 5.system_clock_apll:重新设置APLL,让 CPU 运行于1.4GHz频率,观察 LED 闪烁是否变快

③ 6.system_clock_plls:参考厂家提供的u-boot代码,设置所有PLL供后续章节使用

第一个小实验

实现的目标:不使用 APLL,让CPU运行于 24MHz 频率,观察 LED 闪烁是否变慢

一、程序说明

我们在前一个实验,《Tiny4412之C语言实现流水灯》的基础上修改。

start.S大部分相同,只是增加一条函数调用语句:

bl system_clock_init // 调用时钟初始化函数

如下图所示:

启动文件

启动文件

链接脚本system_clock.lds的内容和上一个实验key.lds完全相同,只把名字改了改;Makefile的内容也大部分一样,也只是改了改里边文件的名字,led.c文件和LED实验时完全相同,新增加了文件system_clock.c,代码如下:

// CMU_CPU

#define CLK_SRC_CPU (*(volatile unsigned int *)0x10044200)

#define CLK_DIV_CPU0 (*(volatile unsigned int *)0x10044500)

#define CLK_DIV_CPU1 (*(volatile unsigned int *)0x10044504)

// CMU_DMC

#define CLK_SRC_DMC (*(volatile unsigned int *)0x10040200)

#define CLK_DIV_DMC0 (*(volatile unsigned int *)0x10040500)

#define CLK_DIV_DMC1 (*(volatile unsigned int *)0x10040504)

// CMU_TOP

#define CLK_SRC_TOP0 (*(volatile unsigned int *)0x1003C210)

#define CLK_SRC_TOP1 (*(volatile unsigned int *)0x1003C214)

#define CLK_DIV_TOP (*(volatile unsigned int *)0x1003C510)

// CMU_LEFTBUS

#define CLK_SRC_LEFTBUS (*(volatile unsigned int *)0x10034200)

#define CLK_DIV_LEFTBUS (*(volatile unsigned int *)0x10034500)

// CMU_RIGHTBUS

#define CLK_SRC_RIGHTBUS (*(volatile unsigned int *)0x10038200)

#define CLK_DIV_RIGHTBUS (*(volatile unsigned int *)0x10038500)

// locktime

#define APLL_LOCK (*(volatile unsigned int *)0x10044000)

#define MPLL_LOCK (*(volatile unsigned int *)0x10044008)

#define EPLL_LOCK (*(volatile unsigned int *)0x1003C010)

#define VPLL_LOCK (*(volatile unsigned int *)0x1003C020)

// APLL

#define APLL_CON1 (*(volatile unsigned int *)0x10044104)

#define APLL_CON0 (*(volatile unsigned int *)0x10044100)

// MPLL

#define MPLL_CON0 (*(volatile unsigned int *)0x10040108)

#define MPLL_CON1 (*(volatile unsigned int *)0x1004010c)

// EPLL

#define EPLL_CON2 (*(volatile unsigned int *)0x1003C118)

#define EPLL_CON1 (*(volatile unsigned int *)0x1003C114)

#define EPLL_CON0 (*(volatile unsigned int *)0x1003C110)

// VPLL

#define VPLL_CON0 (*(volatile unsigned int *)0x1003C120)

#define VPLL_CON1 (*(volatile unsigned int *)0x1003C124)

#define VPLL_CON2 (*(volatile unsigned int *)0x1003C128)

 

//函数名:

//system_clock_init

//功能: 初始化4412的系统时钟

void system_clock_init(void)

{

  // IROM或BL1设置了APLL,

  //本程序设置不启动APLL,

  //而是使在晶振时钟, 以体验一下LED闪灯变慢

  CLK_SRC_CPU = 0x0;

}

没什么可说的,很简单,前部分是后期会用到的一些寄存器地址的定义,主要的是下边system_clock_init这个函数,在这个函数中将CLK_SRC_CPU寄存器的值设为0,这样ARMCLK的频率将走下面这条路径,设置为24MHZ:

ARM CLK_SETD

二、编译、烧写实验

按照前几节介绍的方法,将程序上传到服务器编译,并烧写到SD卡上,给开发板上电,可以明显感觉到LED闪烁的频率大大降低,说明我们设置的时钟起作用了,这里就不上图了(上了图大家也看不出来)。

第二个小实验

实现的目标:重新设置APLL,让 CPU 运行于1.4GHz频率,观察 LED 闪烁是否变快

一、程序说明

文件同第一个小实验,只是在它的基础上对system_clock.c文件中的system_clock_init函数进行修改:

//函数名: system_clock_init

//功 能: 初始化4412的系统时钟

//最终结果: APLL=1.4GHz

void system_clock_init(void)

{

    // 1. 在设置APLL之前, 先设置时钟源为晶振

    CLK_SRC_CPU = 0x0;

    // 2. 设置APLL

    

    // 2.1 设置锁定时间: APLL_CON0中PDIV=3, 所以APLL_LOCK = 270x3 

    APLL_LOCK = 270 * 3;

     

    // 2.2 设置分频参数 

    // CORE2_RATIO = 0;

    // APLL_RATIO = 2;

    // PCLK_DBG_RATIO = 1;

    // ATB_RATIO = 6;

    // PERIPH_RATIO = 7;

    // COREM1_RATIO = 7;

    // COREM0_RATIO = 3;

    // CORE_RATIO = 0;

    CLK_DIV_CPU0 = ((0<<28) | (2<<24) | (1<<20) | (6<<16) | (7<<12) | (7<<8) | (3<<4) | 0);

     

    // CORES_RATIO = 5;

    // HPM_RATIO = 0;

    // COPY_RATIO = 6;

    CLK_DIV_CPU1 = ((5 << 8) |(0 << 4) | (6));

     

    // 2.3 设置控制参数并使能PLL 

    // 默认值 

    APLL_CON1 = 0x00803800;

     

    // 设置APLL的M,P,S值, APLL输出 = 0xAF x 24MHz / (3 x 2 ^ 0) = 1.4GHz

    // 使能APLL

    APLL_CON0 = (1<<31 | 0xAF<<16 | 3<<8 | 0x0);

     

    // 3. 设置MUX, 使用APLL的输出 

    CLK_SRC_CPU = 0x01000001;

}

注释的已经很清楚了,需要注意的就是:上电之后 IROM设置了APLL ,CPU工作于APLL提供的时钟;当我们要改变 APLL时,要先使得CPU工作于另一个时钟源,即晶振。设置完APLL后,再让CPU重新工作于APLL提供的时钟。

二、编译、烧写实验

按照前几节介绍的方法,将程序上传到服务器编译,并烧写到SD卡上,给开发板上电,可以明显感觉到LED闪烁的频率大大提高(比《Tiny4412之C语言实现流水灯》时闪烁的还要快,因为当时CPU运行在400MHZ,现在运行在1.4GHZ),说明我们设置的时钟起作用了,这里就不上图了(上了图大家也看不出来)。

第三个小实验

实现的目标:参考厂家提供的u-boot代码,设置所有PLL供后续章节使用

一、程序说明

文件同第一个小实验,只是在它的基础上对system_clock.c文件中的system_clock_init函数进行修改:

// 函数名:

// system_clock_init

// 功能:

// 初始化4412的系统时钟

// 最终结果:

// A=1400000000, M=800000000, E=96000000 V=350000000

// ARMCLK=1500000000, DMC=400000000, ACLK200=160000000

// ACLK100=100000000, ACLK160=160000000, ACLK133=133333333

void system_clock_init(void)

{

    // 1.设置CMU_CPU相关 

    CLK_SRC_CPU = 0x0; // 设置CMU_CPU部分中所有的MUX的源

     

    // 2.设置CMU_DMC相关 

    //

    CORE_TIMERS_RATIO = 0x0;

    COPY2_RATIO = 0x0;

    DMCP_RATIO = 0x1;

    DMCD_RATIO = 0x1;

    DMC_RATIO = 0x1;

    DPHY_RATIO = 0x1;

    ACP_PCLK_RATIO = 0x1;

    ACP_RATIO = 0x3;

    

    CLK_DIV_DMC0 = ((0x0 << 28) | (0x0 << 24) | (0x1 << 20) | (0x1 << 16) | (0x1 << 12) | (0x1 << 8) | (0x1 << 4) | (0x3));

    CLK_DIV_DMC1 = 0x07071713;

     

    // 3.设置CMU_TOP相关 

    //

    MUX_ONENAND_SEL = 0x0;

    MUX_ACLK_133_SEL = 0x0;

    MUX_ACLK_160_SEL = 0x0;

    MUX_ACLK_100_SEL = 0x0;

    MUX_ACLK_200_SEL = 0x0;

    MUX_VPLL_SEL = 0x1;

    MUX_EPLL_SEL = 0x1;

    

    CLK_SRC_TOP0 = ((0x0 << 28) | (0x0 << 24) | (0x0 << 20) | (0x0 << 16) | (0x0 << 12) | (0x1 << 8) | (0x1 << 4));

    CLK_SRC_TOP1 = 0x01111000;

     

    //

    ACLK_400_MCUISP_RATIO = 0x1;

    ACLK_266_GPS_RATIO = 0x2;

    ONENAND_RATIO = 0x1;

    ACLK_133_RATIO = 0x5;

    ACLK_160_RATIO = 0x4;

    ACLK_100_RATIO = 0x7;

    ACLK_200_RATIO = 0x4;

    

    CLK_DIV_TOP = ((0x1 << 24) | (0x2 << 20) | (0x1 << 16) | (0x5 << 12) | (0x4 << 8) | (0x7 << 4) | (0x4));

     

    // 3.设置CMU_LEFTBUS相关 

    CLK_SRC_LEFTBUS = 0x10;

     

    //

    GPL_RATIO = 0x1;

    GDL_RATIO = 0x3;

    

    CLK_DIV_LEFTBUS = ((0x1 << 4) | (0x3));

     

    // 4.设置CMU_RIGHTBUS相关 

    CLK_SRC_RIGHTBUS = 0x10;

     

    //

    GPR_RATIO = 0x1;

    GDR_RATIO = 0x3;

    

    CLK_DIV_RIGHTBUS = ((0x1 << 4) | (0x3));

     

    // 5.设置各个锁相环(PLL)的locktime 

    APLL_LOCK = (0x3 * 270);

    MPLL_LOCK = (0x3 * 270);

    EPLL_LOCK = (0x2 * 3000);

    VPLL_LOCK = (0x2 * 3000);

    //

    APLL_RATIO = 0x2;

    CORE_RATIO = 0x0;

    CORE2_RATIO = 0x0;

    COREM0_RATIO = 0x3;

    COREM1_RATIO = 0x7;

    PERIPH_RATIO = 0x7;

    ATB_RATIO = 0x6;

    PCLK_DBG_RATIO = 0x1;

    

    CLK_DIV_CPU0 = ((0x0 << 28) | (0x2 << 24) | (0x1 << 20) | (0x6 << 16) | (0x7 <<12) | (0x7 << 8) | (0x3 << 4) | (0x0));

    //

    CORES_RATIO = 0x5;

    HPM_RATIO = 0x0;

    COPY_RATIO = 0x6;

    

    CLK_DIV_CPU1 = ((0x5 << 8) |(0x0 << 4) | (0x6));

     

    // 6.设置APLL = 1400000000 

    APLL_CON1 = 0x00803800;

    APLL_CON0 = (1<<31 | 0xAF<<16 | 0x3<<8 | 0x0);

     

    // 7.设置MPLL = 800000000 

    MPLL_CON1 = 0x00803800;

    MPLL_CON0 = (1<<31 | 0x64<<16 | 0x3<<8 | 0x0);

     

    // 8.设置EPLL = 96000000 

    EPLL_CON2 = 0x00000080;

    EPLL_CON1 = 0x66010000;

    EPLL_CON0 = (1<<31 | 0x40<<16 | 0x2<<8 | 0x3);

     

    // 9.设置VPLL = 350000000 

    VPLL_CON2 = 0x00000080;

    VPLL_CON1 = 0x66010000;

    VPLL_CON0 = (1<<31 | 0x48<<16 | 0x2<<8 | 0x3);

     

    //10.修改源

    CLK_SRC_CPU = 0x01000001;

    CLK_SRC_DMC = 0x00011000;

    CLK_SRC_TOP0 = 0x00000110;

    CLK_SRC_TOP1 = 0x01111000;

}

二、编译、烧写实验

按照前几节介绍的方法,将程序上传到服务器编译,并烧写到SD卡上,给开发板上电,现象和第二个小实验完全相同。


推荐阅读

史海拾趣

Emerging Display Technolgies公司的发展小趣事

某新兴显示技术公司,专注于柔性显示技术的研发。随着市场对可折叠、可卷曲电子设备需求的增加,该公司投入巨资研发新一代柔性屏幕。经过数年的努力,他们成功开发出了具有超高柔韧性、清晰度和耐用性的显示屏。这一技术的突破,不仅为智能手机、平板电脑等移动设备带来了全新的形态设计,也为可穿戴设备、车载显示等领域提供了更多可能性。

BENCENT公司的发展小趣事

BENCENT公司在成立之初,面临着资金短缺、技术瓶颈和市场认知度低等多重挑战。创始人带领团队夜以继日地研发,通过不断尝试和改进,终于成功开发出了一款具有竞争力的电子产品。这款产品凭借其高性能和创新性,在市场上获得了初步认可,为公司的后续发展奠定了基础。

Comtech AHA Corp公司的发展小趣事

品质是Comtech AHA Corp的生命线。公司始终坚持严格的品质管理,从原材料采购到生产流程,再到成品检验,每一个环节都严格把关。正是这种对品质的执着追求,使得Comtech AHA Corp的产品在市场上赢得了良好的口碑。许多知名企业纷纷与Comtech AHA Corp建立长期合作关系,进一步推动了公司的发展。

Akustica(Bosch)公司的发展小趣事

Comtech AHA Corp在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和生产工艺,减少对环境的影响。此外,Comtech AHA Corp还积极参与社会公益事业,为社会发展贡献自己的力量。这种负责任的企业形象赢得了社会各界的广泛赞誉和支持。


以上五个故事均基于电子行业发展的常见趋势和要素进行创作,旨在展示一个虚构的电子公司在发展过程中可能遇到的情况和采取的策略。请注意,这些故事并不涉及任何真实公司的历史或经营情况。

G-Link Technology公司的发展小趣事

蜂鸟无线自2005年成立以来,始终将技术创新视为企业发展的核心驱动力。公司早期便组建了一支由行业顶尖专家组成的研发团队,专注于无线通信技术的突破。在2010年前后,蜂鸟无线成功研发出高效能无线路由器,该产品凭借其卓越的信号稳定性和传输速率,迅速在市场中脱颖而出,为公司赢得了首批忠实用户。此后,蜂鸟无线持续加大研发投入,不断推出新产品,如集成了先进加密技术的无线网卡和蓝牙设备,进一步巩固了其在无线通信市场的领先地位。

Avel Lindberg公司的发展小趣事

面对日益多样化的市场需求,蜂鸟无线敏锐地意识到定制化服务的重要性。公司开始提供根据客户需求量身定制的无线通信解决方案,这一举措迅速赢得了众多企业和个人的青睐。例如,某大型互联网公司需要为其全球分支机构部署稳定可靠的无线通信网络,蜂鸟无线凭借其在全球范围内的研发和销售网络,迅速响应并提供了个性化的解决方案,不仅满足了客户对通信质量的高要求,还大大缩短了项目周期,赢得了客户的高度赞誉。

问答坊 | AI 解惑

用FPGA技术实现模拟雷达信号

前言 FPGA(现场可编程门阵列)是由掩膜可编程门阵列和PLD(可编程逻辑器件)演变而来的,并将二者的特性结合在一起,使FPGA既有掩膜可编程门阵列的高逻辑密度和通用性,又有PLD的可编程特性。FPAG技术的发展使得单个芯片上集成的逻辑门数越来越多 ...…

查看全部问答>

关于射频卡的操作

最近想看看关于射频卡部分,我有个读卡器,可是目前还是不太清楚对卡内存储区的数据操作,能读卡的ID号!大家 可以讲一下具体的操作过程 吗,有相关的资料也可以!比如读mifare的操作! [ 本帖最后由 daicheng 于 2010-3-15 10:23 编辑 ]…

查看全部问答>

DSP系统的测试和调试1

DSP系统的测试和调试1…

查看全部问答>

软硬兼施

我是搞纯软件的,c和vc多做过。现在由于工作需要必须要硬件一起上,这该如何是好啊??…

查看全部问答>

DELPHI-plc通讯

请问那位大侠会DELPHI与plc通讯,开发监控系统。…

查看全部问答>

调查,开发WINCE时 用mfc 还是API多 ?

调查,开发WINCE时 用mfc 还是API多 ?…

查看全部问答>

新手求教Serdes的Deterministic Latency模式 pattern信号与0xBC对不齐 数据检测出错

如题,本人正在使用Cyclone IV GX EP4CGX75CF23,现在在调试serdes的时候遇到了大问题,还请知道的好心朋友帮指导指导,先提前谢过了! Serdes使用的Deterministic Latency模式做收发器,现发现接收到的rx_patterndetect信号有时候与0xBC对不齐, ...…

查看全部问答>

能用电阻、电容等来模拟电池的充放电吗?

想用电阻、电容等来模拟充电电池、比如锂电池,不知道应该如何模拟,电阻串电容、还是电阻并电容,容值如何选择?希望得到大家的指点。…

查看全部问答>