日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【嵌入式开发】时钟初始化 ( 时钟相关概念 | 嵌入式时钟体系 | Lock Time | 分频参数设置 | CPU 异步模式设置 | APLL MPLL 时钟频率设置 )

發(fā)布時間:2025/6/17 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【嵌入式开发】时钟初始化 ( 时钟相关概念 | 嵌入式时钟体系 | Lock Time | 分频参数设置 | CPU 异步模式设置 | APLL MPLL 时钟频率设置 ) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一. 時鐘相關(guān)概念解析
    • 1. 相關(guān)概念術(shù)語
      • ( 1 ) 時鐘脈沖信號 ( 概念 : 電壓幅度 時間間隔 形成脈沖 | 作用 : 時序邏輯基礎(chǔ) 間隔固定 根據(jù)脈沖數(shù)量可計算出時間 )
      • ( 2 ) 時鐘脈沖頻率 ( 概念 : 單位時間內(nèi)產(chǎn)生的脈沖個數(shù) )
      • (3) 時鐘源 ( 產(chǎn)生來源 : ① 晶振 ② 鎖相環(huán) PLL | 晶振 : 晶體震蕩電路 | PLL 鎖相環(huán) : 晶振 + PLL 合成 | 晶振 與 PLL 對比 優(yōu)缺點 )
  • 二. 時鐘體系簡介
    • 1. 2440 開發(fā)板 時鐘體系
      • (1) 2440 開發(fā)板時鐘體系介紹 ( 12MHz 晶振 | 2 PLL : ① MPLL ② UPLL | MPLL -> ① FCLK [ ARM 核 ] ② HCLK [ AHB 總線 ] ③ PCLK [ APB 總線 ] | UPLL -> UCLK [ USB 總線 ] )
      • (2) 6410 開發(fā)板時鐘體系介紹 ( 12MHz 晶振頻率 | 3 PLL : ① APLL ② MPLL ③ EPLL | APLL -> ACLK [ ARM 核 ] | MPLL -> ① HCLK [ AHB 總線 ] ② PCLK [ APB 總線 ] | EPLL -> SCLK [ USB 總線 ] )
      • (3) S5PV210 開發(fā)板時鐘體系介紹 ( 24MHz 晶振頻率 | 4 PLL ① APLL ② MPLL ③ EPLL ④ VPLL )
  • 三. S3C6410 初始化時鐘
    • 1. S3C 6410 時鐘初始化流程簡介
      • (1) CPU 頻率變化過程 ( ① 上電后 12MHz | ② 配置 PLL | ③ 處于 Lock Time 頻率 0Hz | ④ 正常 PLL 頻率 )
      • (2) 時鐘初始化的四個步驟 ( ① 配置 Lock Time | ② 設(shè)置分頻系數(shù) | ③ 設(shè)置 APLL MPLL 頻率 | ④ 設(shè)置 CPU 工作模式 -> 異步工作模式 )
    • 2. S3C 6410 時鐘初始化 匯編代碼編寫
      • (1) 配置 Lock Time
      • (2) 設(shè)置分頻系數(shù)
      • (3) 設(shè)置 CPU 異步工作模式
      • (4) 設(shè)置 APLL 和 MPLL 時鐘頻率
      • (5) 設(shè)置 時鐘源
      • (6) 代碼示例
    • 3. 鏈接器腳本
    • 4. Makefile 編譯腳本
    • 5. 編譯輸出可執(zhí)行文件
    • 6. 燒寫代碼到開發(fā)板并執(zhí)行
      • ( 1 ) OK6410 開發(fā)板啟動切換方式
      • ( 2 ) 制作 SD 卡啟盤 并 準(zhǔn)備程序
      • ( 3 ) SecureCRT 連接開發(fā)板并燒寫程序
    • 7. 將程序燒寫到開發(fā)板上運行 ( 僅做參考 )


本博客的參考文章及相關(guān)資料下載 :

  • 1.本博客代碼及參考手冊下載 :https://download.csdn.net/download/han1202012/10606616


一. 時鐘相關(guān)概念解析



1. 相關(guān)概念術(shù)語


( 1 ) 時鐘脈沖信號 ( 概念 : 電壓幅度 時間間隔 形成脈沖 | 作用 : 時序邏輯基礎(chǔ) 間隔固定 根據(jù)脈沖數(shù)量可計算出時間 )


時鐘脈沖信號 :

  • 1.概念 : 按照 一定的電壓幅度一定的時間間隔 , 連續(xù)發(fā)出的 脈沖信號, 就是 時鐘 脈沖信號;
  • 2.重要作用 : 時鐘脈沖信號 是 時序邏輯的 基礎(chǔ), 脈沖信號的 間隔是固定的, 可以 根據(jù)脈沖信號的個數(shù) 及 間隔 計算出對應(yīng)的時間 ;
  • 3.應(yīng)用場景 : 芯片 中的 晶體管 工作狀態(tài) 都是由 0 1 組成, 即 開和關(guān), 控制這些開關(guān)操作都是 按照 時鐘信號 的 節(jié)奏 進行 的;
  • 4.說明示例 : 現(xiàn)在的主流 CPU i7 8700K 主頻是 3.7GHz, 其中 1 GHz = 10^3 MHz = 10^6 KHz = 10^9 Hz 即 10億 Hz, 每秒鐘有 37億 次時鐘脈沖信號; 也就是 經(jīng)常說的 每秒鐘 運算 37 億次; 當(dāng)前的超級計算機可以到達 每秒 2億億次;


( 2 ) 時鐘脈沖頻率 ( 概念 : 單位時間內(nèi)產(chǎn)生的脈沖個數(shù) )


時鐘脈沖頻率 :

  • 1.概念 : 單位時間內(nèi) 產(chǎn)生 的 時鐘脈沖個數(shù) 就是 時鐘脈沖頻率;
  • 2.舉例 : 1秒中 產(chǎn)生 1次, 就是 1Hz, 1秒鐘產(chǎn)生 100 次就是 100Hz, 上面舉例的 i78700K CPU, 一秒鐘產(chǎn)生 37億次, 就是 3.7GHz 的時鐘脈沖頻率;


(3) 時鐘源 ( 產(chǎn)生來源 : ① 晶振 ② 鎖相環(huán) PLL | 晶振 : 晶體震蕩電路 | PLL 鎖相環(huán) : 晶振 + PLL 合成 | 晶振 與 PLL 對比 優(yōu)缺點 )


