上一此實驗我們講解了如何對代碼進行重定位,但是將代碼重定位到只有256K的IRAM中作用不大。正確的做法是將代碼重定位到容量更大的主存中,即DRAM中。
Exynos4412中有兩個獨立的DRAM控制器,分別叫DMC0和DMC1。DMC0和DMC1分別支持最大1.5GB的DRAM,它們都支持DDR2/DDR3和LPDDR2等,512 Mb, 1 Gb, 2 Gb, 4 Gb and 8 Gbit的內存設備,支持16/32bit的位寬。DRAM0 對應的地址是0x4000_0000~0xAFFF_FFF共1.5GB,DRAM1 對應的地址是0xA000_000~0x0000_0000共1.5GB。
DRAM控制器地址映射
Tiny4412的1GB的DRAM是由4片大小為128MX16的DDR3芯片組合而成,下面看一下Tiny4412的原理圖:
Tiny4412 DDR電路圖
Tiny4412 DDR電路圖
從上兩圖可以看出,這四片DDR 芯片被分成了兩兩一組,組成32位數據,四片都是掛接到DMC0處。
如何才能使用DRAM?對應Tiny4412而言,由于用到了DMC0,所有我們需要初始化DMC0和DDR3 DRAM芯片。
聲明一下:
從這一節開始我們的程序結構發生了一些變化,前幾個實驗我們只生成一個文件,從這個實驗開始我們生成兩個文件,BL2.bin和main.bin,其中BL2.bin文件的鏈接地址是0x02023400;(使用的是位置無關碼,程序可以在任意可用的內存中運行),main.bin 文件的鏈接地址是0x43E00000(使用的并不是位置無關碼,所有程序必須位于該地址處才能正常運行)。需要在SD卡上燒寫三部分程序,分別是:
1.BL1(由三星提供):實現一些初始化
2.BL2(我們自己編寫源碼,用mkbl2工具生成):板級初始化,并完成代碼重定位到DDR SDRAM,完成跳轉
3.主代碼:實現我們想要的功能
三部分代碼在SD卡的位置如下:
程序在SD卡的位置分布
從圖中可以看出,BL1.bin燒寫到SD卡扇區1,BL2.bin燒寫到sd卡的扇區17,main.bin燒寫到sd卡的扇區49處。
整個程序的運行過程大致如下:系統上電后,首先將sd卡扇區1處的bl1拷貝到IRAM的0x02020000地址處,然后運行該部分代碼,該部分代碼首先又會加載BL2.bin,BL2.bin會進行時鐘和DRAM初始化,然后把位于sd卡中扇區49處的main.bin拷貝到DRAM的0x43E00000地址處,最后跳轉到該地址處繼續運行。
一、程序說明
DDR的初始化順序在前一篇文章Tiny4412裸機程序之DDR3初始化流程我們已經經過,下面就根據前面提及的步驟一一來進行設置。
注:看到這么多設置步驟,實在太繁瑣了,我們參考u-boot for Tiny4412中的代碼,搞明白它設置了哪些東西:
================================================================
//(C) Copyright 2011 Samsung Electronics Co. Ltd
//
//See file CREDITS for list of people who contributed to this
//project.
//
//This program is free software; you can redistribute it and/or modify
//it under the terms of the GNU General Public License version 2 as
//published by the Free Software Foundation.
#include "config.h"
#include "asm/arch/cpu.h"
#define MCLK_400
.globl mem_ctrl_asm_init
mem_ctrl_asm_init:
// Async bridge configuration at CPU_core:
// 1: half_sync
// 0: full_sync */
ldr r0, =0x10010350
mov r1, #1
str r1, [r0]
// 這幾行代碼不知道什么意思,以及這樣做的原因
///////////////////////////////////////////////////////////////////
//--------------------------------DREX0---------------------------
///////////////////////////////////////////////////////////////////
ldr r0, =APB_DMC_0_BASE
ldr r1, =0xe0000086
str r1, [r0, #DMC_PHYCONTROL1]
//2. If on die termination is required, enable PhyControl1.term_write_en,
//PhyControl1.term_read_en.
ldr r1, =0xE3854C03
str r1, [r0, #DMC_PHYZQCONTROL]
//3. If ZQ calibration is required, disable PhyZQControl.
// ctrl_zq_mode_noterm and enable PhyZQCon-trol.
// ctrl_zq_start so that the PHY automatically calibrates
// the I/Os to match the driving and termination impedance
// by referencing resistor value of an external resistor
// and updates the matched value during auto re-fresh cycles.
mov r2, #0x100000
1: subs r2, r2, #1
bne 1b
ldr r1, =0x7110100A
str r1, [r0, #DMC_PHYCONTROL0]
//4. Set the PhyControl0.ctrl_start_point and PhyControl0.
// ctrl_inc bit-fields to correct value according to clock frequency.
// Set the PhyControl0.ctrl_dll_on bit-field to "1" to activate the PHY DLL.
ldr r1, =0xe0000086
str r1, [r0, #DMC_PHYCONTROL1]
//5. DQS Cleaning: set the PhyControl1.ctrl_shiftc and PhyControl1.
// ctrl_offsetc bit-fields to the proper value according to clock frequency,
// board delay and memory tDQSCK parameter.
ldr r1, =0x7110100B
str r1, [r0, #DMC_PHYCONTROL0]
// 6. Set the PhyControl0.ctrl_start bit-field to "1".
ldr r1, =0x00000000
str r1, [r0, #DMC_PHYCONTROL2]
// DQS offset
// 實驗了一下可以省略,默認值就是全零
ldr r1, =0x0FFF301A
str r1, [r0, #DMC_CONCONTROL]
// 7. Set the ConControl. At this moment,an auto refresh counter should be off.
ldr r1, =0x00312640
str r1, [r0, #DMC_MEMCONTROL]
// 8. Set the MemControl. At this moment,
// all power down modes and periodic ZQ(pzq_en) should be off.
ldr r1, =0x40e01323
str r1, [r0, #DMC_MEMCONFIG0]
ldr r1, =0x60e01323
str r1, [r0, #DMC_MEMCONFIG1]
// 9. Set the MemConfig0 register. If there are two external memory chips,
// also set the MemConfig1 register.
ldr r1, =(0x80000000 | CONFIG_IV_SIZE)
str r1, [r0, #DMC_IVCONTROL]
// Memory Channel Interleaving
// 實驗了一下可以省略,用默認值就可以
ldr r1, =0xff000000
str r1, [r0, #DMC_PRECHCONFIG]
// 10. Set the PrechConfig and PwrdnConfig registers.
ldr r1, =0x000000BB
str r1, [r0, #DMC_TIMINGAREF] @TimingAref
ldr r1, =0x4046654f
str r1, [r0, #DMC_TIMINGROW] @TimingRow
ldr r1, =0x46400506
str r1, [r0, #DMC_TIMINGDATA] @TimingData
ldr r1, =0x52000a3c
str r1, [r0, #DMC_TIMINGPOWER] @TimingPower
// 11. Set the TimingAref, TimingRow, TimingData and
// TimingPower registers according to memory AC parame-ters.
// chip 0
ldr r1, =0x07000000
str r1, [r0, #DMC_DIRECTCMD]
// 19. Issue a NOP command using the DirectCmd register to assert
//and to hold CKE to a logic high level.
mov r2, #0x100000
2: subs r2, r2, #1
bne 2b
// 20. Wait for tXPR(max(5nCK,tRFC(min)+10ns)) or set tXP to tXPR value before step
// 17. If the system set tXP to tXPR, then the system must set tXP to proper value
// before normal memory operation.
ldr r1, =0x00020000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00030000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00010002
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00000328
str r1, [r0, #DMC_DIRECTCMD]
// 沒搞明白這里發的什么指令
mov r2, #0x100000
3: subs r2, r2, #1
bne 3b
ldr r1, =0x0a000000
str r1, [r0, #DMC_DIRECTCMD]
// 26. Issues a ZQINIT commands using the DirectCmd register.*/
mov r2, #0x100000
4: subs r2, r2, #1
bne 4b
// 27. If there are two external memory chips, perform steps 19 ~ 26
// procedures for chip1 memory device.
#if 1
// chip 1
ldr r1, =0x07100000
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
5: subs r2, r2, #1
bne 5b
ldr r1, =0x00120000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00130000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110002
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00100328
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
6: subs r2, r2, #1
bne 6b
ldr r1, =0x0a100000
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
7: subs r2, r2, #1
bne 7b
#endif
ldr r1, =0xe000008e
str r1, [r0, #DMC_PHYCONTROL1]
ldr r1, =0xe0000086
str r1, [r0, #DMC_PHYCONTROL1]
mov r2, #0x100000
8: subs r2, r2, #1
bne 8b
///////////////////////////////////////////////////////////////////
//---------------------------DREX1--------------------------------/
///////////////////////////////////////////////////////////////////
ldr r0, =APB_DMC_1_BASE
ldr r1, =0xe0000086
str r1, [r0, #DMC_PHYCONTROL1]
ldr r1, =0xE3854C03
str r1, [r0, #DMC_PHYZQCONTROL]
mov r2, #0x100000
1: subs r2, r2, #1
bne 1b
ldr r1, =0xe000008e
str r1, [r0, #DMC_PHYCONTROL1]
ldr r1, =0xe0000086
str r1, [r0, #DMC_PHYCONTROL1]
ldr r1, =0x71101008
str r1, [r0, #DMC_PHYCONTROL0]
ldr r1, =0x7110100A
str r1, [r0, #DMC_PHYCONTROL0]
ldr r1, =0xe0000086
str r1, [r0, #DMC_PHYCONTROL1]
ldr r1, =0x7110100B
str r1, [r0, #DMC_PHYCONTROL0]
ldr r1, =0x00000000
str r1, [r0, #DMC_PHYCONTROL2]
ldr r1, =0x0FFF301A
str r1, [r0, #DMC_CONCONTROL]
ldr r1, =0x00312640
str r1, [r0, #DMC_MEMCONTROL]
ldr r1, =0x40e01323 @Interleaved?
str r1, [r0, #DMC_MEMCONFIG0]
ldr r1, =0x60e01323
str r1, [r0, #DMC_MEMCONFIG1]
ldr r1, =(0x80000000 | CONFIG_IV_SIZE)
str r1, [r0, #DMC_IVCONTROL]
ldr r1, =0xff000000
str r1, [r0, #DMC_PRECHCONFIG]
ldr r1, =0x000000BB
str r1, [r0, #DMC_TIMINGAREF] @TimingAref
ldr r1, =0x4046654f
str r1, [r0, #DMC_TIMINGROW] @TimingRow
ldr r1, =0x46400506
str r1, [r0, #DMC_TIMINGDATA] @TimingData
ldr r1, =0x52000a3c
str r1, [r0, #DMC_TIMINGPOWER] @TimingPower
// chip 0
ldr r1, =0x07000000
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
2: subs r2, r2, #1
bne 2b
ldr r1, =0x00020000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00030000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00010002
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00000328
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
3: subs r2, r2, #1
bne 3b
ldr r1, =0x0a000000
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
4: subs r2, r2, #1
bne 4b
#if 1
// chip 1
ldr r1, =0x07100000
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
5: subs r2, r2, #1
bne 5b
ldr r1, =0x00120000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00130000
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110002
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00100328
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
6: subs r2, r2, #1
bne 6b
ldr r1, =0x0a100000
str r1, [r0, #DMC_DIRECTCMD]
mov r2, #0x100000
7: subs r2, r2, #1
bne 7b
#endif
ldr r1, =0xe000008e
str r1, [r0, #DMC_PHYCONTROL1]
ldr r1, =0xe0000086
str r1, [r0, #DMC_PHYCONTROL1]
mov r2, #0x100000
8: subs r2, r2, #1
bne 8b
///////////////////////////////////////////////////////////////////
//-----------------------Finalize---------------------------------/
///////////////////////////////////////////////////////////////////
ldr r0, =APB_DMC_0_BASE
ldr r1, =0x0FFF303A
str r1, [r0, #DMC_CONCONTROL]
// 28. Set the ConControl to turn on an auto refresh counter.
ldr r0, =APB_DMC_1_BASE
ldr r1, =0x0FFF303A
str r1, [r0, #DMC_CONCONTROL]
// 28. Set the ConControl to turn on an auto refresh counter.
mov pc, lr
================================================================
二、編譯、燒寫、運行
1.編譯
通過FTP或者其他工具將文件上傳到服務器上去,輸入make命令進行編譯將得到make_bl2.bin和main.bin文件。
2.燒寫
將SD卡插入電腦,并讓VmWare里的Ubuntu識別出來,然后執行如下命令:
1 | sudo ./sd_fusing.sh /dev/sdb ../9_reload_ddr/BL2/make_bl2.bin ../9_reload_ddr/MAIN/main.bin |
程序燒寫
二、運行現象
將SD卡插入Tiny4412開發板,連接串口工具,上電,你會看到和上一節的運行效果一樣(因為我們沒有修改LED的顯示效果,只是修改了程序的運行地址,這個對外是看不出區別的)。
串口可以看到如下顯示信息;
運行效果
從圖的信息室打印的地址0x43E00000處的內容(main.bin文件的鏈接地址)
我們將上述打印的信息和main.bin文件進行對比,發現完全一樣,說明代碼已經拷貝到了正確的鏈接地址。
文件對比
上一篇:Exynos4412裸機程序之UART收發數據
下一篇:Exynos4412裸機程序之DDR3初始化流程
推薦閱讀
史海拾趣
隨著市場競爭的加劇,ECC意識到只有不斷創新才能保持領先地位。因此,公司加大了對研發的投入,引進了一批先進的研發設備和人才。經過數年的努力,ECC成功研發出了具有更高精度、更好性能的電子連接器,并推出了一系列新型電子元件。這些新產品不僅滿足了客戶日益增長的需求,還為公司帶來了更多的市場份額。
隨著公司規模的擴大和市場份額的增加,DAYLIGHT開始將目光投向國際市場。公司通過與國際知名電子企業的合作,成功將其產品打入國際市場,并在多個國家和地區建立了銷售渠道。同時,DAYLIGHT還積極參與國際電子展和技術交流會議,不斷提升其在國際市場上的知名度和影響力。
近年來,隨著數字化技術的快速發展,DAYLIGHT公司也積極擁抱數字化轉型。公司加強了與互聯網、大數據、人工智能等技術的融合,推出了一系列智能化、數字化的電子產品和服務。這些新產品和服務的推出不僅提升了DAYLIGHT的市場競爭力,也為其未來的發展奠定了堅實的基礎。同時,DAYLIGHT還積極關注未來電子行業的發展趨勢和技術創新,為公司的長期發展制定了明確的戰略規劃。
請注意,這些故事是基于假設和一般行業趨勢虛構的,并不代表DAYLIGHT公司的實際發展歷程。如果您需要更具體的信息,建議直接聯系DAYLIGHT公司或查閱相關的行業資料。
隨著全球環保意識的提高,DAYLIGHT公司也開始注重環保和可持續發展。公司投入大量資金用于研發環保型電子產品和技術,并積極參與環保公益活動。此外,DAYLIGHT還制定了嚴格的環保標準和生產流程,確保其產品的生產和使用過程中對環境的影響最小化。
隨著技術實力的不斷增強,CALMIRCO公司開始積極拓展國內外市場。公司通過參加國際電子展會、建立海外銷售渠道等方式,逐漸將產品推向全球。同時,CALMIRCO公司還注重品牌建設,通過廣告宣傳、媒體報道等多種渠道提升品牌知名度和美譽度。這些舉措使得CALMIRCO公司的產品在市場上獲得了廣泛認可,公司也因此成為電子行業的佼佼者。
在電子行業的激烈競爭中,睿赫(crechip)公司以其獨特的創新理念和前瞻性的技術布局,逐漸嶄露頭角。公司創始人李明,一位資深的電子工程師,在一次國際技術交流會上,受到了來自全球各地創新思維的啟發。他意識到,隨著科技的飛速發展,電子行業正迎來一場前所未有的變革。于是,李明決定創立睿赫公司,專注于研發高性能、低功耗的半導體芯片。
在創業初期,睿赫公司面臨著重重困難,資金緊張、人才短缺、技術瓶頸等問題接踵而至。但李明帶領團隊迎難而上,通過不懈的努力和堅持,終于成功研制出了一款具有突破性的芯片產品,受到了業界的廣泛關注和認可。
如題,用ARM做變頻器的控制部分,出PWM波形給變頻器的IGBT驅動電路,看到的變頻器都是用DSP做的,不知道ARM是否合適?大家有做成的沒有? 看中了群星M3核的LM3S615了,有6路帶死區控制的PWM,大家給點建議,呵呵。另外根本還不知道輸出什么樣的PW ...… 查看全部問答∨ |
|
1·屏蔽 屏蔽的方法主要是采用金屬板、薄、外殼、鐵氧體吸收板、鐵氧體吸收薄、網格狀金屬殼,以解決內部噪音發射出去、外部噪音滲透進來。 2·鐵氧體 鐵氧體方法主要是采用分離型鐵氧體、鐵氧體環、夾子濾波器和平板型鐵氧體來吸收噪音,并把它 ...… 查看全部問答∨ |
各位大俠好: 北京天睿視迅科技有限公司是一家專業從事嵌入式、音視頻產品研發、生產、銷售的高科技公司,坐 落在北京市上地開發區。公司以嵌入式和音視頻技術為基礎,為客戶提供個性化的產品和服務。天睿專注 于嵌入式和音視頻產 ...… 查看全部問答∨ |
我現在只有一個lanuchpad。還有個壞了的51單片機。 由于lanuchpad自帶一個仿真器,我想繼續用lanuchpad用作仿真器。 該買什么樣的msp430單片機,只要一個最小板就行了。然后把壞51上的零件裝上去實驗。 有好幾個例程在于lanuchpad上無法調試,IO ...… 查看全部問答∨ |
交流一些個人淺薄的cortex m4經驗,從一個莫名的hard fault開始 最近搞了2塊st的cortex m4 discovery 板,玩lcd玩的很開心,把我stmf1上的顯示程序都移植到了新的m4平臺。因為程序大部分都是用c寫的,所以開始的時候非常順利,可是在一個5參數的函數出現了問題。癥狀是一運行到這個函數就進入hard fault,因為程 ...… 查看全部問答∨ |
使用的是Microblaze,單獨在EDK中編寫的程序下載到板子上運行正常,但是將microblaze作為大的ISE工程的IP核加進去的時候,microblaze中的程序運行不正常。具體來說,microbalze中用了4個GPIO,兩個分別引到FPGA引腳分別連接液晶屏和按鍵,另兩個GPIO ...… 查看全部問答∨ |