start.S源碼:
.globl _start
_start:
// 硬件相關的設置
// Peri port setup
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
// 關看門狗
// 往WTCON(0x7E004000)寫0
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]
// 設置棧
ldr sp, =8*1024
// 設置時鐘
bl clock_init
bl ddr_init
bl init_uart
// 清BSS
// 把BSS段對應的內存清零
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
mov r3, #0
cmp r0, r1
b copy_kernel
clean_loop:
str r3, [r0], #4
cmp r0, r1
bne clean_loop
copy_kernel:
mov r0, #0x200000
ldr r1, =(0x50008000 - 64)
mov r2, #0x500000
bl copykernel2ddr
cmp r0, #0
bne halt
bl set_params
mov r0, #0
ldr r1, =1626
ldr r2, =0x50000100
ldr pc, =0x50008000
halt:
b halt
=====================================================================
clock.S源碼:
.globl clock_init
clock_init:
// 1.設置LOCK_TIME
ldr r0, =0x7E00F000 // APLL_LOCK
ldr r1, =0x0000FFFF
str r1, [r0]
str r1, [r0, #4] // MPLL_LOCK
str r1, [r0, #8] // EPLL_LOCK
#define OTHERS 0x7e00f900
@ set async mode // 當CPU時鐘 != HCLK時,要設為異步模式
ldr r0, =OTHERS
ldr r1, [r0]
bic r1, #0xc0
str r1, [r0]
loop1: // 等待,直到CPU進入異步模式
ldr r0, =OTHERS
ldr r1, [r0]
and r1, #0xf00
cmp r1, #0
bne loop1
// SYNC667
// MISC_CON[19] = 0
#define ARM_RATIO 0 // ARMCLK = DOUTAPLL / (ARM_RATIO + 1)
#define HCLKX2_RATIO 1 // HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1)
#define HCLK_RATIO 1 // HCLK = HCLKX2 / (HCLK_RATIO + 1)
#define PCLK_RATIO 3 // PCLK = HCLKX2 / (PCLK_RATIO + 1)
#define MPLL_RATIO 0 // DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)
ldr r0, =0x7E00F020 // CLK_DIV0
ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12)
str r1, [r0]
// 2.配置時鐘
// 2.1 配置APLL
// 2.1.1 設置APLL
// 2.1.2 MUXAPLL
// 2.1.3 SYNC667
// 2.1.4 DIVAPLL
#define APLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F00C
ldr r1, =APLL_CON_VAL
str r1, [r0] // APLL_CON, FOUTAPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz
// 2.2 配置MPLL
// 2.2.1 設置MPLL
// 2.2.2 MUXMPLL
// 2.2.3 SYNCMUX
// 2.2.4 SYNC667
// 2.2.5 HCLKX2_RATIO
// 2.2.6 PCLK_RATIO
#define MPLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F010
ldr r1, =MPLL_CON_VAL
str r1, [r0] // MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz
// 3.選擇PLL的輸出作為時鐘源
ldr r0, =0x7E00F01C
ldr r1, =0x03
str r1, [r0]
mov pc, lr
=====================================================================
sdram.c源碼:
#include "common.h"
#define MEMCCMD 0x7e001004
#define P1REFRESH 0x7e001010
#define P1CASLAT 0x7e001014
#define MEM_SYS_CFG 0x7e00f120
#define P1MEMCFG 0x7e00100c
#define P1T_DQSS 0x7e001018
#define P1T_MRD 0x7e00101c
#define P1T_RAS 0x7e001020
#define P1T_RC 0x7e001024
#define P1T_RCD 0x7e001028
#define P1T_RFC 0x7e00102c
#define P1T_RP 0x7e001030
#define P1T_RRD 0x7e001034
#define P1T_WR 0x7e001038
#define P1T_WTR 0x7e00103c
#define P1T_XP 0x7e001040
#define P1T_XSR 0x7e001044
#define P1T_ESR 0x7e001048
#define P1MEMCFG2 0X7e00104c
#define P1_chip_0_cfg 0x7e001200
#define P1MEMSTAT 0x7e001000
#define P1MEMCCMD 0x7e001004
#define P1DIRECTCMD 0x7e001008
#define HCLK 133000000
#define nstoclk(ns) (ns/( 1000000000/HCLK)+1)
int ddr_init( void )
{
// tell dramc to configure
set_val( MEMCCMD, 0x4 );
// set refresh period
set_val( P1REFRESH, nstoclk(7800) );
// set timing para
set_val( P1CASLAT, ( 3 << 1 ) );
set_val( P1T_DQSS, 0x1 ); // 0.75 - 1.25
set_val( P1T_MRD, 0x2 );
set_val( P1T_RAS, nstoclk(45) );
set_val( P1T_RC, nstoclk(68) );
u32 trcd = nstoclk( 23 );
set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
u32 trfc = nstoclk( 80 );
set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );
u32 trp = nstoclk( 23 );
set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );
set_val( P1T_RRD, nstoclk(15) );
set_val( P1T_WR, nstoclk(15) );
set_val( P1T_WTR, 0x7 );
set_val( P1T_XP, 0x2 );
set_val( P1T_XSR, nstoclk(120) );
set_val( P1T_ESR, nstoclk(120) );
// set mem cfg
set_nbit( P1MEMCFG, 0, 3, 0x2 ); // 10 column address
// set_nbit: 把從第bit位開始的一共len位消零,然后把這幾位設為val
set_nbit( P1MEMCFG, 3, 3, 0x3 ); // 14 row address
set_zero( P1MEMCFG, 6 ); // A10/AP
set_nbit( P1MEMCFG, 15, 3, 0x2 ); // Burst 4
set_nbit( P1MEMCFG2, 0, 4, 0x5 );
set_2bit( P1MEMCFG2, 6, 0x1 ); // 32 bit
set_nbit( P1MEMCFG2, 8, 3, 0x3 ); // Mobile DDR SDRAM
set_2bit( P1MEMCFG2, 11, 0x1 );
set_one( P1_chip_0_cfg, 16 ); // Bank-Row-Column organization
// memory init
set_val( P1DIRECTCMD, 0xc0000 ); // NOP
set_val( P1DIRECTCMD, 0x000 ); // precharge
set_val( P1DIRECTCMD, 0x40000 ); // auto refresh
set_val( P1DIRECTCMD, 0x40000 ); // auto refresh
set_val( P1DIRECTCMD, 0xa0000 ); // EMRS
set_val( P1DIRECTCMD, 0x80032 ); // MRS
set_val( MEM_SYS_CFG, 0x0 );
// set dramc to "go" status
set_val( P1MEMCCMD, 0x000 );
// wait ready
while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));
return 0;
}
=====================================================================
nand.c源碼:
#define MEM_SYS_CFG (*((volatile unsigned long *)0x7E00F120))
#define NFCONF (*((volatile unsigned long *)0x70200000))
#define NFCONT (*((volatile unsigned long *)0x70200004))
#define NFCMMD (*((volatile unsigned long *)0x70200008))
#define NFADDR (*((volatile unsigned long *)0x7020000C))
#define NFDATA (*((volatile unsigned char *)0x70200010))
#define NFSTAT (*((volatile unsigned long *)0x70200028))
void nand_select(void)
{
NFCONT &= ~(1<<1);
}
void nand_deselect(void)
{
NFCONT |= (1<<1);
}
void nand_cmd(unsigned char cmd)
{
NFCMMD = cmd;
}
void nand_addr(unsigned char addr)
{
NFADDR = addr;
}
unsigned char nand_get_data(void)
{
return NFDATA;
}
void nand_send_data(unsigned char data)
{
NFDATA = data;
}
void wait_ready(void)
{
while ((NFSTAT & 0x1) == 0);
}
void nand_reset(void)
{
// 選中
nand_select();
// 發出0xff命令
nand_cmd(0xff);
// 等待就緒
wait_ready();
// 取消選中
nand_deselect();
}
void nand_init(void)
{
#if 1
#define TACLS 7
#define TWRPH0 7
#define TWRPH1 7
NFCONF &= ~((7<<4) | (7<<8) | (7<<12) | (1<<30));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));
// 使能nand flash controller
NFCONT |= 1;
NFCONT &= ~(1<<16);
nand_reset();
#else
// 讓xm0csn2用作nand flash cs0 片選引腳
MEM_SYS_CFG &= ~(1<<1);
// 設置時間參數
#define TACLS 0
#define TWRPH0 1
#define TWRPH1 0
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));
// 使能nand flash controller
NFCONT |= 1;
NFCONT &= ~(1<<16); // 森止soft lock
nand_reset();
#endif
}
void nand_send_addr(unsigned int addr)
{
#if 0
unsigned int page = addr / 2048;
// 這兩個地址表示從頁內哪里開始
nand_addr(addr & 0xff);
nand_addr((addr >> 8) & 0xff);
// 下面三個地址表示哪一頁
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
#elif 0
nand_addr(addr & 0xff); // a0~a7
nand_addr((addr >> 8) & 0x7); // 程序的角度: a8~a10
nand_addr((addr >> 11) & 0xff); // 程序的角度: a11~a18
nand_addr((addr >> 19) & 0xff); // 程序的角度: a19~a26
nand_addr((addr >> 27) & 0xff); // 程序的角度: a27~
#elif 1
nand_addr(addr & 0xff); // a0~a7
nand_addr((addr >> 8) & 0x7); // 程序的角度: a8~a11
nand_addr((addr >> 12) & 0xff); // 程序的角度: a12~a19
nand_addr((addr >> 20) & 0xff); // 程序的角度: a20~a27
nand_addr((addr >> 28) & 0x01); // 程序的角度: a28~
#endif
}
int nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned int addr = nand_start;
int i = nand_start % 4096;
int count = 0;
unsigned char *dest = (unsigned char *)ddr_start;
// 選中芯片
nand_select();
while (count < len)
{
// 發出命令0x00
nand_cmd(0x00);
// 發出地址
nand_send_addr(addr);
// 發出命令0x30
nand_cmd(0x30);
// 等待就緒
wait_ready();
// 讀數據
for (; i < 4096 && count < len; i++)
{
dest[count++] = nand_get_data();
addr++;
}
i = 0;
}
// 取消片選
nand_deselect();
return 0;
}
int nand_erase_block(unsigned long addr)
{
int page = addr / 4096;
nand_select();
nand_cmd(0x60);
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
nand_cmd(0xd0);
wait_ready();
nand_deselect();
return 0;
}
int nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len)
{
unsigned long count = 0;
unsigned long addr = nand_start;
int i = nand_start % 4096;
nand_select();
while (count < len)
{
nand_cmd(0x80);
nand_send_addr(addr);
for (; i < 4096 && count < len; i++)
{
nand_send_data(buf[count++]);
addr++;
}
nand_cmd(0x10);
wait_ready();
i = 0;
}
nand_deselect();
return 0;
}
int copykernel2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
int ret;
// 初始化nand flash controller
nand_init();
// 讀nand flash
ret = nand_read(nand_start, ddr_start, len);
return ret;
}
=====================================================================
params.c源碼:
#include "setup.h"
static struct tag *params;
static void setup_start_tag (void)
{
params = (struct tag *)0x50000100;
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);
}
static void setup_memory_tags (void)
{
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = 0x50000000;
params->u.mem.size = 256*1024*1024;
params = tag_next (params);
}
char * strcpy(char * dest,const char *src)
{
char *tmp = dest;
while ((*dest++ = *src++) != '\0')
// nothing ;
return tmp;
}
int strlen(const char * s)
{
const char *sc;
for (sc = s; *sc != '\0'; ++sc)
// nothing ;
return sc - s;
}
static void setup_commandline_tag (void)
{
char *commandline = "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200";
params->hdr.tag = ATAG_CMDLINE;
params->hdr.size = (sizeof (struct tag_header) + strlen (commandline) + 1 + 3) >> 2;
strcpy (params->u.cmdline.cmdline, commandline);
params = tag_next (params);
}
static void setup_end_tag (void)
{
params->hdr.tag = ATAG_NONE;
params->hdr.size = 0;
}
void set_params(void)
{
setup_start_tag();
setup_memory_tags();
setup_commandline_tag();
setup_end_tag();
}
=====================================================================
uart.c源碼:
#include "s3c6410_regs.h"
//#define ENABLE_FIFO
void init_uart(void)
{
GPACON &= ~0xff;
GPACON |= 0x22;
// ULCON0
ULCON0 = 0x3; // 數據位:8, 無較驗, 停止位: 1, 8n1
UCON0 = 0x5 | (1<<9); // 使能UART發送、接收, tx interrupt request type = level
#ifdef ENABLE_FIFO
UFCON0 = 0x07 | (1<<6); // FIFO enable, tx fifo trigger level = 16 bytes
#else
UFCON0 = 0x00; // FIFO disable
#endif
UMCON0 = 0;
// 波特率
// DIV_VAL = (PCLK / (bps x 16 ) ) - 1
// bps = 57600
// DIV_VAL = (66500000 / (115200 x 16 ) ) - 1
// = 35.08
UBRDIV0 = 35;
// x/16 = 0.08
// x = 1
UDIVSLOT0 = 0x1;
}
unsigned char getc(void)
{
#ifdef ENABLE_FIFO
while ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0);
#else
while ((UTRSTAT0 & (1<<0)) == 0);
#endif
return URXH0;
}
=====================================================================
自己寫bootloader啟動內核,QT文件系統:
測試:把內核源碼放到ubuntu先解壓:
tar xzf linux-3.0.1-2012-09-23.tar.gz
cd linux-3.0.1-2012-09-23/
make uImage
會在arch/arm/boot/目錄下生成uImage文件
把開發板設為SD卡啟動,從SD卡啟動后按空格鍵運行SD卡里的u-boot來燒寫文件:
tftp 52000000 boot.bin
nand erase 0 200000
nand write 52000000 0 200000
tftp uImage 52000000
nand erase 200000 500000
nand write 52000000 200000 500000
斷電把開發板設為nand flash啟動,上電等uboot從nand flash中拷貝內核到DDR中再跳到DDR中運行即可看到內核啟動信息,要提前用SD卡把QT文件系統燒寫到nand flash中,內核才能掛載文件系統成功。
上一篇:OK6410啟動自動掛載nfs文件系統
下一篇:OK6410裸機之LCD調色板
推薦閱讀
史海拾趣
AIE公司自2005年成立以來,一直致力于推動電子測試配件的安全規范標準化。公司積極與各大電子廠商、行業協會以及標準化組織展開合作,共同制定了一系列關于測試配件的性能規格和安全標準。這一舉措不僅提升了AIE產品的競爭力,也促進了整個電子行業的健康發展。通過與業界的緊密合作,AIE逐漸在電子測試配件領域樹立了良好的口碑。
為了適應全球電子市場的快速發展,AIE公司積極實施全球化戰略。公司在多個國家和地區設立了分支機構或辦事處,以便更好地服務當地客戶。同時,AIE還積極參加國際電子展會和論壇,與全球各地的合作伙伴和客戶建立了廣泛的聯系。這些舉措不僅拓展了AIE的市場份額,也提升了公司的國際影響力。
Eurofarad始終將品質管理作為公司發展的重要保障。公司建立了完善的質量管理體系,從原材料采購到生產、檢測、包裝等各個環節都進行嚴格的質量控制。同時,Eurofarad還注重持續改進,不斷優化生產流程和提高生產效率,確保產品的品質和性能始終保持在行業領先水平。
隨著網絡安全威脅的不斷加劇,電子安全行業面臨著前所未有的挑戰。3E SECURITY公司緊跟行業趨勢,加強了網絡安全服務的研發和推廣。公司推出了一系列網絡安全解決方案,幫助客戶有效應對各類網絡攻擊和數據泄露風險。同時,公司還加強了對客戶的安全培訓和技術支持,提升了客戶的安全意識和應對能力。
3E SECURITY公司自創立之初,便以技術創新為核心競爭力。在電子安全領域,公司不斷投入研發,推出了一系列具有自主知識產權的安全產品。其中,一款智能安全監控系統憑借其高度集成和智能化特點,迅速在市場上占據了一席之地。通過不斷的技術革新,3E SECURITY逐漸在電子安全行業樹立了技術領先的形象,吸引了大量合作伙伴和客戶的關注。
作為一家領先的電子企業,DUBILIER公司深知其對社會和環境的影響。因此,公司積極履行社會責任,致力于推動可持續發展。公司采取了一系列環保措施,減少生產過程中的廢棄物和污染物排放。同時,DUBILIER公司還積極參與公益事業,為社會做出積極貢獻。這些努力不僅提升了公司的社會形象,還為公司贏得了更多的尊重和信任。
我需要用周立功ARM10開發平臺操作伺服電動機,目前采用串口控制電動機方式,現在通過串口發出去的東西,不能控制電動機。程序已經發出去,請高手幫忙,需要微軟EVC環境。太感謝了,老總和客戶催催催,我頭都大了,搞不定,請求幫助,請高手幫忙解決 ...… 查看全部問答∨ |
|
初學MSP430,讀數據手冊過程中遇到一個問題,calculated branching是什么意思?翻譯是計算分支,難道對switch case的優化?請知情者解答下!謝謝啊!… 查看全部問答∨ |
功能描述:把一個SD卡中的照片文件遠程傳到另一點的zigbee接收器中(也放SD卡作為存儲介質)。要求具有斷點續傳功能,比如一張圖片文件傳輸過程中意外中斷,要自動重新傳輸該圖片。要求傳輸距離2000米(視距)。 找相應的開發公司來做這個項目,合 ...… 查看全部問答∨ |
為什么我畫PCB的時候 一出來有些芯片就是綠色的呢 真是奇了怪了 有些芯片是我用向導生成的 而且FPGA芯片有的引腳是綠色的 有的是紅色的 有的電阻發綠有的發紅 真是不知怎么搞得很詭異 到底是哪些設計規則影響了他 求高手賜教… 查看全部問答∨ |
2012年中國國際信息通信展覽會于9月18日至23日在北京舉行。這屆通信展主題為\"智變中的ICT產業:開創應用和服務新時代\",著力展示新一代移動通信、下一代互聯網、三網融合、物聯網、云計算、集成電路、高端軟件、新型顯 ...… 查看全部問答∨ |
Hercules DIY By ddllxxrr 周報告匯總 我的報警器最關鍵的除了CPU自然是傳感器和執行部分了。 傳感器我選MQ-5 一、概述 QM-N5型氣敏元件是以金屬氧化物SnO2為主體材料的N型半導體氣敏元件,當元件接觸還原性氣體時,其電導率隨氣體濃度的增加而迅速升高。二、特點&nbs ...… 查看全部問答∨ |
本帖最后由 paulhyde 于 2014-9-15 03:09 編輯 而且硬件I2C。。。。。而且有倆UART。。。。而且有乘法器。。。運算還可以。。。。 … 查看全部問答∨ |
①靜電庫侖力的危害:靜電庫侖力作用下吸附的粉塵、污物,可能帶給元器件,從而增大泄露或造成短路,使性能受損,成品率大大下降。如粉塵粒徑>100微米,鋁線寬度約100微米,薄膜厚度在50微米以下時,最易使產品報廢,這種情形多發 ...… 查看全部問答∨ |
官方例程都毫無顯示,波特率各種參數都是對的,不知道大家是不是這樣的呢.[串口工具在Windows - Show View - Other - Terminal - Terminal] … 查看全部問答∨ |
設計資源 培訓 開發板 精華推薦
- Vxworks cf卡啟動 AtaXbdDevCreate ERROR
- 五四青年節,散200分慶祝一下,讓大家來談談自己的理想,順帶慶祝總技術分突破5000分!
- 我熟悉C語言 和 Java 語言 ,現在從事 S7-200的PLC程序編寫 但總轉不過來, 怎樣定義變量都不知道 ,有和我同樣經歷的過來人點撥下我么 謝謝
- DDR2
- STM32的ISP問題
- 現有一關于XL4015芯片的應用圖,請大神幫幫分析,有重謝!
- 【平頭哥Sipeed LicheeRV 86 Panel測評】- 3 waft-ui組件的測試
- 配置QT出現錯誤 運行make shi
- 基于模擬電感的混沌同步電路的研究
- 兩個LDO能并聯嗎?