時鐘源 : 時鐘脈沖信號 是由 晶振 或 鎖相環(huán) PLL 產(chǎn)生;

  • 1.晶振 : 全稱 晶體振蕩器, 是由 石英晶體 制作的, 石英晶體 ① 按照一定的方位角 切割, 并 ② 在其內(nèi)部添加電子元件組成振蕩電路;
    • ① 震蕩特性 : 如果 給晶振通電, 就會產(chǎn)生機械震蕩, 其 頻率由 制作的材質(zhì), 切割角度 等決定;
    • ② 物理特性 : 石英非常 穩(wěn)定, 其控制的 震蕩頻率也很穩(wěn)定, 其 頻率可以根據(jù)集合尺寸精確控制;
    • ③ 晶振優(yōu)勢 : 晶振具有 A. 結(jié)構(gòu)簡單, B. 噪音低, C. 可提供精確定制的頻率, 等優(yōu)點;
    • ④ 晶振缺陷 : A. 生產(chǎn)成本高 , B. 交貨的周期很長;
  • 2.PLL(鎖相環(huán)) : 鎖相環(huán) 比 晶振 更復(fù)雜, PLL 需要一個外部晶振作為輸入, PLL 可以對外部晶振產(chǎn)生的頻率進行 加倍 或 分頻 操作, 即 提高 或 降低 頻率;
    • ① 使用場景 : 簡單系統(tǒng)一般采用 石英晶振, 復(fù)雜的系統(tǒng)采用 晶振 + PLL 合成 提供時鐘源;
    • ② 降低成本 : 如果需要特定的時鐘頻率, 可以使用 PLL + 低頻晶振 代替高頻的晶振 , 這樣成本比較低;
    • ③ 多時鐘頻率系統(tǒng) : 如果 在一個設(shè)備上需要多個時鐘頻率系統(tǒng), 可以使用 PLL + 晶振 合成提供時鐘源, PLL 將 晶振頻率 進行 加倍 或 分頻 即可得到不同頻率的時鐘源;
    • ④ 與晶振對比 : PLL + 晶振 比 純晶振 成本要低, 并且提供更加靈活多變的時鐘頻率 ;




二. 時鐘體系簡介


時鐘體系學(xué)習(xí)步驟 : 對不不同的時鐘體系, 需要按照下面的學(xué)習(xí)步驟學(xué)習(xí)即可;
① 晶振頻率 ;
② PLL 個數(shù) 及 種類 ;
③ PLL 產(chǎn)生的時鐘類型;
④ PLL 產(chǎn)生的時鐘作用;


1. 2440 開發(fā)板 時鐘體系


參考手冊 : S3C2440.pdf , 章節(jié) : 7 CLOCK & POWER MANAGEMENT , Page 235;


(1) 2440 開發(fā)板時鐘體系介紹 ( 12MHz 晶振 | 2 PLL : ① MPLL ② UPLL | MPLL -> ① FCLK [ ARM 核 ] ② HCLK [ AHB 總線 ] ③ PCLK [ APB 總線 ] | UPLL -> UCLK [ USB 總線 ] )


2440 開發(fā)板時鐘體系介紹 :

  • 1.晶振頻率 : 12MHz;
  • 2.PLL (鎖相環(huán)) : 有 2 個 PLL, 分別是 MPLL 和 UPLL;
  • 3.產(chǎn)生時鐘個數(shù) :MPLL 鎖相環(huán) 產(chǎn)生出 FCLK , HCLK, PCLK 三個時鐘; ② UPLL 鎖相環(huán) 產(chǎn)生出 UCLK 時鐘;
  • 4.各個時鐘作用 :
    • ① FCLK 時鐘作用 : 處理器 中使用, ARM 核使用的時鐘是 FCLK, 該時鐘是 MPLL 產(chǎn)生的;
    • ② HCLK 時鐘作用 : AHB 總線中使用, 如 LCD, DMA 控制, 該時鐘是 MPLL 產(chǎn)生的;
    • ③ PCLK 時鐘作用 : APB 總線中使用, 如 Uart 串口, GPIO, 該時鐘是 MPLL 產(chǎn)生的;
    • ④ UCLK 時鐘作用 : USB 總線中使用, 該時鐘是 UPLL 產(chǎn)生的;
  • 5.2440 時鐘體系圖示 : 該圖在 S3C2440.pdf 文檔中的 7 CLOCK & POWER MANAGEMENT 章節(jié), 237 頁 ;



(2) 6410 開發(fā)板時鐘體系介紹 ( 12MHz 晶振頻率 | 3 PLL : ① APLL ② MPLL ③ EPLL | APLL -> ACLK [ ARM 核 ] | MPLL -> ① HCLK [ AHB 總線 ] ② PCLK [ APB 總線 ] | EPLL -> SCLK [ USB 總線 ] )


參考手冊 : S3C6410X.pdf , 章節(jié) : 3.3.4.1 Clock selection between PLLs and input reference clock , Page 124;


6410 開發(fā)板時鐘體系介紹 :

  • 1.晶振頻率 : 12MHz;
  • 2.PLL (鎖相環(huán)) : 有 3 個 PLL, 分別是 APLL , MPLL 和 EPLL;
  • 3.產(chǎn)生時鐘個數(shù) :APLL 鎖相環(huán) 產(chǎn)生出 ACLK 一個時鐘; ② MPLL 鎖相環(huán) 產(chǎn)生出 HCLK, PCLK 時鐘; ③ EPLL 產(chǎn)生 SCLK 時鐘;
  • 4.各個時鐘作用 :
    • ① ACLK 時鐘作用 : 處理器中使用, ARM核中使用 ACLK 時鐘, 該時鐘是 APLL 鎖相環(huán)產(chǎn)生;
    • ② HCLK 時鐘作用 : AHB 總線中使用, 如 LCD, DMA ; 該時鐘是 MPLL 產(chǎn)生的;
    • ③ PCLK 時鐘作用 : APB 總線中使用, 如 Uart 串口, GPIO 中使用, 該時鐘是 MPLL 產(chǎn)生的;
    • ④ SCLK 時鐘作用 : USB 總線中使用, 該時鐘是 EPLL 鎖相環(huán)產(chǎn)生的;
  • 5.6410時鐘體系圖示 : 該圖在 S3C6410X.pdf 文檔中的 3.3.4.1 Clock selection between PLLs and input reference clock 章節(jié), 124 頁 ;


(3) S5PV210 開發(fā)板時鐘體系介紹 ( 24MHz 晶振頻率 | 4 PLL ① APLL ② MPLL ③ EPLL ④ VPLL )


參考手冊 : S5PV210_UM_REV1.1.pdf , 章節(jié) : 3.4 CLOCK GENERATION , Page 361;


S5PV210 開發(fā)板時鐘體系介紹 :

  • 1.晶振頻率 : 24MHz;
  • 2.PLL (鎖相環(huán)) : 有 4 個 PLL, 分別是 APLL , MPLL , EPLLVPLL;
  • 3.S5PV210 的 時鐘體系分類 : 分為 以下 三類 ;
    • ① 主系統(tǒng)時鐘體系 : MSYS , 由 APLL 鎖相環(huán)產(chǎn)生, 產(chǎn)生的時鐘有 ARMCLK, HCLK_MSYS, PCLK_MSYS , 應(yīng)用在 ARM 核 中;
    • ② 顯示相關(guān)時鐘體系 : DSYS , 由 MPLL 鎖相環(huán)產(chǎn)生, 產(chǎn)生的時鐘有 HCLK_DSYS, PCLK_DSYS, 主要應(yīng)用在顯示相關(guān)的部件中 ;
    • ③ 外圍設(shè)備時鐘體系 : PSYS , 由 EPLL 鎖相環(huán)產(chǎn)生, 產(chǎn)生的時鐘有 HCLK_PSYS, CLK_DPM, 主要用于外設(shè), 如 Uart 串口 等;
    • ④ VPLL 鎖相環(huán)產(chǎn)生的時鐘 : VPLL 產(chǎn)生的時鐘 主要用于視頻處理;
  • 4.S5PV210時鐘體系圖示 : 該圖在 S5PV210_UM_REV1.1.pdf 文檔中的3.4 CLOCK GENERATION, 361 頁 ;




三. S3C6410 初始化時鐘



1. S3C 6410 時鐘初始化流程簡介


(1) CPU 頻率變化過程 ( ① 上電后 12MHz | ② 配置 PLL | ③ 處于 Lock Time 頻率 0Hz | ④ 正常 PLL 頻率 )


