历史上的今天
返回首页

历史上的今天

今天是:2024年12月16日(星期一)

正在发生

2021年12月16日 | TINY4412裸机程序,时钟操作

2021-12-16 来源:eefocus

其实,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_SRC_CPU 的值为:


十六进制:0x01000001


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


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

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

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

所以: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个小实验:


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

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

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:

二、编译、烧写实验


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


推荐阅读

史海拾趣

D+H Mechatronic AG公司的发展小趣事

在全球环保意识日益增强的背景下,D+H Mechatronic AG积极响应绿色制造的号召。公司投入大量资金和资源研发出了一系列节能环保的机械设备,这些设备在生产过程中能够显著降低能耗和排放。同时,公司还积极参与各种环保活动,倡导绿色生产理念。这些举措不仅使公司赢得了客户的信赖和支持,也为其在行业内树立了良好的环保形象。

Alpha 3 Manufacturing公司的发展小趣事

随着市场的不断变化和客户需求的日益多样化,Alpha 3 Manufacturing公司意识到只有不断创新才能在竞争中立于不败之地。因此,公司加大了对技术研发的投入,引进了一批高端技术人才,建立了完善的研发体系。经过不断的努力,公司成功推出了一系列具有自主知识产权的高性能电子产品,赢得了客户的广泛赞誉。

Furukawa Electric Co Ltd公司的发展小趣事

随着市场的不断变化和客户需求的日益多样化,Alpha 3 Manufacturing公司意识到只有不断创新才能在竞争中立于不败之地。因此,公司加大了对技术研发的投入,引进了一批高端技术人才,建立了完善的研发体系。经过不断的努力,公司成功推出了一系列具有自主知识产权的高性能电子产品,赢得了客户的广泛赞誉。

Digital View公司的发展小趣事

随着数字化技术的不断进步和应用领域的不断扩大,Digital View公司也加快了数字化转型和升级的步伐。公司加大了对云计算、大数据、人工智能等前沿技术的研发和应用力度,推出了一系列智能化、数字化的产品和服务。这些产品和服务不仅提高了客户的运营效率和管理水平,还为公司带来了新的增长点。

酷宅(Coolkit)公司的发展小趣事

酷宅科技始终将技术创新作为公司发展的核心驱动力。公司不断投入研发资源,推动物联网、云计算、大数据等前沿技术的研发和应用。通过技术创新,酷宅科技不仅提高了产品的智能化水平,还降低了生产成本,提高了生产效率。同时,公司还积极与高校、科研机构等合作,共同开展技术攻关和人才培养工作,为公司的长期发展提供坚实的技术支持。

BEKA Associates Ltd公司的发展小趣事

在快速发展的过程中,BCD Semi(Diodes)积极寻求风险投资和资本运作的支持。公司通过吸引国内外知名的投资机构参与投资,获得了大量的资金支持,为公司的研发、生产和市场拓展提供了有力的保障。同时,BCD Semi还通过并购、合作等方式,与行业内的其他企业实现资源共享和优势互补,进一步提升了公司的综合实力。

问答坊 | AI 解惑

集团短信:短信实名

短信实名是在短信内容中已注册的,能够联接短信号码或其它短信内容的,任何语言的字词符。  应用举例说明,\"中联软通\"是已注册的实名,如果你想询问中联软通公司地址而又不知道公司的联系方式,你可以利用手机发送短信查询。  如:你用手机编 ...…

查看全部问答>

485 现场总线施工的实际问题和解决办法(1)

一、关于485总线的几个概念: 1、485总线的通讯距离可以达到1200米。 根据485总线结构理论,在理想环境的前提下,485总线传输距离可以达到1200米。其条件是通讯线材优质达标,波特率为9600,只负载一台485设备,才能使得通讯距离达 ...…

查看全部问答>

全国一等奖候选队复测名单

本帖最后由 paulhyde 于 2014-9-15 09:20 编辑 http://www.nuedc.com.cn/news.asp?bid=5&sid=20  …

查看全部问答>

verilog 3*3 按键扫描

https://bbs.eeworld.com.cn/viewthread.php?tid=82614&page=3&extra=page%3D1#pid299699 26楼…

查看全部问答>

通过这种方式汲取5V电源 可行吗

本信息来自合作QQ群:电子工程师技术交流(12425841) 群主在坛子ID:Kata 通过这种方式汲取5V电源 可行吗…

查看全部问答>

用USB虚拟网卡下载系统镜像的过程中传输中断。

在target connectivity options中可以获得 设备名。 开始下载镜像的时候是正常的,传输速率在260K左右。但下载到15.3M的时候下载就停止了,接着下载中断,提示检查网络。 这个时候网络确实出了问题,本地连接已经无法操作,右键没有反应了。ipcon ...…

查看全部问答>

嵌入式开发板——飞凌6410性能及配置详解

嵌入式开发板——飞凌6410性能及配置详解 S3C6410开发板产品备注:     S3C6410是一款低功耗、高性价比的RSIC处理器,可广泛应用于移动电话和通用处理等领域;     S3C6410为2.5G和3G通信服务提供了优化的硬件性能,内置 ...…

查看全部问答>

一个嵌入式初学者引发的思考(jesse谈自己的经验体会)

我目前再跟几个朋友合伙一起做点开源的硬件小产品,随后就成立了一个论坛,也就是现在的armjishu.com,那时候我们在一起商量着怎么让我们的广大初学者能够更快的进入到嵌入式领域,我们琢磨了很长时间,怎么样做到,后来决定做一款嵌入式硬件产品出 ...…

查看全部问答>

如何实现CE设备在PC上识别为U盘?

通过看资料: http://blog.eeworld.net/nanjianhui/archive/2009/08/20/4466741.aspx 我的BSPP中USB 驱动中有         1、USB\\FUNCTION         2、USB\\HCD\\OHCD   & ...…

查看全部问答>

做过“博创杯”嵌入式设计大赛的大虾,指教下~~~

    小弟第一次做这个比赛,还不是太懂     据说,这个比赛是自己编程序,然后下载到开发平台的芯片上运行,如果开发工具用IAR EWARM     那各种接口的驱动程序,要不要自己写?     自己写的代码是不 ...…

查看全部问答>