|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
我使用gcc编译,但只能生成,o文件,无法生成.bin文件,什么原因
) ] n. F3 h3 E.head.s% C" I. ?$ ?) |. y% f
* z n7 h, j4 Y' \@******************************************************************************. c' t* p3 Z- p" `* w2 g& S
@ File:head.S
0 b: b% f" e, k@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
! B- b) d) }3 T' o* o7 K2 ~5 A@******************************************************************************
: t" D! O( h8 X( ]' C ( j1 s( u) S5 @
.extern main
D9 U4 U7 ^0 T, O.text
4 _& t+ \0 @1 w, f0 i/ H7 h.global _start
. _/ d! N. [& R+ M7 y6 {3 K- k_start:
9 m$ t7 g- i% @* U2 VReset: , K a/ y+ J9 ]0 r
ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈% S! W# R1 T- [, {# _& t7 C- V0 ~
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
. j2 C Q0 l0 ]9 j# F1 c$ _( K // bl是位置无关码,相当于:PCnew = PC + 偏移
! f8 I3 Y* c+ Y$ | // PCnew = (4+8) + 0x28 = 0x345 x, B, ^" G( M7 D
$ s& o& j' e( f3 d
ldr pc, =disable_watch_dog3 Q# D+ T& Q# g6 }3 M
8 t& i Z" \# R, T* m8 n bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK
H9 J: w$ h' K4 Z- C. a bl memsetup @ 设置存储控制器以使用SDRAM8 C; C$ @3 L; }
bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中, E# F6 g0 }$ L# S& I
ldr pc, =on_sdram @ 跳到SDRAM中继续执行
( i. v: i4 C/ aon_sdram:
5 Q2 s1 }& S: w, ?7 K1 P c ldr sp, =0x34000000 @ 设置栈指针$ C% p) u! W& n: x5 \$ I
ldr lr, =halt_loop @ 设置返回地址
4 |* N) }1 i# ~# M* A" b) t8 X" l& \+ i ldr pc, =main @ 调用main函数
4 t7 a8 a8 |: T. h5 ?$ |2 X/ hhalt_loop:
" K& m7 P) w6 Q+ L: O- F i; } { b halt_loop
2 w. F4 y6 X3 P' B% T) W
F+ ~( \$ P) U, V: j2.init.c! k6 n+ Z% x1 v$ |, @7 x7 M
/*6 d, C4 f3 D7 U8 | }" Q
* init.c: 进行一些初始化5 ~1 t1 n" V- V0 k, J% Q5 P
*/
! J" i; J; u$ Q3 l. }! S' q" P' z7 k( m, \- d' z
#include "s3c24xx.h"
5 k( o0 i0 j1 M2 b3 a3 q- L6 B4 n) D5 O# F
void disable_watch_dog(void);
, ^: o6 I8 `' I2 n$ k }3 Nvoid clock_init(void);9 ^. d8 O4 U- G5 H' X
void memsetup(void);
( G) W* C: s2 z: f/ G' T( G$ \void copy_steppingstone_to_sdram(void);- g0 o4 a4 i7 o& t: h/ Y1 u6 V
$ e; k6 n9 Q9 N7 S2 i" R7 }
/*
8 R; O! y( s! @6 h* 关闭WATCHDOG,否则CPU会不断重启/ f& ^, C9 R+ b
*/& F4 H1 T( A* D. f7 X
void disable_watch_dog(void)
/ \. J# |0 h0 y. X3 `{8 _5 Q4 L& z7 `, l! Z; ~
WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可
# ~2 ]+ ?- k1 d- B- _}
1 ?) W; R# }+ m
. k3 C* q$ V7 x#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))& B0 ?* {( { z. Y; ~) w) g
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))* D- \8 f5 n0 b7 L; ]- R" h
/*4 y7 l4 ^! o5 {( C. \3 Y
* 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV
5 I" ]. |* X! u7 l s* 有如下计算公式:" d% C' [; l# Z4 p% _, Y; M
* S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
, b. z2 M; ^8 h! f* S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
' K- L( a# w$ W* 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV$ v: [: J' g7 H- L, e% b
* 对于本开发板,Fin = 12MHz4 R9 U+ |, t8 h5 X
* 设置CLKDIVN,令分频比为:FCLK:HCLK CLK=1:2:4,. Z, C% w% K A2 V; P
* FCLK=200MHz,HCLK=100MHz,PCLK=50MHz. {+ y) Q- c; C- f( n
*/! ~9 F0 m4 R$ t+ q/ N
void clock_init(void)7 i- |' m6 D0 {6 _, v) R+ I
{
0 B# b: o/ P/ V* o0 P9 ?9 ]8 S // LOCKTIME = 0x00ffffff; // 使用默认值即可
5 d+ K- w, K8 L6 A, }- l; K6 \ CLKDIVN = 0x03; // FCLK:HCLK CLK=1:2:4, HDIVN=1,PDIVN=1$ G# N2 o$ I! \/ S0 ?8 Z2 d
4 G0 h4 o+ L% |& `
/* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */; a* W6 p% @0 d0 p* T- H
__asm__(3 ^- J; `( ]3 d, N2 }
"mrc p15, 0, r1, c1, c0, 0\n" /* 读出控制寄存器 */
3 _& L" f$ {9 O V. Y7 C "orr r1, r1, #0xc0000000\n" /* 设置为“asynchronous bus mode” */
" [0 L K: ~! x4 b+ W% ^ "mcr p15, 0, r1, c1, c0, 0\n" /* 写入控制寄存器 */$ `, H! V2 r% `0 E0 U7 Y
);
- W9 a2 U/ G% d$ O/ v0 |1 M3 J. a0 U' ~* F# q
/* 判断是S3C2410还是S3C2440 */
. W9 Q) P5 m9 d' t }2 P if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))1 d4 {; S: p- D7 O" l$ I
{ Y- @$ G* V4 i9 |0 f
MPLLCON = S3C2410_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */: N( @4 p6 \6 F1 L" R6 A
}
2 V0 b* a- `2 r0 S e8 r else
. E6 x% z( v- A; J* T" g9 j {( s# t9 S& o& B9 Q
MPLLCON = S3C2440_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */* Q. ?: y: i$ x& G3 a0 f4 |
}
& u) n* B8 D' u5 N% u) g}
7 l6 K/ C+ U1 V, _
5 T" j$ d3 v) w J. z% i/*
: e( \& g6 G* u B+ y$ o* 设置存储控制器以使用SDRAM
, f: b, l5 o, ]( F*/! }- @7 d/ ~9 w- {5 ^! c3 ]( Q( ?
void memsetup(void)
6 n' \5 {8 t- ?2 f, Q{
9 r3 d! X7 z: y6 r volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
1 F, s6 N0 {- t4 E% V1 Z7 z# n3 t9 N: f; Q" T
/* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值
) G, b1 s7 O/ N3 i- Y. | * 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到; i( y4 |% ]$ x) ?4 P
* SDRAM之前就可以在steppingstone中运行
% F+ s' U* H" g/ _' U */8 f$ V* o, [( Q, E& H) S
/* 存储控制器13个寄存器的值 */: X$ P$ ^8 `$ \. R' J/ {
p[0] = 0x22011110; //BWSCON9 D5 ?/ N/ X, U2 s& W$ o
p[1] = 0x00000700; //BANKCON06 b4 \- h- f& L
p[2] = 0x00000700; //BANKCON1
# L" U* b1 R: w( C' U- f8 q p[3] = 0x00000700; //BANKCON2" K( x6 ]1 h$ D- [! H6 M: J
p[4] = 0x00000700; //BANKCON3 $ A O; A! i. i1 w$ F9 e
p[5] = 0x00000700; //BANKCON4
0 I* Q0 v3 W1 b3 X- q$ ^ p[6] = 0x00000700; //BANKCON5
. M- c" O& m; I2 }( V* c p[7] = 0x00018005; //BANKCON6! {( q7 u7 I/ m: V
p[8] = 0x00018005; //BANKCON7
4 R* f: y7 d& t- A7 x8 k G5 Q9 y5 U) P : v2 Q' i4 J- q; B! h
/* REFRESH,* `& G/ K; ?. C* c- p+ C8 x' d+ y
* HCLK=12MHz: 0x008C07A3,* H( J8 a, B* i$ g4 ?7 L! _5 M
* HCLK=100MHz: 0x008C04F4
* {- i ^7 G" Z9 I" F( V */4 `5 a8 X$ m) c f% b- |9 R, F' ]
p[9] = 0x008C04F4;
5 o, t! E; A( E2 \/ y Z p[10] = 0x000000B1; //BANKSIZE
! \& }: P, G; C. ^) _/ X. |4 ? p[11] = 0x00000030; //MRSRB6) S; I& }) _, n; B2 J* a/ z1 G5 M
p[12] = 0x00000030; //MRSRB72 Z) |" C1 r( \
}
. {0 o2 Q9 `* Q+ b0 D9 X$ e
5 x7 Q0 ]7 D7 I2 n7 avoid copy_steppingstone_to_sdram(void); I$ B t) q3 r, L) Q: ^; u0 U
{* K" l: H. f2 K7 _
unsigned int *pdwSrc = (unsigned int *)0;
7 v: S; S0 g2 c. V/ f: _3 K unsigned int *pdwDest = (unsigned int *)0x30000000;/ z g! I" ?( [5 b. [/ Z
! g2 [3 |, U( [9 t/ `* N t, E
while (pdwSrc < (unsigned int *)4096), o# b7 K2 r+ X- \; I3 ]* N
{
( r" e9 q# R1 N+ c1 `3 k5 v& U *pdwDest = *pdwSrc;1 e4 h- Y% f3 |
pdwDest++;
8 w2 e9 \ M/ g* a9 C pdwSrc++;
0 |0 B5 K" j9 F9 m, ]* Q3 r$ @ }
9 B: i( f3 I3 ~( e}) f: P% L1 P6 }1 Z
+ G' N; r. y6 A& |- }/ j& O/ z5 P$ h2 w
3.uart.c
2 f/ E8 Y* B7 z#include "s3c24xx.h"# t; W0 N6 J& D
#include "serial.h"/ t+ f! [5 d. o; V/ u
2 c8 ]. k% M" d$ D9 v* f. ]#define TXD0READY (1<<2)
$ O2 @: d W3 L& T v* d, A% i#define RXD0READY (1)6 D6 P! h1 ]- p! v6 L u7 ^9 l
9 {6 K; S; D5 I. f#define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz: {; w1 R) S4 @5 j" r
#define UART_CLK PCLK // UART0的时钟源设为PCLK
5 [8 T# P) Y( K+ P$ _, w/ k7 s#define UART_BAUD_RATE 115200 // 波特率
; z1 p/ i& x. ~$ X) B. ?#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
3 Q' f& ~+ Q m4 N5 U7 j, y. v( ~: N
/*6 {. W$ j4 {0 H) f' t9 G1 M q
* 初始化UART0
$ W, k% }/ [& `7 \6 w* C* |* 115200,8N1,无流控) a0 {: O% k Y- }3 M- n
*/
* f, X" m+ t) l7 A) dvoid uart0_init(void). X* k( `: z0 c2 A
{
! ?% |# G, V# J, x- F6 M. P2 ~& |1 W1 C GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD04 X' k5 I; f8 c) v. j0 W6 v
GPHUP = 0x0c; // GPH2,GPH3内部上拉3 R% \9 s+ O( ~9 p$ m9 g9 f; o
1 t3 l& p9 ?7 @0 m4 J ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)3 \/ D8 c, @: V& q* o( G$ P
UCON0 = 0x05; // 查询方式,UART时钟源为PCLK" `! P4 r5 v: m
UFCON0 = 0x00; // 不使用FIFO
. f1 ` X2 q% L/ J3 \2 { UMCON0 = 0x00; // 不使用流控" _; x/ `7 [+ u1 L% E3 A4 T
UBRDIV0 = UART_BRD; // 波特率为115200
/ q& i2 H- N8 R/ l: f( \$ N( F}
9 P/ d& @* I d9 R. h' P+ d7 K J5 X2 L( F9 w- ]
/*$ ^2 D1 O/ z" Q" p3 D- y- Y# d4 W
* 发送一个字符, }' C8 x% k& z5 g3 q5 t& t
*/( b* `8 _' d0 ?- a N
void putc(unsigned char c)
$ j! f8 R6 x5 ~* X6 G{$ V; @: E- c7 k" C- w. j1 E
/* 等待,直到发送缓冲区中的数据已经全部发送出去 */5 A+ Y( Z& W4 W4 ~$ F: T
while (!(UTRSTAT0 & TXD0READY));2 j* v! Y- [, L, P3 p! O! S5 o! g3 E
+ R; w5 ~! S6 g- N3 U# S
/* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
0 \! E" F6 J; ] UTXH0 = c;7 d/ j( h" }8 g
}1 x* ^5 T( y! C% s
7 e5 h% Q6 g4 }# Q" ?/*( E1 w# A7 o2 R H! E. l
* 接收字符( _% [: Y d- l
*/
! w5 v6 M4 R! _3 Wunsigned char getc(void)9 M& A! L( m3 \7 V$ n4 m
{/ |- r+ l6 u; J1 ^% }0 O `
/* 等待,直到接收缓冲区中的有数据 */4 o I3 a7 a; d9 H- n. C" m
while (!(UTRSTAT0 & RXD0READY));
- D/ v* R# t+ }0 U6 n1 Y \ 4 J; P/ M# w1 i% R% ^' Q
/* 直接读取URXH0寄存器,即可获得接收到的数据 */
4 `( m7 D5 c9 V( e return URXH0;
" J, E0 }& V1 i6 r: `& W8 R}- @1 C* L* ]$ g
: c9 q j$ i2 Z- l; c; C5 k/*
9 W* C( J$ ^8 z T2 q4 i! {* 判断一个字符是否数字
$ Y7 o9 U! t6 h$ b*/4 q [3 m% c% g0 i/ T# @' D2 @
int isDigit(unsigned char c). {' u( F- k8 C: w2 T* C
{7 ?6 g+ a, J) ^) \
if (c >= '0' && c <= '9')* O2 K& G( r/ u
return 1;
& Y9 n& o! R9 g$ y1 ?! e4 J else# b. }5 x: G$ y; p" x: r4 _% a
return 0; 0 K( y* N5 p6 {8 p6 t+ o
}9 j7 n7 d& I6 X
2 M% E+ ]( P1 z4 ~/ E& X( ?0 l
/*
/ l! M6 X* u; @* f! t! g+ [1 r* 判断一个字符是否英文字母7 b9 o) d7 P, z7 @. o
*/
9 m7 F; S: j" Cint isLetter(unsigned char c)/ g8 F* }4 p' B3 [; O
{
. w* ?3 S+ H1 H& ?: Z if (c >= 'a' && c <= 'z')
& b: N7 z, g2 g; f0 f( h return 1;
) k( s; Q7 u5 u& {8 p2 }: f- T$ z else if (c >= 'A' && c <= 'Z')* S* k- D/ [: P! t
return 1; 1 F2 S T) K- {* a7 z, Z( e
else
4 `* j8 ]1 v$ O& f+ R return 0;
, s' `% o8 s# i}' \% h. ^/ R6 N
9 ]. Y; ~* d+ t' m$ _: { Z: G
: ^8 @; N x8 s1 Q/ j4.uart.lds
/ g8 S/ T8 J7 J4 w' y9 tSECTIONS {% k: ^* U9 H5 w L
. = 0x30000000;# \" p7 K" V; M
.text : { *(.text) }- }' T8 U7 x9 z9 e2 R
.rodata ALIGN(4) : {*(.rodata)}
/ Z" L/ ]1 t; S+ G `& _ .data ALIGN(4) : { *(.data) }
- J5 w5 f/ h: Z0 L- {$ o7 K7 l .bss ALIGN(4) : { *(.bss) *(COMMON) }
, Y* w5 J& j$ W}
. e* p' o" m ]) u5 k W
3 J2 L4 ]. r! X, k& ~, n0 x Y5.main.c
5 r& |5 H T* R9 L5 G#include "serial.h"
, c4 E: @: x2 \; ~! K9 J3 v/ F" y3 u# k
- m. [9 C+ O2 j8 E, lint main()! b4 c; q* R$ A4 G1 r
{2 N3 ]* L7 p0 U( a
unsigned char c;
/ A: z7 n p6 A3 M# T uart0_init(); // 波特率115200,8N1(8个数据位,无校验位,1个停止位)% q8 J! a( e5 Q4 F
/ v) P/ s9 k' W: J) @+ ~$ ?1 x
while(1)& H$ \/ k5 v: J+ I6 L/ _
{
( _8 A0 [: A- z* t+ h: ] // 从串口接收数据后,判断其是否数字或子母,若是则加1后输出
4 U. Q8 [, _; [0 w. U4 L8 y z" m c = getc();
' B, W) M9 A* z& x$ Z0 n if (isDigit(c) || isLetter(c))
% C5 A- e% N5 e& C; k! Y. G' } putc(c+1);& B/ _. n" Y/ C- e3 N! n
}
. x. I) E# J3 @8 g4 V; t* s8 K
& I% N- ]# @" s- f5 g. x! Q return 0;$ w& ]3 R$ _0 {/ |
}) A5 a3 |8 m) x" K& s! y: h
1 f4 K- a0 n9 ]. s/ S- _
( v, q3 X! s/ O& }6.Makefile
2 o0 n* g, ]) i: K! Vobjs := head.o init.o serial.o main.o& ?5 s& ?8 \& B) j. D
r% t9 |, u$ K! c
uart.bin: $(objs)+ @ B, B7 H4 f. b+ P
ARM-linux-ld -Tuart.lds -o uart_elf $^; d$ ?! N( r% S* l
arm-linux-objcopy -O binary -S uart_elf $@5 N+ L/ b' C4 s' B
arm-linux-objdump -D -m arm uart_elf > uart.dis
1 F! D0 k& M/ N" \' G
7 p6 _" B7 [6 j; B; p1 D. d%.o:%.c0 O( _8 a! Z; C6 r$ p) t
arm-linux-gcc -Wall -O2 -c -o $@ $<+ }6 L% d/ V5 D/ Z8 `1 \ s
0 q i2 \- @& ~5 C1 r4 t2 E
%.o:%.S$ o9 {7 s* L: N. F
arm-linux-gcc -Wall -O2 -c -o $@ $<
( r3 t$ Q+ c7 M' C3 j; L9 ?
|5 I- o( {6 H# Q, n8 `0 @0 `" lclean:
! Z* \) }& g/ K5 M5 H2 A rm -f uart.bin uart_elf uart.dis *.o | ( n. a9 ]- D2 [3 b( X- V& t1 ?5 ]' i
6 b- L. i. p7 b1 \8 x( ]% {& T! |+ \; U! B5 _
|
|