CPU 上電后 從 低頻率 到 高頻率的變化過程 :

  • 1.上電后的工作頻率 : 上電后 ARM 核的工作頻率就是晶振頻率, 即 12MHz, 這個速度非常慢;
  • 2.配置鎖相環(huán) : 配置鎖相環(huán), 使 頻率 增加;
  • 3.Lock Time 時間 : 配置 PLL 鎖相環(huán)后, 會出現(xiàn)一段不工作的時間, 此時 CPU 頻率為 0Hz, 這段時間叫 Lock Time;
  • 4.正常頻率 : 在 Lock Time 之后, 就會進入正式的 鎖相環(huán) 工作頻率, 此時的頻率是 晶振頻率 經(jīng)過 鎖相環(huán) 處理后的 高頻率;
  • 5.圖示 : 下圖是處理器上電后各種參數(shù)的變化, 橫軸是時間軸, 沒有縱軸, 各個參數(shù)在上電后的每個時間段的表現(xiàn);

整個時鐘初始化流程是需要軟件幫助進行的, 因此這些步驟需要開發(fā)者進行開發(fā), 這也是該博客的主要內(nèi)容;



(2) 時鐘初始化的四個步驟 ( ① 配置 Lock Time | ② 設(shè)置分頻系數(shù) | ③ 設(shè)置 APLL MPLL 頻率 | ④ 設(shè)置 CPU 工作模式 -> 異步工作模式 )


時鐘初始化流程 :

  • 1.配置 Lock Time : 配置 PLL 鎖相環(huán)后會有一段 CPU 頻率為 0 的時間, 這段時間處理器不工作, 這段時間就是 Lock Time;
  • 2.設(shè)置分頻系數(shù) : 通過 為 不同的時鐘設(shè)置不同的分頻系數(shù), 根據(jù)這個分頻系數(shù), 來確定每個時鐘的頻率;
  • 3.設(shè)置 APLL MPLL 頻率 : 設(shè)置一個時鐘的頻率, 可以根據(jù)分頻系數(shù)計算出其它所有時鐘的頻率了;
  • 4.設(shè)置 CPU 工作模式 : 如果 FCLK 與 HCLK 的頻率不同, 那么 CPU 需要設(shè)置為 異步工作模式, FCLK 是 ARM 核的時鐘, HCLK 是 總線時鐘, 如果兩個時鐘不一致, 需要將 CPU 設(shè)置為 異步工作模式;
    • ① 常用設(shè)置 : 一般情況下 設(shè)置 分頻系數(shù)的時候, 不會給 FCLK 與 HCLK 設(shè)置相同的分頻系數(shù), 因此, 該步驟大部分情況下都要執(zhí)行;



2. S3C 6410 時鐘初始化 匯編代碼編寫


參考手冊 : ARM芯片 手冊 S3C6410X.pdf ( 基于 6410 開發(fā)板 ARM 11 )

  • 1.手冊對應(yīng)章節(jié) : 3 SYSTEM CONTROLLER;
  • 2.S3C6410X.pdf手冊下載地址 :

(1) 配置 Lock Time


配置 Lock Time :

  • 1.文檔位置 : S3C6410X.pdf 手冊, Page 141, 3.4.2.1 PLL Control Registers 章節(jié);
  • 2.默認設(shè)置不變 ( 推薦 ) : 一般情況下, 使用開發(fā)板的默認設(shè)置即可, 如果有特殊定制需求才修改該 PLL_LOCK 寄存器的值;


(2) 設(shè)置分頻系數(shù)


設(shè)置分頻系數(shù) :

  • 1.相關(guān)文檔位置 : S3C6410X.pdf 手冊, Page 125, 3.3.4.2 ARM and AXI/AHB/APB bus clock generation 章節(jié);
  • 2.APLL 鎖相環(huán) : 12 MHz 的晶振頻率, 經(jīng)過 APLL 鎖相環(huán) 產(chǎn)生 輸出時鐘, 該輸出時鐘 經(jīng)過 DIVARM 分頻, 產(chǎn)生 ARMCLK, 這是 ARM 核使用的時鐘;
  • 3.MPLL 鎖相環(huán) : 12MHz 晶振頻率時鐘, 經(jīng)過 MPLL 鎖相環(huán) 產(chǎn)生的 時鐘, 該時鐘 經(jīng)過 DIVHCLKX2 分頻后, 產(chǎn)生 HCLKx2 時鐘, 同時 DIVHCLKX2 分頻后的時鐘 又 經(jīng)過不同的 分頻 產(chǎn)生 HCLK, PCLK, CLKJPEG, CLKSECUR 時鐘;
    • ① HCLK 時鐘 : HCLKx2 時鐘 經(jīng)過 DIVHCLK 分頻后, 產(chǎn)生 HCLK 時鐘;
    • ② PCLK 時鐘 : HCLKx2 時鐘 經(jīng)過 DIVPCLK 分頻后, 產(chǎn)生 PCLK 時鐘;
    • ③ CLKJPEG 時鐘 : HCLKx2 時鐘 經(jīng)過 DIVCLKJPEG 分頻后, 產(chǎn)生 CLKJPEG 時鐘;
    • ④ CLKSECUR 時鐘 : HCLKx2 時鐘 經(jīng)過 DIVCLKSECUR 分頻后, 產(chǎn)生 CLKSECUR 時鐘;
  • 4.分頻參數(shù)參考 : 不同的時鐘分頻器的分頻參數(shù)列表 , 來源 S3C6410X.pdf 手冊, Page 126, 3.3.4.2 ARM and AXI/AHB/APB bus clock generation 章節(jié);
  • 5.時鐘分頻公式 : 文檔位置 S3C6410X.pdf 手冊, Page 126, 3.4.2.3 Clock divider control register 章節(jié);
    • ① DIVARM 分頻公式 : ARMCLK = DOUTAPLL / (ARM_RATIO + 1) , DOUTAPLL 是 APLL 鎖相環(huán)輸出的時鐘, ARM_RATIO 是設(shè)置的分頻系數(shù);
    • ② DIVHCLKX2 分頻公式 : HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1), HCLKX2IN 是 MPLL 鎖相環(huán)的輸出時鐘頻率, HCLKX2_RATIO 是設(shè)置的分頻系數(shù);
    • ③ DIVHCLK 分頻公式 : HCLK = HCLKX2 / (HCLK_RATIO + 1), HCLKX2 是 DIVHCLKX2 分頻后的時鐘頻率, HCLK_RATIO 是設(shè)置的分頻系數(shù);
    • ④ DIVPCLK 分頻公式 : PCLK = HCLKX2 / (PCLK_RATIO + 1), HCLKX2 是 DIVHCLKX2 分頻后的時鐘頻率, PCLK_RATIO 是設(shè)置的分頻系數(shù);
  • 6.PLL 鎖相環(huán)輸出頻率 :
    • ① APLL 鎖相環(huán)輸出頻率 : 533 MHz ;
    • ② MPLL 鎖相環(huán)輸出頻率 : 533 MHz ;
  • 7.具體參考參數(shù)設(shè)置 : 從 6410 開發(fā)板中的 u-boot 源碼中查找相關(guān)的時鐘 分頻系數(shù) ;
    • ① DIVARM 分頻參數(shù) : 0 , APLL 輸出頻率為 533MHz, 根據(jù)公式計算 ARMCLK 時鐘頻率為 533MHz;
    • ② DIVHCLKX2 分頻參數(shù) : 1 , MPLL 輸出頻率 533MHz, 根據(jù)公式計算 HCLKX2 時鐘為 266 MHz;
    • ③ DIVPCLK 分頻參數(shù) : 3 , HCLKX2 時鐘為 266 MHz, PCLK 頻率為 66MHz;
    • ④ DIVHCLK 分頻參數(shù) : 1 , HCLKX2 時鐘為 266 MHz, HCLK 頻率為 133MHz;

