啟動程序源碼head.S:
@******************************************************************************
@ File:head.S
@ 功能:設置SDRAM,將程序復制到SDRAM,然后跳到SDRAM繼續執行
@******************************************************************************
.extern main
.text
.global _start
_start:
Reset:
ldr sp, =4096 @ 設置棧指針,以下都是C函數,調用前需要設好棧
bl disable_watch_dog @ 關閉WATCHDOG,否則CPU會不斷重啟
// bl是位置無關碼,相當于:PCnew = PC + 偏移
// PCnew = (4+8) + 0x28 = 0x34
//ldr pc, =disable_watch_dog 這一條指令即為位置相關的,用絕對地址(鏈接地址)跳轉
bl clock_init @ 設置MPLL,改變FCLK、HCLK、PCLK
bl memsetup @ 設置存儲控制器以使用SDRAM
bl copy_steppingstone_to_sdram @ 復制代碼到SDRAM中
ldr pc, =on_sdram @ 跳到SDRAM中繼續執行
on_sdram:
ldr sp, =0x34000000 @ 設置棧指針
ldr lr, =halt_loop @ 設置返回地址
ldr pc, =main @ 調用main函數
halt_loop:
b halt_loop
=====================================================================
init.c源碼:
// init.c: 進行一些初始化
#include "s3c24xx.h"
void disable_watch_dog(void);
void clock_init(void);
void memsetup(void);
void copy_steppingstone_to_sdram(void);
// 關閉WATCHDOG,否則CPU會不斷重啟
void disable_watch_dog(void)
{
WTCON = 0; // 關閉WATCHDOG很簡單,往這個寄存器寫0即可
}
#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
// 對于MPLLCON寄存器,[19:12]為MDIV,[9:4]為PDIV,[1:0]為SDIV
// 有如下計算公式:
// S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
// S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
// 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
// 對于本開發板,Fin = 12MHz
// 設置CLKDIVN,令分頻比為:FCLK:HCLK:PCLK=1:2:4,
// FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
void clock_init(void)
{
// LOCKTIME = 0x00ffffff; // 使用默認值即可
CLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
// 如果HDIVN非0,CPU的總線模式應該從“fast bus mode”變為“asynchronous bus mode”
__asm__(
"mrc p15, 0, r1, c1, c0, 0\n" // 讀出控制寄存器
"orr r1, r1, #0xc0000000\n" // 設置為“asynchronous bus mode”
"mcr p15, 0, r1, c1, c0, 0\n" // 寫入控制寄存器
);
// 判斷是S3C2410還是S3C2440
if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
{
MPLLCON = S3C2410_MPLL_200MHZ; // 現在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
}
else
{
MPLLCON = S3C2440_MPLL_200MHZ; // 現在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
}
}
// 設置存儲控制器以使用SDRAM
void memsetup(void)
{
volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
// 這個函數之所以這樣賦值,而不是像前面的實驗(比如mmu實驗)那樣將配置值
// 寫在數組中,是因為要生成”位置無關的代碼”,使得這個函數可以在被復制到
// SDRAM之前就可以在steppingstone中運行
// 存儲控制器13個寄存器的值
p[0] = 0x22011110; //BWSCON
p[1] = 0x00000700; //BANKCON0
p[2] = 0x00000700; //BANKCON1
p[3] = 0x00000700; //BANKCON2
p[4] = 0x00000700; //BANKCON3
p[5] = 0x00000700; //BANKCON4
p[6] = 0x00000700; //BANKCON5
p[7] = 0x00018005; //BANKCON6
p[8] = 0x00018005; //BANKCON7
// HCLK=12MHz: 0x008C07A3,
// HCLK=100MHz: 0x008C04F4
p[9] = 0x008C04F4; //REFRESH
p[10] = 0x000000B1; //BANKSIZE
p[11] = 0x00000030; //MRSRB6
p[12] = 0x00000030; //MRSRB7
}
void copy_steppingstone_to_sdram(void)
{
unsigned int *pdwSrc = (unsigned int *)0;
unsigned int *pdwDest = (unsigned int *)0x30000000;
while (pdwSrc < (unsigned int *)4096)
{
*pdwDest = *pdwSrc;
pdwDest++;
pdwSrc++;
}
}
=====================================================================
serial.h源碼:
void uart0_init(void);
void putc(unsigned char c);
unsigned char getc(void);
int isDigit(unsigned char c);
int isLetter(unsigned char c);
=====================================================================
serial.c源碼:
#include "s3c24xx.h"
#include "serial.h"
#define TXD0READY (1<<2)
#define RXD0READY (1)
#define PCLK 50000000 // init.c中的clock_init函數設置PCLK為50MHz
#define UART_CLK PCLK // UART0的時鐘源設為PCLK
#define UART_BAUD_RATE 115200 // 波特率
#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
// 初始化UART0
// 115200,8N1,無流控
void uart0_init(void)
{
GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
GPHUP = 0x0c; // GPH2,GPH3內部上拉
ULCON0 = 0x03; // 8N1(8個數據位,無較驗,1個停止位)
UCON0 = 0x05; // 查詢方式,UART時鐘源為PCLK
UFCON0 = 0x00; // 不使用FIFO
UMCON0 = 0x00; // 不使用流控
UBRDIV0 = UART_BRD; // 波特率為115200
}
// 發送一個字符
void putc(unsigned char c)
{
// 等待,直到發送緩沖區中的數據已經全部發送出去
while (!(UTRSTAT0 & TXD0READY));
// 向UTXH0寄存器中寫入數據,UART即自動將它發送出去
UTXH0 = c;
}
// 接收字符
unsigned char getc(void)
{
// 等待,直到接收緩沖區中的有數據
while (!(UTRSTAT0 & RXD0READY));
// 直接讀取URXH0寄存器,即可獲得接收到的數據
return URXH0;
}
// 判斷一個字符是否數字
int isDigit(unsigned char c)
{
if (c >= '0' && c <= '9')
return 1;
else
return 0;
}
// 判斷一個字符是否英文字母
int isLetter(unsigned char c)
{
if (c >= 'a' && c <= 'z')
return 1;
else if (c >= 'A' && c <= 'Z')
return 1;
else
return 0;
}
=====================================================================
main.c源碼:
#include "serial.h"
int main()
{
unsigned char c;
uart0_init(); // 波特率115200,8N1(8個數據位,無校驗位,1個停止位)
while(1)
{
// 從串口接收數據后,判斷其是否數字或子母,若是則加1后輸出
c = getc();
if (isDigit(c) || isLetter(c))
putc(c+1);
}
return 0;
}
=====================================================================
Makefile文件:
objs := head.o init.o serial.o main.o
uart.bin: $(objs)
arm-linux-ld -Tuart.lds -o uart_elf $^
arm-linux-objcopy -O binary -S uart_elf $@
arm-linux-objdump -D -m arm uart_elf > uart.dis
%.o:%.c
arm-linux-gcc -Wall -O2 -c -o $@ $<
%.o:%.S
arm-linux-gcc -Wall -O2 -c -o $@ $<
clean:
rm -f uart.bin uart_elf uart.dis *.o
=====================================================================
uart.lds文件:
SECTIONS {
. = 0x30000000;
.text : { *(.text) }
.rodata ALIGN(4) : {*(.rodata)}
.data ALIGN(4) : { *(.data) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}
上一篇:JZ2440裸板之LCD實驗
下一篇:JZ2440裸板之中斷控制器
推薦閱讀
史海拾趣
為了進一步提升技術實力和產品競爭力,Engelking Elektronik積極尋求與高校和研究機構的合作。通過與多家知名科技院校的合作,公司獲得了多項技術專利和研發成果。其中,一項重要的技術突破是開發了一種新型的高效能電子元件,該元件在能效和可靠性方面均達到了行業領先水平。這一成果不僅為公司帶來了可觀的經濟效益,也提升了公司在業界的地位。
隨著全球電子行業的競爭日益激烈,Ferroxcube公司意識到,要想保持領先地位,就必須不斷創新。于是,公司決定投入巨資建立一個新的研發中心,專注于磁性元件的前沿技術研究。
研發中心的建立吸引了大批優秀的科研人才加入Ferroxcube。在新的研發團隊的帶領下,公司相繼推出了多款具有自主知識產權的新型磁性元件,這些元件在性能、穩定性和可靠性方面都達到了行業領先水平。
其中一款名為“XX磁芯”的產品,憑借其超高的磁導率和極低的損耗,在市場上引起了轟動。這款產品不僅被廣泛應用于各類電子設備中,還成為了許多高校和科研機構的研究對象。Ferroxcube因此成為了行業內技術創新的佼佼者。
隨著電子技術的不斷進步,市場對繼電器產品的要求也越來越高。DRI Relays Inc公司意識到,只有不斷創新才能保持市場競爭力。為此,公司投入大量資金和資源,組建了一支由行業專家組成的研發團隊,專注于新技術和新產品的研發。經過數年的努力,公司成功開發出一系列具有自主知識產權的高性能繼電器產品,這些產品在市場上取得了巨大的成功,為公司帶來了可觀的利潤。
在追求經濟效益的同時,臺灣誠陽(BC)公司也積極履行企業社會責任。公司關注環保和可持續發展,致力于推廣綠色電子產品和節能減排技術。同時,公司還積極參與社會公益事業,為當地社區的發展做出貢獻。這種對社會責任的承擔和關注,使得臺灣誠陽在業界樹立了良好的形象,贏得了社會各界的認可和尊重。
請注意,以上故事僅為虛構示例,并不代表臺灣誠陽(BC)公司或任何真實公司的實際情況。如果您對該公司有進一步的了解需求,建議直接訪問其官方網站或查閱相關新聞報道。
面對全球電子行業的激烈競爭,FINECHIPS公司意識到供應鏈優化的重要性。公司積極調整供應鏈策略,與全球領先的半導體制造商和原材料供應商建立長期穩定的合作關系,確保原材料的穩定供應和成本控制。同時,FINECHIPS還在全球范圍內設立生產基地和研發中心,實現本地化生產和快速響應市場需求,進一步提升了公司的全球競爭力。
隨著技術的不斷進步和市場需求的增長,芯朋微電子逐步將產品線拓展至標準電源和工業驅動領域。2013年,公司推出工控功率芯片產品,這些芯片廣泛應用于電機、基站、智能電表等行業領域,進一步擴大了公司的市場份額。
一、 概述: 在網絡上最近最流行的LPC1114開發板主要有周立功、NXP等。都采用了仿真器加目標板的格式進行設計,設計得都非常小巧大方。每個工程師都想擁有一塊。哈哈,很幸運這兩種本人都各有一塊。下面是網絡上的圖片,光從圖片上來看,好像 ...… 查看全部問答∨ |
|
最近想學習ecos操作系統的內存管理部分。我在看源代碼的時候感覺沒有頭緒, 對固定大小的內存塊管理中,只看到了類Cyg_Mempool_Fixed_Implementation的定義,其成員函數try_alloc,resize_alloc等只有聲明,卻沒有找到這些函數的定義在哪里。還有程 ...… 查看全部問答∨ |
|
用msp430 f2132芯片,想精確計時到ms級別。 結果測試時間誤差很大,計時比實際實際多近1/10,另外還有一個問題,缺省smclk的時鐘是1Mhz的嗎? 代碼如下: void TimerAInit(void){ TACTL=TASSEL_2+TACLR+MC_0+ID_0; //選擇時 ...… 查看全部問答∨ |
|