|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
我使用gcc编译,但只能生成,o文件,无法生成.bin文件,什么原因
9 N; X; N5 h* f* S! I# e5 G s.head.s. F7 n% K8 r3 K0 F- E, F, i( u+ @
, S8 t* z, `! F2 B8 Q5 J4 ]
@******************************************************************************
. `' u4 `- \$ J: S1 G9 _7 e@ File:head.S u( p0 p: [' Q: T( F
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行: u. a4 I- N% Y
@******************************************************************************
5 X8 [0 n8 x+ h, y5 I8 A r$ |
) f# |' x7 m# g# E! N.extern main* j8 F+ t1 o B t, q
.text
K' {" p, v0 N8 I; I.global _start
2 V8 [: p! u6 S2 h9 p; q_start:
; }# Q; c, N/ |" W+ }Reset: $ O9 _% D( @4 b/ [2 P& g) |( X0 z
ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
. t: I. e+ G5 S4 k bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
6 I9 m& J# d3 w, B2 s8 C* W; E // bl是位置无关码,相当于:PCnew = PC + 偏移
9 r4 N( B7 J2 [ // PCnew = (4+8) + 0x28 = 0x34
, g* z/ [( U4 H4 k+ |: ?* j * j( | {8 A4 {. D
ldr pc, =disable_watch_dog
0 v; c0 x9 O6 N- c/ \. S) M - ^( s& V3 z9 b) ]2 s Q. F
bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK5 b% g9 P1 ]2 R# _; J
bl memsetup @ 设置存储控制器以使用SDRAM
! t# n8 T4 B" ]& [7 M bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
1 ^: F& R3 P) M4 V ldr pc, =on_sdram @ 跳到SDRAM中继续执行1 I: B/ y! I6 l
on_sdram:
+ H+ X: y* i( \8 o$ j! b ldr sp, =0x34000000 @ 设置栈指针
5 ~; Y1 G9 z, K ldr lr, =halt_loop @ 设置返回地址0 R2 ]6 ?# @7 {
ldr pc, =main @ 调用main函数
( J% X/ q* I1 Ghalt_loop:$ d* I Q6 N9 h
b halt_loop" W' E: {* q, c: {' J% e
! S, j9 z. ^4 P/ t8 ~: b+ _ |
2.init.c- D* S/ f2 I% h3 ^. r$ q) V
/*6 J; O9 ?, O; k9 P& k! M m( \
* init.c: 进行一些初始化
* V3 S/ ]! ?1 q4 W5 I*/
7 \! v% x1 H* M- D/ o3 \- s6 S- N/ h8 W: J
#include "s3c24xx.h"
B. Y- h: t4 B! K! R5 J
$ P; K; J: w m( dvoid disable_watch_dog(void);
& ~; C! U! s+ _7 p7 Xvoid clock_init(void);
: f- W; B3 t; R* C# I* fvoid memsetup(void);
; X8 p: E A0 {! ?5 o+ y" Ovoid copy_steppingstone_to_sdram(void);: s3 Z u; M# y2 @9 R* b
5 Z- `/ _" Q! `
/*
, c+ Z' u% u. ~! \* 关闭WATCHDOG,否则CPU会不断重启$ p$ J" ~/ m. c3 x( q
*/$ w( H+ k/ v1 j5 u5 J8 ~9 {# m
void disable_watch_dog(void)
; M9 ~& }+ G: ^: w) N3 G: Q{- z" w5 X6 C1 W* I8 S9 r" l
WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可
5 l% `6 a& @" d& J( ?1 O3 e}- V% O+ G2 q& p; H+ ^1 }; ?& @
( @2 x& k7 O% N$ n0 u#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))- k, V3 j6 W- b
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
, y3 R: e6 P9 j- @, y/*6 {- }7 h) t( ]* O* g
* 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV
/ @8 {% _, n) C7 M, s* 有如下计算公式:) J Y. i) b6 y' u3 D- y [
* S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
`; b/ i% N# y7 m7 k6 S+ K* S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
$ L( ?$ g$ `) J8 ~7 Y* H3 g% q* 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
7 W' n, @0 @$ I$ d* 对于本开发板,Fin = 12MHz4 i' k( X, C. W: A
* 设置CLKDIVN,令分频比为:FCLK:HCLK CLK=1:2:4,' @! l" O9 C% G+ Y
* FCLK=200MHz,HCLK=100MHz,PCLK=50MHz- W# V( C# I a4 p( }
*/
- A6 Y/ {! w% c3 ]8 r7 U7 Y7 Wvoid clock_init(void)
' \9 X3 ^& z, A& }! x8 h{) S* n8 b% m6 j% U" b1 y3 G
// LOCKTIME = 0x00ffffff; // 使用默认值即可
9 y9 n: `8 w2 L! u6 c# R) L CLKDIVN = 0x03; // FCLK:HCLK CLK=1:2:4, HDIVN=1,PDIVN=1
% e6 |/ r! \& L; X* V
( B1 H/ n v4 u5 a3 v. x /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */& L5 \ h% F6 G6 F! M. _5 B% @, b
__asm__(0 I& K- y; b- m& n. L$ i# ]
"mrc p15, 0, r1, c1, c0, 0\n" /* 读出控制寄存器 */6 }) {& U/ d! S
"orr r1, r1, #0xc0000000\n" /* 设置为“asynchronous bus mode” */
% y4 v3 N5 B8 k; [% n) } "mcr p15, 0, r1, c1, c0, 0\n" /* 写入控制寄存器 */
0 z6 g6 h9 p: g );
c" U! Q; l" }5 P! M3 `$ A! `3 w0 p1 e3 O
/* 判断是S3C2410还是S3C2440 */
7 v3 K: |- u, R& V if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
$ H" U4 X* l, m1 e+ K {7 d0 ~- {9 e3 Y4 l8 \
MPLLCON = S3C2410_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */: M! ~' m7 W* T( |
}
/ N; s8 b% \' n) _0 p% g else
" Y+ J) C. V7 o z8 Q& f6 a {
& s u) e% Z$ q% x, C MPLLCON = S3C2440_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
! t+ t+ u2 b% S8 E3 W }
. ?- f1 M5 y$ a+ Z}
% _! c; E% w+ ~! e
- o( o: Z6 Q! t% U2 T; j' R! a# c/*
; d6 ~$ K$ g& u- b8 V8 m! e+ O! o5 H* o* 设置存储控制器以使用SDRAM. e5 \! I. i/ h' W
*/
7 l) f" G% ~' r* zvoid memsetup(void)5 p7 Z" C# t7 c/ @8 e1 g
{% i! F6 e! b, Y" j& q
volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
# z+ _# j6 K, T7 z. _6 I; F' h
3 V' h# I9 b {" C1 d /* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值, t7 n5 v J. k7 h- W' { m
* 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到- J' ^( {7 U* x% @+ D4 f% X$ E3 I
* SDRAM之前就可以在steppingstone中运行- d3 ]) u$ D% @4 v, e
*/
( @0 G2 n. F5 {" s* t* t /* 存储控制器13个寄存器的值 */: Y- W& N$ O6 g: I
p[0] = 0x22011110; //BWSCON
5 d9 N5 X* h& ^$ i6 _$ T' P. I p[1] = 0x00000700; //BANKCON0+ j/ e& @8 }+ U7 s# s' @
p[2] = 0x00000700; //BANKCON1
) ]. Y0 T f0 H p[3] = 0x00000700; //BANKCON2
* L' S7 g8 B; m* z p[4] = 0x00000700; //BANKCON3
3 a8 R/ ^2 T9 b8 ~: d p[5] = 0x00000700; //BANKCON4) Z5 q5 K! P: ]! A3 O# @
p[6] = 0x00000700; //BANKCON58 S5 C9 u) g6 x5 W* h# B7 N
p[7] = 0x00018005; //BANKCON6. Q& P- ?8 L4 C. @& r: {
p[8] = 0x00018005; //BANKCON78 k+ V$ w$ K/ H7 _2 ?! V
8 K8 S# r) Z* Y4 Z& f0 E6 u6 ~ /* REFRESH,
+ b8 }& k w/ Y& d3 t X, L * HCLK=12MHz: 0x008C07A3,
2 P( c; Q8 k3 I, O, ` * HCLK=100MHz: 0x008C04F4
^6 V! O, h, }% r, V7 ? */! | Q8 v6 u( d
p[9] = 0x008C04F4;
7 G. c: Z- v7 S" _) l; U p[10] = 0x000000B1; //BANKSIZE
, `0 n0 \3 S+ U$ H6 K3 h1 r' M p[11] = 0x00000030; //MRSRB6( I3 A. N+ h/ t! X, a' Y# c$ O; z
p[12] = 0x00000030; //MRSRB7
; l) G! c2 o! x, i% A) \# E# p}
4 A' E" K6 h* Z) p3 `8 e4 A+ P, h) i' q3 z
void copy_steppingstone_to_sdram(void)
# J$ T4 _, P! M) j$ p* |& \{# r, R( A) C3 |& [3 x+ g- m" H2 }
unsigned int *pdwSrc = (unsigned int *)0;
/ H8 H* ?1 ]2 Z% V unsigned int *pdwDest = (unsigned int *)0x30000000;+ B& j9 n7 j; |: `4 I7 m/ A( P2 w6 @
$ E" v8 S% g( O: d
while (pdwSrc < (unsigned int *)4096)) ~. P9 ]: w6 f% |
{
/ S' l7 F4 A1 P) G: E% H/ p *pdwDest = *pdwSrc;; w# A, b: O0 ^: C
pdwDest++;
. }( }1 ]/ N7 r }$ ~/ F pdwSrc++;, u' ^) m4 K2 {
}
" ?8 H( c/ `0 z8 [. h. V, G}3 n0 f7 M# O5 @ z
* V6 v# F& |, ]' j3.uart.c
1 l. L4 q/ p5 ]( N#include "s3c24xx.h"
8 r% `0 h) o# m% e( p#include "serial.h"
1 p1 @8 T6 o, o# q
# x7 D% w7 m# r9 d#define TXD0READY (1<<2)
8 }+ T- l$ ` E* z#define RXD0READY (1)
0 U$ t3 N# g, r7 m l1 Y0 [8 ~0 g& V; p, @1 `. d' p$ M* b! t
#define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz- l5 l! }1 Q$ p
#define UART_CLK PCLK // UART0的时钟源设为PCLK
4 c3 f/ ]3 v: U; Z#define UART_BAUD_RATE 115200 // 波特率
! ~7 ]- d* }5 c$ N' @/ K2 f#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)' ~2 p& ^8 B; r. l$ U
. t# k6 c: Q; M
/*
* |9 n3 C; x& w- k' a* 初始化UART0
, _% F6 p! x$ `* 115200,8N1,无流控. ^/ K: p$ S, l5 a
*/: G' Y8 D1 q. j8 {
void uart0_init(void)
5 [4 _+ U* u! z{
1 r. C/ L% W! K3 w. o; q GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0; R7 R; O2 n/ s4 i5 ~
GPHUP = 0x0c; // GPH2,GPH3内部上拉
! G. o' ?+ Q, _8 G8 J
8 @! O% g N, `2 u) k. F ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)
9 D6 h0 v5 L2 Z3 H, Z. H2 c0 F( U UCON0 = 0x05; // 查询方式,UART时钟源为PCLK
7 q9 k& P: ^5 L; k UFCON0 = 0x00; // 不使用FIFO% n8 T. M5 D9 C4 B8 v, s! o1 H6 n
UMCON0 = 0x00; // 不使用流控) }8 S5 }3 Y' V4 Y2 ]$ ^) V
UBRDIV0 = UART_BRD; // 波特率为115200
' }9 O4 j5 L$ }, \- w}5 t) F, S; Q& _5 M5 m3 @5 I9 R n
/ h* B+ z. H1 i' [) e
/*. b9 D* }9 |8 e) ^9 A( ~
* 发送一个字符
' k- ^& J. e+ q+ s5 }, P: g- Q# Z' O- B*/, M3 f2 T S: E/ l; `: _* _' h, k/ O
void putc(unsigned char c): i7 Z: l' O) F
{
* N( }; k( Y' d1 @2 A /* 等待,直到发送缓冲区中的数据已经全部发送出去 */* u( o9 L, f5 P( x. Y1 {/ M/ u, J* ~
while (!(UTRSTAT0 & TXD0READY));
& a- Q! u0 B) w X # l G- `- [/ _
/* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
! Z5 D- Z) a) H' H9 z5 q, ]' L UTXH0 = c;$ R6 K+ ^6 p' U& }' w3 h5 w ~5 }
}: V6 I! r; @. s4 w6 e! X
- O' r6 z* K# h6 }% c. m# A' X/ U
/*
3 ^5 |8 C7 l. u: J; N8 \0 S9 `* 接收字符
- N( E. R- W6 E( v$ f3 v*/
; E8 W7 d9 C& o o. E' @0 _% }; K' I5 V$ _unsigned char getc(void)
5 W5 a' I* o; Y& v{; R$ S. ] g2 n l* H& D6 `; d
/* 等待,直到接收缓冲区中的有数据 */3 M3 f- d+ _; {9 ]8 A" R
while (!(UTRSTAT0 & RXD0READY));
6 A7 k1 h/ @& c: b2 V" ` 5 l; M( O# _# k
/* 直接读取URXH0寄存器,即可获得接收到的数据 */* k! S# m: [6 t& v! }* P" b
return URXH0;
5 D9 [6 X6 U( E9 |% W}. ^$ b( `6 u, J0 d7 x0 a- ~
, d# o" m, \9 \# w! U6 W/*
" x6 K$ k* I* M- o$ T6 H g* 判断一个字符是否数字0 {, C. V5 l+ t; J
*/. `7 X! \& B1 {4 x
int isDigit(unsigned char c), P0 o) D' B. _: @% C/ s
{
" u0 j3 h" x% C$ N5 k! ? if (c >= '0' && c <= '9')# G6 v n+ a5 E0 }0 L+ y/ Z( C1 Q4 @7 G
return 1;
8 q6 r8 }+ |& z% U$ i else
1 m2 C! D4 K. Y* f return 0; 8 r: L* I( j9 t! m
}8 E/ H2 p$ @3 e5 f! u
+ d/ }8 x) c, X) I0 @3 @) X/*5 `# \9 Z' t- X7 Y
* 判断一个字符是否英文字母
G& M d3 r: J*/! H9 c- Y5 p5 T1 b1 F( X
int isLetter(unsigned char c)6 P5 O" [5 s0 `' Q+ e
{
3 O- k j+ M$ T2 w. [ if (c >= 'a' && c <= 'z')3 _# J" L+ s# q
return 1;
7 K/ i+ w3 G: B4 L0 B2 [6 y else if (c >= 'A' && c <= 'Z')
0 e# c0 A0 X6 l7 D( B7 y: s+ a return 1;
' i1 A4 v. ^, J8 x+ b2 V! A/ { else
: j% @7 [& d5 m# K4 a! n return 0;
0 h3 \3 c0 |. L* j. b% z}
8 ?/ Q" M' Z f; u! x' g
( ]+ i3 X; f- Y, r5 L/ k7 o/ [: O: @5 @2 E8 D. M+ a
4.uart.lds
0 ^7 d$ p7 ]6 V2 qSECTIONS {
9 u) s2 V( ?4 b; O . = 0x30000000;7 h* M% k$ B/ O" i! x. f
.text : { *(.text) }/ H0 h8 }: n9 `* O0 B
.rodata ALIGN(4) : {*(.rodata)}
) A1 ~% S8 w, l9 h .data ALIGN(4) : { *(.data) }
( V7 S5 ?. _: Q5 X .bss ALIGN(4) : { *(.bss) *(COMMON) }
3 u- i3 i% X, {# Z}8 e! e6 b' h/ u% ?0 \" B
6 c% ]7 c( Q) @8 @- Z1 z' D4 p5.main.c
* B/ C0 H& K; C- A- Q#include "serial.h"3 O: |, k P9 N, \) K
# Z/ O @2 N) v+ b
int main()
" u+ @6 `- b! h{6 n- `& N3 q2 R6 f) Q( |
unsigned char c;0 ?* w- Y, u2 ^0 u8 s
uart0_init(); // 波特率115200,8N1(8个数据位,无校验位,1个停止位)
8 v' R' r2 r6 V+ z& f2 z( R c0 n& A5 F, U; l- x1 c$ E! |* [9 \# a/ j
while(1)4 V! ]2 M9 ?4 E8 x0 L
{
2 ] J0 \6 ~1 Y1 H, \ // 从串口接收数据后,判断其是否数字或子母,若是则加1后输出
; `/ w) |/ k3 G, H# ]* s. ` c = getc();
8 X# ~5 I8 a6 l- R if (isDigit(c) || isLetter(c))* i9 a( \+ ]/ q; g" {
putc(c+1);/ S% }6 V0 ~ T8 w4 V
}
: {1 c; C7 h; v$ I/ q, F1 { L7 @. g2 D" U
return 0;& a6 o& L7 W/ F! J) U( @. ]2 I
}) d# y( b/ ^% k- O0 v3 Q5 x" a! N
% T4 T4 k3 |2 t) e$ x% d: I: A3 I {. B9 \& s( l& \% n: r) B2 E
6.Makefile
, R# v, A0 K) w2 F1 o8 O6 tobjs := head.o init.o serial.o main.o: ^, ?9 u% h6 z0 `- G# u
/ K' h$ s; L- d0 Z& F+ [
uart.bin: $(objs)) _+ V8 @% I2 h% y* W( r
ARM-linux-ld -Tuart.lds -o uart_elf $^* N8 b. X2 ?3 n8 G
arm-linux-objcopy -O binary -S uart_elf $@$ H: M9 i2 N' j1 u$ ?" T4 B5 D- ]
arm-linux-objdump -D -m arm uart_elf > uart.dis$ |. ^3 O* n4 W( J
& a, Q6 b/ j% h+ A5 v; V
%.o:%.c
& T) A) i; R2 H' d+ I arm-linux-gcc -Wall -O2 -c -o $@ $<0 j$ b3 m8 s4 L# N1 H/ m! y, \
6 w/ X4 U7 a8 d' ~* E. m%.o:%.S0 V& d& Z% p# \2 ^" Z! Z
arm-linux-gcc -Wall -O2 -c -o $@ $<8 I9 O/ f3 i& ]$ |( A
: N$ a8 E# o! U& B% r$ Z
clean:
% x5 D+ C- ?& o7 H ?4 _; W% @ rm -f uart.bin uart_elf uart.dis *.o |
+ S% g2 K, o [% p0 J+ v: g! l$ N* O1 H9 a0 I* @
# t! i0 y4 {6 T' S- d |
|