設(shè)置分頻系數(shù)代碼編寫 :

  • 1.定義分頻控制寄存器( Clock divider control register ) 地址 : 之前說的 分頻參數(shù) 都是通過 CLK_DIV0 寄存器設(shè)置的, 將 CLK_DIV0 的地址定義成常量, #define CLK_DIV0 0x7E00F020;
  • 2.定義分頻參數(shù)的值 : 參考 CLK_DIV0 值的表格 設(shè)置 CLK_DIV0 寄存器的實際值;
    • ① 定義 ARM_RATIO 分頻參數(shù) : 這個參數(shù)設(shè)置成 0, CLK_DIV0 寄存器的 [3:0] 位 設(shè)置該參數(shù), 該參數(shù)單獨為 0x0 << 0;
    • ② 定義 HCLKX2_RATIO 分頻參數(shù) : 這個參數(shù)設(shè)置成 1, CLK_DIV0 寄存器的 [11:9] 位 設(shè)置該參數(shù), 值為 0x1 << 9;
    • ③ 定義 HCLK_RATIO 分頻參數(shù) : 這個參數(shù)設(shè)置成 1, CLK_DIV0 寄存器的 [8] 位 設(shè)置該參數(shù), 值為 0x1 << 8;
    • ④ 定義 PCLK_RATIO 分頻參數(shù) : 這個參數(shù)設(shè)置成 3, CLK_DIV0 寄存器的 [15:12] 位 設(shè)置該參數(shù), 值為 0x3 << 12;
    • ⑤ 設(shè)置的值 : 將上面四個值匯總起來為 (0x0 << 0) | (0x1 << 9) | (0x1 << 8) | (0x3 << 12) ;
    • ⑥ 代碼 : #define CLK_VAL ( (0x0 << 0) | (0x1 << 9) | (0x1 << 8) | (0x3 << 12) ) ;
  • 3.裝載 CLK_DIV0 地址到通用寄存器中 : ldr r0, =CLK_DIV0;
  • 4.裝載 CLK_DIV0 的寄存器值到通用寄存器中 : ldr r1, =CLK_VAL;
  • 5.設(shè)置 CLK_DIV0 寄存器的值 : str r1, [r0], 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中 ;
  • 6.截止到當(dāng)前的匯編代碼展示 :
#define CLK_DIV0 0x7E00F020 @ 定義 CLK_DIV0 寄存器地址, 時鐘的分頻參數(shù)都是通過該寄存器進行設(shè)置的 #define CLK_VAL ( (0x0 << 0) | (0x1 << 9) | (0x1 << 8) | (0x3 << 12) ) @ 設(shè)置 CLK_DIV0 寄存器的值, 即 各個時鐘分頻器的參數(shù) init_clock : ldr r0, =CLK_DIV0 @ 將 CLK_DIV0 的地址裝載到 r0 通用寄存器中l(wèi)dr r1, =CLK_VAL @ 將 要設(shè)置給 CLK_DIV0 寄存器的值 CLK_VAL 立即數(shù) 裝載到 r1 通用寄存器中; str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中mov pc, lr

(3) 設(shè)置 CPU 異步工作模式


設(shè)置 CPU 異步工作模式 :

  • 1.相關(guān)文檔位置 : S3C6410X.pdf 手冊, Page 169, 3.4.2.14 Others control register 章節(jié);

  • 2.Others control register 寄存器 [7] : 第 7 位 [7], 設(shè)置為 0 時工作在 異步模式下, 設(shè)置為 1 時 工作在 同步模式 下;
  • 3.Others control register 寄存器 [6] : 第 6 位 用于選擇 鎖相環(huán)輸出源, 設(shè)置為 0 選擇 MPLL 鎖相環(huán) 輸出時鐘, 設(shè)置為 1 選擇 APLL 鎖相環(huán)輸出時鐘, 注意 只有在 CPU 同步模式下才設(shè)置為1;

匯編代碼編寫 :

  • 1.定義 OTHERS 寄存器地址 : #define OTHERS 0x7E00F900;
  • 2.將 OTHERS 寄存器地址存儲到 r0 寄存器中 : ldr r0, =OTHERS;
  • 3.讀取 OTHERS 寄存器的值 : ldr r1, [r0], 即 將 r0 寄存器存儲的地址指向的內(nèi)存中的值 裝載到 r1 通用寄存器中;
  • 4.設(shè)置寄存器值 : 將 r1 寄存器中存儲的 OTHERS 寄存器的 6 和 7 位 清零, 設(shè)置 CPU 異步工作模式, 同時設(shè)置 MPLL 鎖相環(huán)時鐘輸出, bic r1, r1, #0xc0;
  • 5.設(shè)置 OTHERS 寄存器值 : str r1, [r0], 將 r1 通用寄存器中的值 存儲到 r0 寄存器中保存的地址指向的內(nèi)存中, 即 OTHERS 寄存器;
  • 6.截止到當(dāng)前的匯編代碼展示 :
#define CLK_DIV0 0x7E00F020 @ 定義 CLK_DIV0 寄存器地址, 時鐘的分頻參數(shù)都是通過該寄存器進行設(shè)置的 #define OTHERS 0x7E00F900 @ 定義 OTHERS 寄存器地址, 用于設(shè)置 CPU 異步工作模式 #define CLK_VAL ( (0x0 << 0) | (0x1 << 9) | (0x1 << 8) | (0x3 << 12) ) @ 設(shè)置 CLK_DIV0 寄存器的值, 即 各個時鐘分頻器的參數(shù) init_clock : ldr r0, =CLK_DIV0 @ 將 CLK_DIV0 的地址裝載到 r0 通用寄存器中l(wèi)dr r1, =CLK_VAL @ 將 要設(shè)置給 CLK_DIV0 寄存器的值 CLK_VAL 立即數(shù) 裝載到 r1 通用寄存器中; str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中l(wèi)dr r0, =OTHERS @ 將 OTHERS 寄存器地址存到 r0 通用寄存器中l(wèi)dr r1, [r0] @ 將 r0 寄存器存儲的地址指向的寄存器中的值讀取到 r1 通用寄存器中bic r1, r1, #0xc0 @ 將 r1 寄存器中的值的 第 6 位 和 第 7 位 設(shè)置成 0str r1, [r0] @ 將 r1 寄存器中的值 寫出到 r0 寄存器存儲的地址指向的內(nèi)存位置 即 OTHERS 寄存器mov pc, lr

(4) 設(shè)置 APLL 和 MPLL 時鐘頻率


設(shè)置 APLL 和 MPLL 時鐘頻率 :

  • **1.相關(guān)文檔位置 : **S3C6410X.pdf 手冊, Page 141, 3.4.2.1 PLL Control Registers 章節(jié);
  • 2.APLL 和 MPLL 控制寄存器 : 下面兩張表格 分別說明了 兩個 PLL 控制寄存器對應(yīng)的地址, 以及寄存器每一位設(shè)置的值;

  • 3.PLL 輸出頻率公式 : FOUT = MDIV X FIN / (PDIV X 2^SDIV), 該公式在 S3C6410X.pdf 文檔 142 頁, 由公式可以得到 PLL 輸出頻率由 MDIV , PDIV, SDIV 三個參數(shù)決定, 文檔中給出了一個固定的表格示例, 這里我們選擇 第 5 行的參數(shù)進行設(shè)置;

