有了上一節(jié)《Exynos4412時(shí)鐘體系分析》的基礎(chǔ),這一節(jié)我們來(lái)做幾個(gè)和時(shí)鐘有關(guān)的實(shí)驗(yàn)。
其實(shí),Exynos 4412的 IROM代碼已經(jīng)設(shè)置了PLL,我們可以通過(guò)串口把IROM設(shè)置的PLL寄存器值打印出來(lái),這些值打印出來(lái)是這樣的(摘自韋東山老師的《嵌入式Linux系統(tǒng)開(kāi)發(fā)完全手冊(cè)_基于4412__上冊(cè)》):
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
現(xiàn)在來(lái)計(jì)算 ARMCLK的時(shí)鐘頻率:
由上一節(jié)《Exynos4412時(shí)鐘體系分析》的介紹我們知道,ARMCLK 有如下計(jì)算公式:
如下圖所示:
由上邊打印的寄存器CLK_SRC_CPU 的值為:
十六進(jìn)制:0x01000001
二進(jìn)制:0000 0001 0000 0000 0000 0000 0000 0001
① BIT[0] 控制第1個(gè)MUX (即 MUXAPLL) ,該位值為1.
② BIT[16]控制 第2個(gè) MUX( 即MUXCORE) ,該位值為0.
所以由此看出ARMCLK時(shí)鐘走的是如下的路線:
所以: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
本次實(shí)驗(yàn)涉及3個(gè)小實(shí)驗(yàn):
① 4.system_clock_disable_apll:不使用 APLL,讓CPU運(yùn)行于 24MHz 頻率,觀察 LED 閃爍是否變慢
② 5.system_clock_apll:重新設(shè)置APLL,讓 CPU 運(yùn)行于1.4GHz頻率,觀察 LED 閃爍是否變快
③ 6.system_clock_plls:參考廠家提供的u-boot代碼,設(shè)置所有PLL供后續(xù)章節(jié)使用
第一個(gè)小實(shí)驗(yàn)
實(shí)現(xiàn)的目標(biāo):不使用 APLL,讓CPU運(yùn)行于 24MHz 頻率,觀察 LED 閃爍是否變慢
一、程序說(shuō)明
我們?cè)谇耙粋€(gè)實(shí)驗(yàn),《Tiny4412之C語(yǔ)言實(shí)現(xiàn)流水燈》的基礎(chǔ)上修改。
start.S大部分相同,只是增加一條函數(shù)調(diào)用語(yǔ)句:
bl system_clock_init // 調(diào)用時(shí)鐘初始化函數(shù)
如下圖所示:
啟動(dòng)文件
鏈接腳本system_clock.lds的內(nèi)容和上一個(gè)實(shí)驗(yàn)key.lds完全相同,只把名字改了改;Makefile的內(nèi)容也大部分一樣,也只是改了改里邊文件的名字,led.c文件和LED實(shí)驗(yàn)時(shí)完全相同,新增加了文件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)
//函數(shù)名:
//system_clock_init
//功能: 初始化4412的系統(tǒng)時(shí)鐘
void system_clock_init(void)
{
// IROM或BL1設(shè)置了APLL,
//本程序設(shè)置不啟動(dòng)APLL,
//而是使在晶振時(shí)鐘, 以體驗(yàn)一下LED閃燈變慢
CLK_SRC_CPU = 0x0;
}
沒(méi)什么可說(shuō)的,很簡(jiǎn)單,前部分是后期會(huì)用到的一些寄存器地址的定義,主要的是下邊system_clock_init這個(gè)函數(shù),在這個(gè)函數(shù)中將CLK_SRC_CPU寄存器的值設(shè)為0,這樣ARMCLK的頻率將走下面這條路徑,設(shè)置為24MHZ:
二、編譯、燒寫實(shí)驗(yàn)
按照前幾節(jié)介紹的方法,將程序上傳到服務(wù)器編譯,并燒寫到SD卡上,給開(kāi)發(fā)板上電,可以明顯感覺(jué)到LED閃爍的頻率大大降低,說(shuō)明我們?cè)O(shè)置的時(shí)鐘起作用了,這里就不上圖了(上了圖大家也看不出來(lái))。
第二個(gè)小實(shí)驗(yàn)
實(shí)現(xiàn)的目標(biāo):重新設(shè)置APLL,讓 CPU 運(yùn)行于1.4GHz頻率,觀察 LED 閃爍是否變快
一、程序說(shuō)明
文件同第一個(gè)小實(shí)驗(yàn),只是在它的基礎(chǔ)上對(duì)system_clock.c文件中的system_clock_init函數(shù)進(jìn)行修改:
//函數(shù)名: system_clock_init
//功 能: 初始化4412的系統(tǒng)時(shí)鐘
//最終結(jié)果: APLL=1.4GHz
void system_clock_init(void)
{
// 1. 在設(shè)置APLL之前, 先設(shè)置時(shí)鐘源為晶振
CLK_SRC_CPU = 0x0;
// 2. 設(shè)置APLL
// 2.1 設(shè)置鎖定時(shí)間: APLL_CON0中PDIV=3, 所以APLL_LOCK = 270x3
APLL_LOCK = 270 * 3;
// 2.2 設(shè)置分頻參數(shù)
// 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 設(shè)置控制參數(shù)并使能PLL
// 默認(rèn)值
APLL_CON1 = 0x00803800;
// 設(shè)置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. 設(shè)置MUX, 使用APLL的輸出
CLK_SRC_CPU = 0x01000001;
}
注釋的已經(jīng)很清楚了,需要注意的就是:上電之后 IROM設(shè)置了APLL ,CPU工作于APLL提供的時(shí)鐘;當(dāng)我們要改變 APLL時(shí),要先使得CPU工作于另一個(gè)時(shí)鐘源,即晶振。設(shè)置完APLL后,再讓CPU重新工作于APLL提供的時(shí)鐘。
二、編譯、燒寫實(shí)驗(yàn)
按照前幾節(jié)介紹的方法,將程序上傳到服務(wù)器編譯,并燒寫到SD卡上,給開(kāi)發(fā)板上電,可以明顯感覺(jué)到LED閃爍的頻率大大提高(比《Tiny4412之C語(yǔ)言實(shí)現(xiàn)流水燈》時(shí)閃爍的還要快,因?yàn)楫?dāng)時(shí)CPU運(yùn)行在400MHZ,現(xiàn)在運(yùn)行在1.4GHZ),說(shuō)明我們?cè)O(shè)置的時(shí)鐘起作用了,這里就不上圖了(上了圖大家也看不出來(lái))。
第三個(gè)小實(shí)驗(yàn)
實(shí)現(xiàn)的目標(biāo):參考廠家提供的u-boot代碼,設(shè)置所有PLL供后續(xù)章節(jié)使用
一、程序說(shuō)明
文件同第一個(gè)小實(shí)驗(yàn),只是在它的基礎(chǔ)上對(duì)system_clock.c文件中的system_clock_init函數(shù)進(jìn)行修改:
// 函數(shù)名:
// system_clock_init
// 功能:
// 初始化4412的系統(tǒng)時(shí)鐘
// 最終結(jié)果:
// 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.設(shè)置CMU_CPU相關(guān)
CLK_SRC_CPU = 0x0; // 設(shè)置CMU_CPU部分中所有的MUX的源
// 2.設(shè)置CMU_DMC相關(guān)
//
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.設(shè)置CMU_TOP相關(guān)
//
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.設(shè)置CMU_LEFTBUS相關(guān)
CLK_SRC_LEFTBUS = 0x10;
//
GPL_RATIO = 0x1;
GDL_RATIO = 0x3;
CLK_DIV_LEFTBUS = ((0x1 << 4) | (0x3));
// 4.設(shè)置CMU_RIGHTBUS相關(guān)
CLK_SRC_RIGHTBUS = 0x10;
//
GPR_RATIO = 0x1;
GDR_RATIO = 0x3;
CLK_DIV_RIGHTBUS = ((0x1 << 4) | (0x3));
// 5.設(shè)置各個(gè)鎖相環(huán)(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.設(shè)置APLL = 1400000000
APLL_CON1 = 0x00803800;
APLL_CON0 = (1<<31 | 0xAF<<16 | 0x3<<8 | 0x0);
// 7.設(shè)置MPLL = 800000000
MPLL_CON1 = 0x00803800;
MPLL_CON0 = (1<<31 | 0x64<<16 | 0x3<<8 | 0x0);
// 8.設(shè)置EPLL = 96000000
EPLL_CON2 = 0x00000080;
EPLL_CON1 = 0x66010000;
EPLL_CON0 = (1<<31 | 0x40<<16 | 0x2<<8 | 0x3);
// 9.設(shè)置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;
}
二、編譯、燒寫實(shí)驗(yàn)
按照前幾節(jié)介紹的方法,將程序上傳到服務(wù)器編譯,并燒寫到SD卡上,給開(kāi)發(fā)板上電,現(xiàn)象和第二個(gè)小實(shí)驗(yàn)完全相同。
上一篇:Exynos4412裸機(jī)程序之操作ICache
下一篇:Exynos4412時(shí)鐘體系分析
推薦閱讀
史海拾趣
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦
- 神經(jīng)形態(tài)芯片可能是革新機(jī)器人實(shí)時(shí)電機(jī)控制的未來(lái)
- 從三個(gè)方面理解ARM嵌入式系統(tǒng)
- 自動(dòng)報(bào)警 基于MCU的家庭防盜報(bào)警系統(tǒng)的設(shè)計(jì)
- 存儲(chǔ)控制器及其訪問(wèn)外設(shè)的原理
- 基于51系列單片機(jī)的智能照明控制系統(tǒng)設(shè)計(jì)方案
- 基于STM32的四旋翼飛行器控制系統(tǒng)
- 單片機(jī)應(yīng)用編程技巧解析
- 基于89C52的教室智能節(jié)能照明系統(tǒng)設(shè)計(jì)
- 一種新型的雨量光照傳感器的設(shè)計(jì)
- 穩(wěn)壓器到底有哪些作用?如何選擇穩(wěn)壓器
- 穩(wěn)壓器有哪些使用規(guī)范?如何選擇穩(wěn)壓器的功率
- 穩(wěn)壓器如何安裝?4種必須掌握的穩(wěn)壓器接線方法
- 變壓器的保護(hù)有哪些?變壓器過(guò)負(fù)荷要求了解嗎
- 飽和變壓器有哪些特點(diǎn)?飽和/非飽和變壓器有什么區(qū)別
- 短路阻抗對(duì)變壓器有哪些影響?如何維護(hù)變壓器
- 如何進(jìn)行變壓器減容?短路阻抗和變壓器有什么關(guān)聯(lián)
- 如何測(cè)量變壓器各繞組電壓?變壓器減容是怎么回事
- 隔離變壓器的工作原理是什么?隔離變壓器如何選型
- 隔離變壓器對(duì)電源有影響嗎?隔離變壓器應(yīng)用方法介紹
- S3C2440 跳到 SDRAM 中執(zhí)行程序
- 存儲(chǔ)控制器與外設(shè)之間的關(guān)系
- S3c2440代碼重定位詳解
- s3c2440中斷程序(燒錄到NORFlash,運(yùn)行在SDRAM中)
- S3C2440 SDRAM寄存器初始化設(shè)置
- 華碩即將公布AMOLED屏幕手機(jī) 不過(guò)并不是ZenFone6
- 低配版R15?OPPO又一款新機(jī)確認(rèn)搭載聯(lián)發(fā)科P60
- 功率因數(shù)校正: PQvar?助力提高能效并確保負(fù)載平衡
- Vishay的業(yè)內(nèi)首款3通道和4通道透射式光傳感器已AEC-Q101認(rèn)證
- Silicon Labs完成對(duì)Sigma Designs 公司Z-Wave事業(yè)單位的收購(gòu)
- 歡迎加入:TI 2015年及以后畢業(yè)實(shí)習(xí)生招聘開(kāi)始啦!
- ST BlueCoin 開(kāi)發(fā)套件播放音頻
- 【NUCLEO-L073RZ】物聯(lián)網(wǎng)時(shí)代-開(kāi)發(fā)就是這么easy!
- 曬曬芯片
- RMII接口數(shù)據(jù)檢測(cè)問(wèn)題
- 采用高通CRS8635的一款藍(lán)牙耳機(jī) 功耗評(píng)測(cè) 數(shù)據(jù),分享供交流討論!
- RFID有效追蹤藥品和醫(yī)療管理
- TEC控制芯片ADN8834的疑問(wèn)
- 放大器的輸入、輸出電壓范圍與軌到軌的理解誤區(qū)
- msp430f5529簡(jiǎn)單uart源程序(用串口助手 發(fā)什么 回復(fù)什么)