|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
我使用gcc编译,但只能生成,o文件,无法生成.bin文件,什么原因
2 w, t8 g8 M4 {: z* c* _.head.s$ \; ^# s* l+ L: W6 U8 F& b
) F( J: @7 _3 i l
@******************************************************************************# ]/ p7 r- [+ k& `6 ?
@ File:head.S
8 P, @" W4 V' z4 N@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
' m9 O. e( l, J w Y- ?( j% |, |7 x@******************************************************************************
" w5 @4 I/ J& w1 P8 A . {: F/ K& i* T. x
.extern main' c2 [ a0 L$ o% f( k6 E$ ]
.text7 T+ }* u0 H5 k& }
.global _start
( e6 `8 O3 O J4 g_start:. V+ u% R4 D3 n0 v" H& X! M- {
Reset:
. _& }% v5 Y" ~# c% s3 D ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈0 G0 P& `7 ]$ S$ j9 ~ ]
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
) L4 j# E6 W& s+ o // bl是位置无关码,相当于:PCnew = PC + 偏移# w! y l& S `2 V
// PCnew = (4+8) + 0x28 = 0x34
% L6 ?& A9 y. S3 j ! E' M* O& C" |) l4 ^7 S, A
ldr pc, =disable_watch_dog) T5 S0 Q6 q' R/ I7 W' T
2 y. ~! g! f2 ^6 Q! l5 x7 S5 E4 H
bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK/ Z( z, d6 L! Q# |
bl memsetup @ 设置存储控制器以使用SDRAM
" A# e. |4 r# k3 `, g: t, O bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
4 }% S; x: j1 m6 t ldr pc, =on_sdram @ 跳到SDRAM中继续执行) Y Y1 e- R8 e: x: O0 g
on_sdram:
+ Q1 ], G8 p& h0 U ldr sp, =0x34000000 @ 设置栈指针
\4 z! I1 y2 @8 z ldr lr, =halt_loop @ 设置返回地址
3 D* F+ y, j* Q3 r* s ldr pc, =main @ 调用main函数; ?" N. d0 e D6 r* e" \, l# Z
halt_loop:
: c W1 A5 Q! j! c9 l b halt_loop4 S) |" A9 v' C3 ^
* f' h1 f8 L( t! ~5 N
2.init.c1 r( A, T+ o, V+ B) \& H# |2 t
/*) W+ H5 U2 P: O: C6 z) p
* init.c: 进行一些初始化
; B. Q5 ]3 N7 k& M1 s*/
% e" S& d. E; W0 G7 p" [) ]2 K. G' ^: a3 I' l
#include "s3c24xx.h"
/ e8 I- H; C# y2 w" K/ h
5 w7 _9 j' w+ H# q Pvoid disable_watch_dog(void);
; o* ~ a1 a8 [3 I% Dvoid clock_init(void);
, W/ j( _$ L5 q4 z) [4 S6 ?2 U( O$ qvoid memsetup(void);
1 I. `; o6 d3 ^1 I7 Mvoid copy_steppingstone_to_sdram(void);) l! c9 p% F% m) z
- L! F. r& M% j( z; ?% P/*% |0 D, x( A' G: e4 Q
* 关闭WATCHDOG,否则CPU会不断重启
$ G2 ]% o2 n" N*/+ y' r) v: \, E) R
void disable_watch_dog(void)
$ t: ], M5 s) S* B9 A* ]9 L{+ P( ]; R* y% l& T
WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可/ X4 s- w% H$ F# e2 }, E) B7 _% h
}' y3 \# p+ t, Y! ~/ a
3 l. u$ n Z2 V+ c' u1 w
#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))
) R/ o) u1 h1 S#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
) j: m6 _0 V5 ~/*
: u# O8 }- A E( p0 T1 E* 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV
# \- b s4 w5 W: k6 F0 Z$ `* 有如下计算公式:
6 e- v, N- g3 u* S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
( k" d' A4 O2 w. x9 B5 {* S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)/ w" v3 l& K$ i$ R# N
* 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
3 m1 _9 `+ x% P* 对于本开发板,Fin = 12MHz
# M/ ~5 R4 w& K s8 X! ?& ~* 设置CLKDIVN,令分频比为:FCLK:HCLK CLK=1:2:4,
3 B) u, e( X0 X' O! M% o5 J6 b, T* FCLK=200MHz,HCLK=100MHz,PCLK=50MHz1 I+ d- ^# o& l+ |9 y
*/' p1 P4 m2 r1 G1 w# Q* p7 U
void clock_init(void)
4 Z' l# a1 ~3 g( D1 a$ v{& L+ F* u$ M! i5 L) A) n
// LOCKTIME = 0x00ffffff; // 使用默认值即可
/ m& a. J2 s) f( K4 e' _1 O3 S CLKDIVN = 0x03; // FCLK:HCLK CLK=1:2:4, HDIVN=1,PDIVN=10 T6 a i- v' u
6 g1 f z/ X! w/ a7 y+ r
/* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
+ m7 h7 m! d8 s+ Z$ A( j+ c- k) n__asm__(5 Z' k7 `7 m. @- Q
"mrc p15, 0, r1, c1, c0, 0\n" /* 读出控制寄存器 */% M" w' k2 K% I/ F$ [6 j; N
"orr r1, r1, #0xc0000000\n" /* 设置为“asynchronous bus mode” */
; ~- T+ l( \, E& f! x "mcr p15, 0, r1, c1, c0, 0\n" /* 写入控制寄存器 */% }4 R; F$ P5 w# y
);
1 Y. Y* b' |/ N, W7 B3 c8 f
4 |, V3 x( j7 l) u- b /* 判断是S3C2410还是S3C2440 */
: t/ E; N+ d- ~. Q7 q! ^: b if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))0 k4 b4 a7 \0 L2 b9 z
{
7 `& _/ V8 h3 z4 G: m; q$ W MPLLCON = S3C2410_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */( k5 \- j) ^3 p- P4 j* ^
}! p9 B: I1 r. ~
else
# X. c* I! C) _9 P* B { g8 \- R+ K" u: C p. w3 Y' Z) d
MPLLCON = S3C2440_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */ a, e( H* t/ W
} ! [9 @+ s7 p: S1 f% o( U* e
}
/ y, J n9 `! Z; N( _# |$ ?
, k* ]0 J' O- N5 B" b/*
8 ?* _4 y, a) b( U$ u. U- n* 设置存储控制器以使用SDRAM" D1 Z$ C/ A Z) o/ Y5 `
*/1 [; d* H, o: f! p- _, f
void memsetup(void)
+ K/ A5 ^$ v, ]0 u z{
9 ]$ `. ]- R6 j9 V3 U9 G& O6 E& n volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
9 H4 {, J! M" X& I9 e, v, v+ h v4 O+ y) g
/* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值& Y. ?# M. z% W! q% n
* 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到1 L7 [* ^3 Q: f; L. F+ b) ]
* SDRAM之前就可以在steppingstone中运行2 w. E" E- s" h0 J' t
*/
" v8 z: c: l- Z* }; M5 s0 A( M /* 存储控制器13个寄存器的值 */ ~, v8 f4 @. _1 _+ f; k+ a! H
p[0] = 0x22011110; //BWSCON
; {( H% K$ a- f4 ]0 f; f' P p[1] = 0x00000700; //BANKCON0+ [8 u4 U& U; b' m1 R7 w+ P3 A
p[2] = 0x00000700; //BANKCON1
& @6 l' f. L# I p[3] = 0x00000700; //BANKCON2( _) |- u4 j" F; ]* {; y' h+ S
p[4] = 0x00000700; //BANKCON3
. ]' |: D, v2 P! ^6 S) `, B9 _ p[5] = 0x00000700; //BANKCON4: C$ o8 q, \+ D
p[6] = 0x00000700; //BANKCON5
# Q+ I1 @+ L Q6 W p[7] = 0x00018005; //BANKCON6
2 m% d% p3 |/ q& n p[8] = 0x00018005; //BANKCON7
4 l' e9 ~9 K9 L8 i/ B" t1 C+ e
# ~( ?5 r. u9 X y5 m /* REFRESH,
$ }- z& d; {$ H' U" g' V# ? * HCLK=12MHz: 0x008C07A3,0 `: V/ ^7 ~( ^( W! U& z
* HCLK=100MHz: 0x008C04F4/ c6 a8 Z2 o4 n& ~ x8 H U
*/0 ~, H# i; k" b' D
p[9] = 0x008C04F4;
* J. \3 X0 D. T6 |- q p[10] = 0x000000B1; //BANKSIZE! U3 f+ D6 I7 \, g
p[11] = 0x00000030; //MRSRB6
) @1 ^4 u$ c' m$ G9 \ p[12] = 0x00000030; //MRSRB7
* a& F7 V2 m) }" w5 d1 I0 L}
2 f3 P+ M8 _3 o! J' g" f& y
, ]/ I2 U9 w4 l6 q; X+ zvoid copy_steppingstone_to_sdram(void)
) D& l1 _" q; V" W* V" w* }{
) ?! e1 w2 p0 m+ }5 Y- I unsigned int *pdwSrc = (unsigned int *)0;# o. W ?0 k; \6 h& C
unsigned int *pdwDest = (unsigned int *)0x30000000; b6 I( t( e9 D4 y) k, w8 \0 r
+ o* z; {' ^9 z" o7 x# h; t while (pdwSrc < (unsigned int *)4096)9 F, M, w5 _+ x& ^
{
+ q0 i4 u h" t5 ~2 Z6 ]; o *pdwDest = *pdwSrc;
* _$ ]7 Q$ P3 U' |( o) x! A8 L pdwDest++;: e8 g* J: v' A. H) [0 e* l F
pdwSrc++;
2 d& T* D0 n' ~* n! u }0 o: |' n, P, Z
}
" ]5 ^' `/ c7 s
8 \1 D* I) z! d) x0 _: s) c3.uart.c
- f' P* Y* F# s1 [* E$ t#include "s3c24xx.h"; j# A N1 g( d
#include "serial.h"
. y- j# A- @' C# g0 D- W" y. E- j% B. f% x; j K
#define TXD0READY (1<<2)+ t3 h' H r& {
#define RXD0READY (1)
% N/ g$ j7 L( W( @# n' Z! S7 B, d, A. c/ \& Q1 A/ g0 U2 S1 v
#define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz9 ~6 ?, m8 \/ a7 l$ V
#define UART_CLK PCLK // UART0的时钟源设为PCLK
& s5 u# |& z, ]' j+ j$ L0 l# I#define UART_BAUD_RATE 115200 // 波特率
9 H6 x3 g5 ~5 o8 v- t#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
9 W/ U& V" P3 R( x+ e% Q0 @. j
; s0 r* x8 z R2 v- y/ V u* H/*
- e' _6 k. E a7 J* 初始化UART0
) {, {. @7 X# ~& d# I8 {. T+ t* 115200,8N1,无流控
7 U, \9 N" R- H5 _*/6 p& o3 w: |1 k7 W7 f
void uart0_init(void)
' G9 ?3 @$ a! ?! l6 d# K{
& X) U4 o. J" S* m- q& _ GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0' [. }' ^, N1 d0 ?& y: b
GPHUP = 0x0c; // GPH2,GPH3内部上拉0 |; X: {/ S( ~
5 P7 `. P, x- |+ @
ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)
4 l2 x) Z. z1 b$ M- X5 g) K) o UCON0 = 0x05; // 查询方式,UART时钟源为PCLK
- h, `( v6 B9 q9 ` UFCON0 = 0x00; // 不使用FIFO: m- I; ]* ^# E, M8 J& h- E
UMCON0 = 0x00; // 不使用流控
% l. r: v7 c2 _8 s UBRDIV0 = UART_BRD; // 波特率为115200
& F* [& N& |( b; E4 ~# C* j3 p& ]}4 M4 ?+ F6 F4 o9 w
! H% l* z0 Y/ J s% q4 W! X
/*
2 Z5 f0 c! E8 ~* 发送一个字符* E8 l& j! J5 h" D L; [& z
*/$ h7 \7 i' r/ w4 M9 E0 `
void putc(unsigned char c)! k1 L; G: K k z" B5 m8 }
{
' c+ J& G9 c) f; w /* 等待,直到发送缓冲区中的数据已经全部发送出去 */
' X* m' R) l* Y+ C while (!(UTRSTAT0 & TXD0READY));/ ` g3 _ ?; g
5 e, F V% u4 T3 H( ^; Y /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */3 I' M) S0 b' N2 L
UTXH0 = c;4 K2 |7 d, V) \( @6 m E: u6 ^
}
8 `- [, d s k* I) X+ @
' U3 p" H# h d1 a1 U4 Y: b0 C% C/*- ^: O8 {9 Y e! ]' S: m
* 接收字符
* [7 J! K& D! f! b- {1 u8 n" e' T n*/
: F/ Y4 c2 r4 Q, F% l$ U2 h/ v1 _unsigned char getc(void)+ P; B; l+ a- \) k- F+ m
{
& F- Z% q' [/ b( i3 i /* 等待,直到接收缓冲区中的有数据 */
5 G0 v% k0 y3 r- ?/ ]# f) z9 B' ^ while (!(UTRSTAT0 & RXD0READY));
8 ~) `5 t" N9 m( J% C" o
2 v/ C4 P9 |1 d# T /* 直接读取URXH0寄存器,即可获得接收到的数据 */" ?( e* W3 m5 x4 J4 i V
return URXH0;" W$ L" h+ h6 ?; b9 Y1 O& _" A- G1 V
}* D F3 b$ y" z' C
$ N5 S" ~# f: T/*
% l7 ^% d1 g# `2 P* 判断一个字符是否数字
: U/ F- y' C1 ?*/
6 l, v& w% S2 T1 K% Dint isDigit(unsigned char c)
, \% V. V0 L) Z& @( {( Y{
0 Y7 i5 u( I0 U& o6 b r if (c >= '0' && c <= '9')
: b4 a1 H! B1 A e# @7 y( d return 1;/ \$ j4 G, L6 Q* D/ D% @
else/ C# Y* w8 M/ e3 I
return 0;
! ~3 G$ b; Z6 C}& V( N4 g4 _* G( w
, ?' ~0 F1 f: }8 p$ ^/*$ B4 t* E+ `+ I( {: ?
* 判断一个字符是否英文字母) D& V% w: { K8 B
*/
) R6 k! e8 r1 C( d7 t& Qint isLetter(unsigned char c)
. p1 c! P# Y* ~{- Z' K1 M l/ N3 \3 l
if (c >= 'a' && c <= 'z')0 r! C, K; K, e2 B( q
return 1;
) _- Y0 |% Q# t7 l else if (c >= 'A' && c <= 'Z')
3 M6 M K( N0 D. P/ i) n3 d return 1;
/ _3 S9 D1 B$ |; k. I: { else
& c1 z* D0 B8 @' J, x: j& x* \ return 0;1 Q2 U! A' o" x T
}
2 Y9 k ?/ B" F8 q- i1 S/ B) |6 V9 ?3 o9 @/ M! X9 l& U5 M
I3 i H0 g5 X3 m( h2 I* \
4.uart.lds) H, B/ }5 x6 T, f5 I7 B0 g
SECTIONS {9 i9 b( ~' p9 V; n
. = 0x30000000;( f5 ]2 r3 k5 I; A: e
.text : { *(.text) }" [8 d7 R ]! N6 Y
.rodata ALIGN(4) : {*(.rodata)}, B7 W: v& c' o
.data ALIGN(4) : { *(.data) }+ x% K: |; o. W/ a$ c) l4 b1 c+ @
.bss ALIGN(4) : { *(.bss) *(COMMON) }
6 t7 N$ N' V0 |% h8 l}
$ m: m/ v& m( W! o) v5 ?
" Z/ h2 Q8 g# k7 F% E. `1 S1 K5.main.c
3 b: j( G$ C, Z9 }#include "serial.h"
/ A! s6 t4 n* E9 z
1 _0 B# t6 s, X/ E; z* gint main()
, p2 ]3 g2 N5 v, O! P{$ `: u! K. h8 U; n; l& s/ q: R9 f% \( ?
unsigned char c;
7 ^2 W, C% D3 y1 x# W. X uart0_init(); // 波特率115200,8N1(8个数据位,无校验位,1个停止位)- H& M: m3 Q& }
/ v `9 [2 s* x8 _6 a. K
while(1)
3 F# j1 g' v$ h. y {) |$ O% ?0 @" ~2 y8 ^1 s1 d
// 从串口接收数据后,判断其是否数字或子母,若是则加1后输出! o8 d$ m& i& `* [
c = getc();6 H. H% K( c1 V
if (isDigit(c) || isLetter(c))
6 @/ P: p: v' u k2 D5 V w$ [/ x& | putc(c+1);
5 @& y8 T3 Z7 H4 L( B }
/ n. M, |# L8 F- g( I2 y& E
9 j. j) P" S7 D$ N return 0;
2 F: k8 o1 G6 f0 z! }}/ G5 j, s" \% S
& Z" l- X- y0 v2 n& d
3 }1 A8 z/ y; D, F. K1 P6.Makefile
% Q1 W/ b K/ s0 G Robjs := head.o init.o serial.o main.o4 {8 ?6 x: V" p( ?2 v1 t. O
& i3 D3 ^2 z' ~' W: {# l) s
uart.bin: $(objs)
1 H3 l0 |, q$ b0 \ ARM-linux-ld -Tuart.lds -o uart_elf $^2 N5 Y* l. a3 k
arm-linux-objcopy -O binary -S uart_elf $@ `& P; T9 \! i4 L9 ^9 Y
arm-linux-objdump -D -m arm uart_elf > uart.dis& e* D: E" i( l( f) C" Y
: x. b1 L5 k0 j6 u$ v; S+ T% H
%.o:%.c' ~5 u$ q' t8 @
arm-linux-gcc -Wall -O2 -c -o $@ $<
) p% Q, h+ W9 t: i5 v* K% q4 X; A. m; D4 \7 p
%.o:%.S
* j- V6 e3 @6 Z4 v; O1 e0 T, L arm-linux-gcc -Wall -O2 -c -o $@ $</ P. y, A! k& h- m7 D3 Y9 }
& o' R, Q2 Y2 ~1 V# Eclean:
. H2 W3 r: z2 K: b( M; \1 d2 I rm -f uart.bin uart_elf uart.dis *.o | : a& @% W7 C$ H9 S4 T. [8 \ K
. p/ m( V, B9 P* R2 i" \, }
6 O! C6 W$ A0 ?+ t7 S7 y$ P" | |
|