匯編代碼編寫 :

  • 1.定義 APLL_CON 寄存器地址常量 : #define APLL_CON 0x7E00F00C ;
  • 2.定義 MPLL_CON 寄存器地址常量 : #define MPLL_CON 0x7E00F010 ;
  • 3.分析 PLL 控制寄存器要設(shè)置的位 : 我們要設(shè)置 533MHz 的 PLL 輸出頻率, APLL 和 MPLL 都輸出 533MHz 的頻率;
    • ① 533MHz 輸出確定的參數(shù) : MDIV 設(shè)置成 266, PDIV 設(shè)置 3, SDIV 設(shè)置 1;
    • ② 寄存器值設(shè)置 : #define PLL_VAL ( (0x1 << 31) | (266 << 16) | (3 << 8) | (1 << 0) ) ;
      • a. 啟用 PLL : [31] 設(shè)置成 1 , 設(shè)置值為 1 << 31;
      • b. 設(shè)置 MDIV : [25:16] 位設(shè)置成 266, 設(shè)置值為 266 << 16;
      • c. 設(shè)置 PDIV : [13:8] 位 設(shè)置成 3, 值為 3 << 8 ;
      • d.設(shè)置 SDIV : [2:0] 位 設(shè)置成 1, 值為 1 << 0;
      • e. 最終值為 : (0x1 << 31) | (266 << 16) | (3 << 8) | (1 << 0) ;
  • 4.設(shè)置 APLL_CON 寄存器的值 : 首先將 APLL_CON 寄存器地址存儲到 r0 寄存器中, 然后將 要設(shè)置的值 存儲到 r1 寄存器中, 之后 使用 str 指令將 r1 寄存器的值 存儲到 r0 寄存器中存儲的地址指向的內(nèi)存中, 即 將 PLL_VAL 值設(shè)置給 APLL_CON 寄存器;
ldr r0, =APLL_CON ldr r1, =PLL_VAL str r1, [r0]
  • 5.設(shè)置 MPLL_CON 寄存器的值 : 首先將 MPLL_CON 寄存器地址存儲到 r0 寄存器中, 然后將 要設(shè)置的值 存儲到 r1 寄存器中, 之后 使用 str 指令將 r1 寄存器的值 存儲到 r0 寄存器中存儲的地址指向的內(nèi)存中, 即 將 PLL_VAL 值設(shè)置給 MPLL_CON 寄存器;
ldr r0, =MPLL_CON ldr r1, =PLL_VAL str r1, [r0]
  • 6.截止到當(dāng)前的代碼 : 目前已完成 ① 分頻參數(shù)設(shè)置,② CPU 異步模式設(shè)置, ③APLL 和 MPLL 時鐘頻率設(shè)置工作;
#define CLK_DIV0 0x7E00F020 @ 定義 CLK_DIV0 寄存器地址, 時鐘的分頻參數(shù)都是通過該寄存器進行設(shè)置的 #define OTHERS 0x7E00F900 @ 定義 OTHERS 寄存器地址, 用于設(shè)置 CPU 異步工作模式 #define CLK_VAL ( (0x0 << 0) | (0x1 << 9) | (0x1 << 8) | (0x3 << 12) ) @ 設(shè)置 CLK_DIV0 寄存器的值, 即 各個時鐘分頻器的參數(shù) #define MPLL_CON 0x7E00F010 @ 定義 MPLL_CON 寄存器地址常量 #define APLL_CON 0x7E00F00C @ 定義 APLL_CON 寄存器地址常量 #define PLL_VAL ( (0x1 << 31) | (266 << 16) | (3 << 8) | (1 << 0) ) @ 設(shè)置 PLL 控制寄存器的值 init_clock : ldr r0, =CLK_DIV0 @ 將 CLK_DIV0 的地址裝載到 r0 通用寄存器中l(wèi)dr r1, =CLK_VAL @ 將 要設(shè)置給 CLK_DIV0 寄存器的值 CLK_VAL 立即數(shù) 裝載到 r1 通用寄存器中; str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中l(wèi)dr r0, =OTHERS @ 將 OTHERS 寄存器地址存到 r0 通用寄存器中l(wèi)dr r1, [r0] @ 將 r0 寄存器存儲的地址指向的寄存器中的值讀取到 r1 通用寄存器中bic r1, r1, #0xc0 @ 將 r1 寄存器中的值的 第 6 位 和 第 7 位 設(shè)置成 0str r1, [r0] @ 將 r1 寄存器中的值 寫出到 r0 寄存器存儲的地址指向的內(nèi)存位置 即 OTHERS 寄存器ldr r0, =APLL_CON @ 將 APLL_CON 寄存器地址存到 r0 通用寄存器中l(wèi)dr r1, =PLL_VAL @ 將 要設(shè)置給 APLL_CON 寄存器的值 PLL_VAL 立即數(shù) 裝載到 r1 通用寄存器中;str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中, 即 將 PLL_VAL 的值 設(shè)置到 APLL_CON 寄存器中l(wèi)dr r0, =MPLL_CON @ 將 MPLL_CON 寄存器地址存到 r0 通用寄存器中l(wèi)dr r1, =PLL_VAL @ 將 要設(shè)置給 MPLL_CON 寄存器的值 PLL_VAL 立即數(shù) 裝載到 r1 通用寄存器中;str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中, 即 將 PLL_VAL 的值 設(shè)置到 MPLL_CON 寄存器中mov pc, lr

(5) 設(shè)置 時鐘源


時鐘源設(shè)置 :

  • 1.相關(guān)文檔位置 : S3C6410X.pdf 手冊, Page 145, 3.4.2.2 Clock source control register 章節(jié);

  • 2.CLK_SRC 寄存器 : 控制時鐘源;
    • ① 控制 APLL 時鐘源 : [0] 位 控制 APLL 時鐘源, 如果設(shè)置為 0 , 使用晶振作為時鐘源, 如果設(shè)置為 1, 使用 APLL 輸出的時鐘作為時鐘源;
    • ② 控制 MPLL 時鐘源 : [1] 位 控制 MPLL 時鐘源, 如果設(shè)置為 0 , 使用晶振作為時鐘源, 如果設(shè)置為 1, 使用 MPLL 輸出的時鐘作為時鐘源;
    • ③ 控制 EPLL 時鐘源 : [2] 位 控制 EPLL 時鐘源, 如果設(shè)置為 0 , 使用晶振作為時鐘源, 如果設(shè)置為 1, 使用 EPLL 輸出的時鐘作為時鐘源;

匯編代碼編寫 :

  • 1.定義 CLK_SRC 寄存器地址常量 : #define CLK_SRC 0x7E00F01C ;
  • 2.設(shè)置 CLK_SRC 寄存器的值 : 將 [1:0] 兩位設(shè)置成 1; 首先將 CLK_SRC 寄存器地址存儲到 r0 寄存器中, 然后將 要設(shè)置的值 0x3 立即數(shù) 存儲到 r1 寄存器中, 之后 使用 str 指令將 r1 寄存器的值 存儲到 r0 寄存器中存儲的地址指向的內(nèi)存中, 即 將 0x3 值設(shè)置給 CLK_SRC 寄存器;
ldr r0, =CLK_SRC mov r1, #0x3 str r1, [r0]

(6) 代碼示例


代碼示例 : 截止到當(dāng)前的代碼示例 ① 設(shè)置 MVC 模式 ② 外設(shè)基地址初始化, ③ 關(guān)閉看門狗, ④ 關(guān)閉中斷, ⑤ 關(guān)閉 MMU, ⑥ 初始化時鐘, ⑦ 打開 LED 發(fā)光二極管;

@**************************** @File:start.S @ @BootLoader 初始化代碼 @**************************** .text @ 宏 指明代碼段 .global _start @ 偽指令聲明全局開始符號 _start: @ 程序入口標(biāo)志 b reset @ reset 復(fù)位異常 ldr pc, _undefined_instruction @ 未定義異常, 將 _undefined_instruction 值裝載到 pc 指針中 ldr pc, _software_interrupt @ 軟中斷異常 ldr pc, _prefetch_abort @ 預(yù)取指令異常 ldr pc, _data_abort @ 數(shù)據(jù)讀取異常 ldr pc, _not_used @ 占用 0x00000014 地址 ldr pc, _irq @ 普通中斷異常 ldr pc, _fiq @ 軟中斷異常 _undefined_instruction: .word undefined_instruction @ _undefined_instruction 標(biāo)號存放了一個值, 該值是 32 位地址 undefined_instruction, undefined_instruction 是一個地址 _software_interrupt: .word software_interrupt @ 軟中斷異常 _prefetch_abort: .word prefetch_abort @ 預(yù)取指令異常 處理 _data_abort: .word data_abort @ 數(shù)據(jù)讀取異常 _not_used: .word not_used @ 空位處理 _irq: .word irq @ 普通中斷處理 _fiq: .word fiq @ 快速中斷處理 undefined_instruction: @ undefined_instruction 地址存放要執(zhí)行的內(nèi)容 nop software_interrupt: @ software_interrupt 地址存放要執(zhí)行的內(nèi)容 nop prefetch_abort: @ prefetch_abort 地址存放要執(zhí)行的內(nèi)容 nop data_abort: @ data_abort 地址存放要執(zhí)行的內(nèi)容 nop not_used: @ not_used 地址存放要執(zhí)行的內(nèi)容 nop irq: @ irq 地址存放要執(zhí)行的內(nèi)容 nop fiq: @ fiq 地址存放要執(zhí)行的內(nèi)容 nop reset: @ reset 地址存放要執(zhí)行的內(nèi)容 bl set_svc @ 跳轉(zhuǎn)到 set_svc 標(biāo)號處執(zhí)行bl set_serial_port @ 設(shè)置外設(shè)基地址端口初始化bl disable_watchdog @ 跳轉(zhuǎn)到 disable_watchdog 標(biāo)號執(zhí)行, 關(guān)閉看門狗bl disable_interrupt @ 跳轉(zhuǎn)到 disable_interrupt 標(biāo)號執(zhí)行, 關(guān)閉中斷bl disable_mmu @ 跳轉(zhuǎn)到 disable_mmu 標(biāo)號執(zhí)行, 關(guān)閉 MMU init_clock @ 跳轉(zhuǎn)到 init_clock 標(biāo)號, 執(zhí)行時鐘初始化操作bl light_led @ 打開開發(fā)板上的 LED 發(fā)光二極管set_svc:mrs r0, cpsr @ 將 CPSR 寄存器中的值 導(dǎo)出到 R0 寄存器中bic r0, r0, #0x1f @ 將 R0 寄存器中的值 與 #0x1f 立即數(shù) 進行與操作, 并將結(jié)果保存到 R0 寄存器中, 實際是將寄存器的 0 ~ 4 位 置 0orr r0, r0, #0xd3 @ 將 R0 寄存器中的值 與 #0xd3 立即數(shù) 進行或操作, 并將結(jié)果保存到 R0 寄存器中, 實際是設(shè)置 0 ~ 4 位 寄存器值 的處理器工作模式代碼msr cpsr, r0 @ 將 R0 寄存器中的值 保存到 CPSR 寄存器中mov pc, lr @ 返回到 返回點處 繼續(xù)執(zhí)行后面的代碼#define pWTCON 0x7e004000 @ 定義看門狗控制寄存器 地址 ( 6410開發(fā)板 ) disable_watchdog: ldr r0, =pWTCON @ 先將控制寄存器地址保存到通用寄存器中mov r1, #0x0 @ 準(zhǔn)備一個 0, 看門狗控制寄存器都設(shè)置為0 , 即看門狗也關(guān)閉了str r1, [r0] @ 將 0 值 設(shè)置到 看門狗控制寄存器中 mov pc, lr @ 返回到 返回點處 繼續(xù)執(zhí)行后面的代碼disable_interrupt:mvn r1,#0x0 @ 將 0x0 按位取反, 獲取 全 1 的數(shù)據(jù), 設(shè)置到 R1 寄存器中l(wèi)dr r0,=0x71200014 @ 設(shè)置第一個中斷屏蔽寄存器, 先將 寄存器 地址裝載到 通用寄存器 R0 中 str r1,[r0] @ 再將 全 1 的值設(shè)置到 寄存器中, 該寄存器的內(nèi)存地址已經(jīng)裝載到了 R0 通用寄存器中l(wèi)dr r0,=0x71300014 @ 設(shè)置第二個中斷屏蔽寄存器, 先將 寄存器 地址裝載到 通用寄存器 R0 中 str r1,[r0] @ 再將 全 1 的值設(shè)置到 寄存器中, 該寄存器的內(nèi)存地址已經(jīng)裝載到了 R0 通用寄存器中mov pc, lr @ 返回到 返回點處 繼續(xù)執(zhí)行后面的代碼disable_mmu : mcr p15,0,r0,c7,c7,0 @ 設(shè)置 I-Cache 和 D-Cache 失效mrc p15,0,r0,c1,c0,0 @ 將 c1 寄存器中的值 讀取到 R0 通用寄存器中bic r0, r0, #0x00000007 @ 使用 bic 位清除指令, 將 R0 寄存器中的 第 0, 1, 2 三位 設(shè)置成0, 代表 關(guān)閉 MMU 和 D-Cachemcr p15,0,r0,c1,c0,0 @ 將 R0 寄存器中的值寫回到 C1 寄存器中mov pc, lr @ 返回到 返回點處 繼續(xù)執(zhí)行后面的代碼set_serial_port : ldr r0, =0x70000000 @ 將基地址裝載到 r0 寄存器中, 該基地址 在 arm 核 手冊中定義orr r0, r0, #0x13 @ 設(shè)置初始化基地址的范圍, 將 r0 中的值 與 0x13 立即數(shù) 進行或操作, 將結(jié)果存放到 r0 中mcr p15, 0, r0, c15, c2, 4 @ 將 r0 中的值設(shè)置給 c15 協(xié)處理器 mov pc, lr#define CLK_DIV0 0x7E00F020 @ 定義 CLK_DIV0 寄存器地址, 時鐘的分頻參數(shù)都是通過該寄存器進行設(shè)置的 #define OTHERS 0x7E00F900 @ 定義 OTHERS 寄存器地址, 用于設(shè)置 CPU 異步工作模式 #define CLK_VAL ( (0x0 << 0) | (0x1 << 9) | (0x1 << 8) | (0x3 << 12) ) @ 設(shè)置 CLK_DIV0 寄存器的值, 即 各個時鐘分頻器的參數(shù) #define MPLL_CON 0x7E00F010 @ 定義 MPLL_CON 寄存器地址常量 #define APLL_CON 0x7E00F00C @ 定義 APLL_CON 寄存器地址常量 #define PLL_VAL ( (0x1 << 31) | (266 << 16) | (3 << 8) | (1 << 0) ) @ 設(shè)置 PLL 控制寄存器的值 #define CLK_SRC 0x7E00F01C @ 定義 CLK_SRC 時鐘源控制寄存器的地址常量 init_clock : ldr r0, =CLK_DIV0 @ 將 CLK_DIV0 的地址裝載到 r0 通用寄存器中l(wèi)dr r1, =CLK_VAL @ 將 要設(shè)置給 CLK_DIV0 寄存器的值 CLK_VAL 立即數(shù) 裝載到 r1 通用寄存器中; str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中l(wèi)dr r0, =OTHERS @ 將 OTHERS 寄存器地址存到 r0 通用寄存器中l(wèi)dr r1, [r0] @ 將 r0 寄存器存儲的地址指向的寄存器中的值讀取到 r1 通用寄存器中bic r1, r1, #0xc0 @ 將 r1 寄存器中的值的 第 6 位 和 第 7 位 設(shè)置成 0str r1, [r0] @ 將 r1 寄存器中的值 寫出到 r0 寄存器存儲的地址指向的內(nèi)存位置 即 OTHERS 寄存器ldr r0, =APLL_CON @ 將 APLL_CON 寄存器地址存到 r0 通用寄存器中l(wèi)dr r1, =PLL_VAL @ 將 要設(shè)置給 APLL_CON 寄存器的值 PLL_VAL 立即數(shù) 裝載到 r1 通用寄存器中;str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中, 即 將 PLL_VAL 的值 設(shè)置到 APLL_CON 寄存器中l(wèi)dr r0, =MPLL_CON @ 將 MPLL_CON 寄存器地址存到 r0 通用寄存器中l(wèi)dr r1, =PLL_VAL @ 將 要設(shè)置給 MPLL_CON 寄存器的值 PLL_VAL 立即數(shù) 裝載到 r1 通用寄存器中;str r1, [r0] @ 將 r1 寄存器中的內(nèi)容 存儲到 r0 存儲的地址 指向的內(nèi)存中, 即 將 PLL_VAL 的值 設(shè)置到 MPLL_CON 寄存器中l(wèi)dr r0, =CLK_SRC @ 將 CLK_SRC 寄存器地址設(shè)置到 r0 通用寄存器中mov r1, #0x3 @ 將 0x3 立即數(shù)設(shè)置給 r1 寄存器str r1, [r0] @ 將 r1 中存儲的立即數(shù)設(shè)置給 r0 寄存器存儲的地址指向的內(nèi)存中, 即 CLK_SRC 寄存器中mov pc, lr#define GPBCON 0x7F008820 #define GPBDAT 0x7F008824 light_led : ldr r0, =GPBCON @ 將 0x7F008820 GPM 控制寄存器的地址 0x7F008820 裝載到 r0 寄存器中l(wèi)dr r1, =0x1111 @ 設(shè)置 GPM 控制寄存器的行為 為 Output 輸出, 即每個對應(yīng)引腳的設(shè)置為 0b0001 值str r1, [r0] @ 將 r1 中的值 存儲到 r0 指向的 GPBCON 0x7F008820 地址的內(nèi)存中l(wèi)dr r0, =GPBDAT @ 將 GPBDAT 0x7F008824 地址值 裝載到 r0 寄存器中l(wèi)dr r1, =0b110000 @ 計算 GPM 數(shù)據(jù)寄存器中的值, 設(shè)置 0 為 低電平, 設(shè)置 1 為高電平, 這里設(shè)置 0 ~ 3 位為低電平, 其它為高電平str r1, [r0] @ 將 r1 中的值 存儲到 r0 指向的 GPBDAT 0x7F008824 地址的內(nèi)存中mov pc, lr


3. 鏈接器腳本


u-boot.lds 鏈接器腳本 代碼解析 :

  • 1.指明輸出格式 ( 處理器架構(gòu) ) : 使用 OUTPUT_ARCH(架構(gòu)名稱) 指明***輸出格式, 即處理器的架構(gòu)***, 這里是 arm 架構(gòu)的, OUTPUT_ARCH(arm) ;
  • 2.指明輸出程序的入口 : 設(shè)置編譯輸出的程序入口位置, 語法為 ENTRY(入口位置), 在上面的 Start.S 中設(shè)置的程序入口是 _start, 代碼為 ENTRY(_start) ;
  • 3.設(shè)置代碼段 : 使用 .text : 設(shè)置代碼段;
  • 4.設(shè)置數(shù)據(jù)段 : 使用 .data : 設(shè)置數(shù)據(jù)段;
  • 5.設(shè)置 BSS 段 : 使用 .bss : 設(shè)置 BSS 段;
    • ( 1 ) 記錄 BSS 段的起始地址 : bss_start = .; ;
    • ( 2 ) 記錄 BSS 段的結(jié)束地址 : bss_end = .; ;
  • 6.對齊 : 每個段都需要設(shè)置內(nèi)存的對齊格式, 使用 . = ALIGN(4); 設(shè)置四字節(jié)對齊即可;
  • 7.代碼示例 :
OUTPUT_ARCH(arm) /*指明處理器結(jié)構(gòu)*/ ENTRY(_start) /*指明程序入口 在 _start 標(biāo)號處*/ SECTIONS { . = 0x50008000; /*整個程序鏈接的起始位置, 根據(jù)開發(fā)板確定, 不同開發(fā)板地址不一致*/ . = ALIGN(4); /*對齊處理, 每段開始之前進行 4 字節(jié)對齊*/ .text : /*代碼段*/ { start.o (.text) /*start.S 轉(zhuǎn)化來的代碼段*/ *(.text) /*其它代碼段*/ } . = ALIGN(4); /*對齊處理, 每段開始之前進行 4 字節(jié)對齊*/ .data : /*數(shù)據(jù)段*/ { *(.data) } . = ALIGN(4); /*對齊處理, 每段開始之前進行 4 字節(jié)對齊*/ bss_start = .; /*記錄 bss 段起始位置*/ .bss : /*bss 段*/ { *(.bss) } bss_end = .; /*記錄 bss 段結(jié)束位置*/ }


4. Makefile 編譯腳本


makefile 文件編寫 :

  • 1.通用規(guī)則 ( 匯編文件編譯規(guī)則 ) : 匯編文件 編譯 成同名的 .o 文件, 文件名稱相同, 后綴不同, %.o : %.S, 產(chǎn)生過程是 arm-linux-gcc -g -c $^ , 其中 ^ 標(biāo)識是所有的依賴文件, 在該規(guī)則下 start.S 會被變異成 start.o ;
  • 2.通用規(guī)則 ( C 文件編譯規(guī)則 ) : C 代碼編譯成同名的 .o 文件, %.o : %.c , 產(chǎn)生過程是 arm-linux-gcc -g -c $^ ;
  • 3.設(shè)置最終目標(biāo) : 使用 all: 設(shè)置最終編譯目標(biāo);
    • ( 1 ) 依賴文件 : 產(chǎn)生最終目標(biāo)需要依賴 start.o 文件, 使用 all: start.o 表示最終目標(biāo)需要依賴該文件;
    • ( 2 ) 鏈接過程 : arm-linux-ld -Tu-boot.lds -o u-boot.elf $^, 需要使用鏈接器腳本進行連接, ①鏈接工具是 arm-linux-ld 工具, ②使用 -Tu-boot.lds 設(shè)置鏈接器腳本 是剛寫的 u-boot.lds 鏈接器腳本, ③輸出文件是 u-boot.elf 這是個中間文件, ④ 依賴文件是 $^ 代表所有的依賴;
    • ( 3 ) 轉(zhuǎn)換成可執(zhí)行二進制文件 : arm-linux-objcopy -O binary u-boot.elf u-boot.bin, 使用 -O binary 設(shè)置輸出二進制文件, 依賴文件是 u-boot.elf, 輸出的可執(zhí)行二進制文件 即 結(jié)果是 u-boot.bin ;
  • 4.makefile 文件內(nèi)容 :
all: start.oarm-linux-ld -Tu-boot.lds -o u-boot.elf $^ arm-linux-objcopy -O binary u-boot.elf u-boot.bin %.o : %.Sarm-linux-gcc -g -c $^%.o : %.carm-linux-gcc -g -c $^.PHONY: clean clean:rm *.o *.elf *.bin


5. 編譯輸出可執(zhí)行文件


編譯過程 :

  • 1.文件準(zhǔn)備 : 將 匯編代碼 ( start.S ) 鏈接器腳本 ( gboot.lds ) makefile 文件 拷貝到編譯目錄 ;
  • 2.執(zhí)行編譯命令 : make ;
  • 3.編譯結(jié)果 : 可以看到 生成了 編譯目標(biāo)文件 start.o, 鏈接文件 u-boot.elf, 可執(zhí)行的二進制文件 u-boot.bin ;



6. 燒寫代碼到開發(fā)板并執(zhí)行


( 1 ) OK6410 開發(fā)板啟動切換方式


OK6410 開發(fā)板啟動切換方式 : 通過控制 開發(fā)板右側(cè)的 8個開關(guān)來設(shè)置啟動來源;

  • 1.sd 卡啟動 : (1~8) 位置 : 0, 0, 0, 1, 1, 1, 1, 1;
  • 2.nand flash 啟動 : (1~8) 位置 : x, x, x, 1, 1, 0, 0, 1;
  • 3.nor flash 啟動 : (1~8) 位置 : x, x, x, 1, 0, 1, 0, x;


( 2 ) 制作 SD 卡啟盤 并 準(zhǔn)備程序


制作 SD 卡啟動盤 :

  • 1.找到開發(fā)板的燒寫工具 : OK6410-A 開發(fā)板的燒寫工具 在開發(fā)光盤 A 的 OK6410-A-1G用戶光盤(A)-20160812\Linux-3.0.1\Linux燒寫工具 目錄下, 開發(fā)板光盤資料下載地址 ;
  • 2.設(shè)置 SD_Writer.exe 屬性 ( win10系統(tǒng)需要進行的設(shè)置 ) : 右鍵點擊屬性, 在兼容性一欄, 設(shè)置 以 Windows 7 兼容模式運行, 并設(shè)置 以管理員身份運行此程序 ;
  • 3.先格式化 SD 卡 : 注意這里要使用 SD_Writer 中的 format 功能進行格式化 , 按照下面的步驟, 一步一步點擊確定執(zhí)行 ;


  • 4.選擇要燒寫的文件 : 這里選擇 OK6410-A-1G用戶光盤(A)-20160812\Linux-3.0.1\Linux燒寫工具\mmc_ram256.bin 文件;
  • 5.燒寫文件到 SD 卡中 : 直接點擊 Program 按鈕, 就將啟動程序燒寫到了 SD 卡中;
  • 6.準(zhǔn)備 LED 燈程序 : 將編譯出的 gboot.bin 文件名修改成 u-boot.bin, 必須修改成該文件名, 否則無法燒寫上去;
  • 7.將程序拷貝到 SD 卡中 : 將程序直接拷貝到 SD 卡中即可;

參考資料 : OK6410燒寫裸板程序方法
這是之前寫過的博客, 僅作為參考;



( 3 ) SecureCRT 連接開發(fā)板并燒寫程序


SecureCRT 連接開發(fā)板并燒寫程序 步驟 :

  • 1.硬件連接操作 : 使用 USB 轉(zhuǎn) 串口工具 將電腦 與 開發(fā)板鏈接, USB 插在電腦端, 串口端插在 開發(fā)板上, 插上電源適配器, 但是不要打開電源開關(guān);
  • 2.開發(fā)板設(shè)置 : 將開發(fā)板右側(cè)的開關(guān)設(shè)置成 SD 卡啟動, 即 (1~8) 位置 : 0, 0, 0, 1, 1, 1, 1, 1; 該步驟很重要;
  • 2.查詢串口端口號 : 在設(shè)備管理器中查看串口端口號, 這里可以看到是 COM9;
  • 3.SecureCRT 連接串口 : 打開 SecureCRT 軟件, 點擊快速連接, 然后在彈出的對話框中按照下面進行配置, ① 首先要選擇 Serial 協(xié)議, ② 然后選擇端口, 這個端口從設(shè)備管理器中查看, ③ 波特率選擇 115200, ④ 取消 RTS/CTS 選項;
  • 4.打開開發(fā)板 ( 很重要 ) : 選中 SecureCRT 軟件, 然后按住空格鍵不放, 這個操作很重要, 打開開發(fā)板開關(guān), ① 先按住空格鍵, ②再打開開關(guān);
  • 5.首先格式化 Nand Flash : 選擇 [1] 選項, 格式化 Nand Flash;
  • 6.選擇從 SD 卡中燒寫 : 選擇 [2] Burn image from SD card 選項, 從 SD 卡中向開發(fā)板燒寫程序;
  • 7.選擇燒寫 u-boot : 選擇 [2] Flash u-boot, 燒寫 u-boot, 會從 SD 卡中查找 u-boot.bin 文件, 然后燒寫到 nand flash 中, 如果 SD 卡中 沒有 u-boot.bin 會報錯;
  • 8.設(shè)置從 Nand Flash 啟動 : 設(shè)置開發(fā)板上的啟動開關(guān), (1~8) 位置 : x, x, x, 1, 1, 0, 0, 1; 此時 四個 LED 全亮;
  • 9.效果展示 : 設(shè)置的 GPBDAT 寄存器值為 0b110000, 四個 LED 燈都亮起來;
  • 10.修改 LED 燈顯示參數(shù)后顯示結(jié)果 : 設(shè)置 GPBDAT 寄存器中值為 0b110101 是 第一個 和 第三個 LED 亮起來;



7. 將程序燒寫到開發(fā)板上運行 ( 僅做參考 )


燒寫程序并運行 :

  • 1.參考步驟 : 燒寫代碼到開發(fā)板并執(zhí)行
  • 2.本次運行結(jié)果 : 設(shè)置的 GPBDAT 寄存器值為 0b110000, 四個 LED 燈都亮起來;
  • 3.修改 LED 燈顯示參數(shù)后顯示結(jié)果 : 設(shè)置 GPBDAT 寄存器中值為 0b110101 是 第一個 和 第三個 LED 亮起來;

總結(jié)

以上是生活随笔為你收集整理的【嵌入式开发】时钟初始化 ( 时钟相关概念 | 嵌入式时钟体系 | Lock Time | 分频参数设置 | CPU 异步模式设置 | APLL MPLL 时钟频率设置 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。