|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
我使用gcc编译,但只能生成,o文件,无法生成.bin文件,什么原因4 S5 n$ }- {( A7 }3 A
.head.s# J4 l9 {2 ?, k' d$ K. r
9 N% y, E9 E7 S' t% C
@******************************************************************************
* {2 P$ a# o6 P p2 f/ Q@ File:head.S4 z2 d. A( V7 g! e) ~
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行% @' L+ b4 |! ^
@****************************************************************************** 2 J- O& r v6 c9 d3 q
- r+ b0 v( d D- P% }* O4 p
.extern main1 U. ]% S0 i3 W# v+ k5 k& _
.text
! c; b, F% u! b3 i0 _$ q5 }.global _start
. }9 S4 v3 o( C/ |_start:. C$ W- P/ _4 G6 V3 Q
Reset: 0 a/ e; F+ |2 G& S" o% L- \
ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
9 I$ _& z/ m9 R/ i; C8 c bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
4 i! X$ ]6 L6 [8 h) n4 b1 ` // bl是位置无关码,相当于:PCnew = PC + 偏移& Y) N/ a4 G2 e$ V9 q- |
// PCnew = (4+8) + 0x28 = 0x34
( E0 t) w, `7 U5 e# K- K, y
4 X& @8 g; I/ ? _9 t- c ldr pc, =disable_watch_dog6 a; H0 F9 D* i5 K' d2 U
1 c( s4 }4 F# Q; N4 k" j& f1 @" Y o bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK
7 K O4 ?+ l$ d8 Y0 f bl memsetup @ 设置存储控制器以使用SDRAM
$ k5 w: q# [, _+ X' m. T4 u; L bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中2 M% E( ^: ]$ e- p& A n/ i
ldr pc, =on_sdram @ 跳到SDRAM中继续执行
+ h) \4 J+ {! v! Son_sdram:
8 T9 K) F/ ]; m8 Y9 M5 }# N' ? ldr sp, =0x34000000 @ 设置栈指针- D. S% e0 Z: ]0 [! h" d& m3 ?! Y
ldr lr, =halt_loop @ 设置返回地址* ~5 @# j( B# t _8 Y0 E! t
ldr pc, =main @ 调用main函数
4 C$ g4 W% H9 q# Thalt_loop:
7 x( U4 z6 X8 n$ c6 s Y7 c' V b halt_loop
$ [7 K- ]: O9 J& ?* e
1 r7 x1 J, C8 k+ G2.init.c
7 [1 w1 `' n$ d9 n7 d) Q& m7 i4 w" T/*
2 O D0 H5 [% l' h$ s* init.c: 进行一些初始化1 c; D$ [- ?1 W8 P W0 l% E
*/" O- X+ R3 f! k( @0 P% g3 n
' V' n3 Z! `; J4 ~' E! O6 N#include "s3c24xx.h"1 `" N4 H- o' v2 @ f* \8 f
/ X. o* ?2 C" j! r; E. ?
void disable_watch_dog(void);
" k5 X+ D+ d+ T( s9 m7 yvoid clock_init(void);2 y% P9 `" v3 e5 y5 J8 Y
void memsetup(void);7 G0 s0 c, n6 v4 h* T
void copy_steppingstone_to_sdram(void);2 N" `% M- G+ n/ q" S
! _7 @* b ?( |7 U" W
/*
* {' C. r4 W+ H* 关闭WATCHDOG,否则CPU会不断重启
/ p' x1 y6 v; Y4 W# \) J*/, u8 G* f6 H$ r6 S# C/ [4 Y6 h) Z
void disable_watch_dog(void)
2 A# e$ h" e: _ s$ O$ D{
' {3 x. g+ r) R5 X WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可9 Z9 s% B6 |( n6 L. y8 X
}
) u5 [7 X* @: U- a' a' i/ J l" Q# g3 ]6 x7 k
#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))
# g6 n7 C# I2 Z* h: u#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))8 V# ?) P1 L j/ i
/*( _4 G! c8 d# F3 T( c+ M/ r0 B' {
* 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV! N8 \; Z/ c* Q* h
* 有如下计算公式:
9 F2 E" c) P: _. H& y" J- L5 D. K* S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
" K+ m+ c% I) }9 k4 R* S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)9 V3 ?8 s+ ^7 s( R$ [
* 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
3 q0 k* Y" R6 {$ r" }5 o* 对于本开发板,Fin = 12MHz8 C3 A( I; k# T P& |+ V: D
* 设置CLKDIVN,令分频比为:FCLK:HCLK CLK=1:2:4,
( M+ \& i% y! o S; U* k- I: k5 o* FCLK=200MHz,HCLK=100MHz,PCLK=50MHz- f5 Q4 ^, H5 F2 K
*/6 N: g$ ~( H7 L: i
void clock_init(void)" j8 W" d# K0 f) @
{2 l4 M. x+ l1 P' x5 }% \- V
// LOCKTIME = 0x00ffffff; // 使用默认值即可
( H' F8 `2 |4 i) t K CLKDIVN = 0x03; // FCLK:HCLK CLK=1:2:4, HDIVN=1,PDIVN=1: g$ Z) U; ~* u, P6 V
! z" l G2 s( w8 ^! w' k7 C; F' O /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */" K- X9 }4 Z) p: K5 T _( \+ q
__asm__(
+ y7 z1 } s* U: P "mrc p15, 0, r1, c1, c0, 0\n" /* 读出控制寄存器 */5 \" e; t) G# S% v
"orr r1, r1, #0xc0000000\n" /* 设置为“asynchronous bus mode” */
& ` c- v/ \9 j8 Q- @ "mcr p15, 0, r1, c1, c0, 0\n" /* 写入控制寄存器 */
! \4 d: P/ q# m) s8 t% c9 ` );
. r7 P. [% T7 `! C3 Z9 Y, q. Z- Z% I4 [, V2 {. d( F8 i# V
/* 判断是S3C2410还是S3C2440 */
5 N& a( w$ L9 i if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))1 {% b: F( c3 G& _$ C. f4 n) B6 z4 Z
{
9 q. y2 z6 g: { MPLLCON = S3C2410_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
: l8 A0 t0 a+ ? }
$ T$ b O0 q: @; B/ M1 N else
" R3 ?/ @, M9 l* d2 Y- q+ `$ U5 | {1 J! K4 l* n: c9 V5 O
MPLLCON = S3C2440_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */' ~3 @) D( H$ h; _; h/ w6 y
}
% G% ], G( |$ G' ~; [4 R# h}
. q- c8 O$ _4 K, o2 `
* D/ ?* R( w) ^( A* y) Q B/*
0 K. c/ V) |6 ~( Z! y3 `* 设置存储控制器以使用SDRAM0 l! w' y& t% g7 c/ A7 G
*/
5 S2 Q$ A$ F& {2 H& [void memsetup(void)
5 S% o* N2 F5 t5 i* c' p( l{
( r2 b# d. W6 F volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;+ A1 d+ p$ J$ R" x0 Q
7 y/ L; X2 W$ O: \3 t" s /* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值! {$ h3 d$ V$ ]% `' B8 g) `
* 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到
; Y3 z& J2 m7 a9 A * SDRAM之前就可以在steppingstone中运行
' s# k( O4 p9 h& d */) O) W1 q0 g# O
/* 存储控制器13个寄存器的值 */
2 }, r! F2 k4 \ a# [9 |3 l p[0] = 0x22011110; //BWSCON
. C+ A- ?# S7 ]+ ]+ y i p[1] = 0x00000700; //BANKCON08 }2 ?* @1 B* i# ~
p[2] = 0x00000700; //BANKCON1$ H: I+ U% q. b
p[3] = 0x00000700; //BANKCON2, x) l) e1 w! k+ u8 h0 V
p[4] = 0x00000700; //BANKCON3 h0 e0 d4 \) b3 r& d( P: V' ^
p[5] = 0x00000700; //BANKCON4
' s, l: J$ y- d p[6] = 0x00000700; //BANKCON5
- D8 z1 w% k! S p[7] = 0x00018005; //BANKCON69 f; L, j+ i6 U9 T: I7 n
p[8] = 0x00018005; //BANKCON78 w+ v9 N+ h. c3 z9 ^5 f
; t) R; [7 w: T8 n# C /* REFRESH,' |/ ~7 j" e( A B. ?* t$ S
* HCLK=12MHz: 0x008C07A3,5 `$ M9 t/ c9 e4 d, T p. m
* HCLK=100MHz: 0x008C04F4) y3 s' c8 s6 Z, L) F
*/
8 l% A" \" A" ~% c1 F p[9] = 0x008C04F4;! R% |4 U' q/ M6 S0 C/ k$ q( _
p[10] = 0x000000B1; //BANKSIZE
3 j0 D& g3 B: J a/ U K p[11] = 0x00000030; //MRSRB6% _! v0 E+ V, ^8 w
p[12] = 0x00000030; //MRSRB71 M) p" n5 |- m1 d- x
}
% F& q8 v W2 J( P8 W
" `' y* ]+ O1 Q2 S9 e3 w4 ?void copy_steppingstone_to_sdram(void)- O1 O4 `+ E% B6 t, }7 u
{5 b& }: m8 k+ S H
unsigned int *pdwSrc = (unsigned int *)0;
- }" g" t1 X( U unsigned int *pdwDest = (unsigned int *)0x30000000;
3 @0 }7 [( B3 c6 e+ w* r8 s - U" T+ j" q/ D: K1 ~* i
while (pdwSrc < (unsigned int *)4096)
) ?! S, ]+ X% x- ~! Y% x+ B$ n5 A {
" a5 U& K/ V/ a" t+ S' ] *pdwDest = *pdwSrc;! S8 n& ~& A+ Y' a- q7 d- B
pdwDest++;! L# [" C O m$ Z8 H5 w
pdwSrc++; Q3 g% |; |$ V V
}) F4 E0 \$ o! j. p6 ?5 K
}
" H( @- U, U9 o; x# }2 D) h
+ Y0 ]' P, d; G2 u3.uart.c0 g8 ^4 J( [6 N3 Y8 Z2 S
#include "s3c24xx.h"
. _( \- q+ O& p& s#include "serial.h"! H7 ]: P# b q- p. O
# i! m2 |4 z# T0 j#define TXD0READY (1<<2)2 g- I$ ?0 U- u6 t& z* T! r' ^
#define RXD0READY (1)0 |& i7 U; Y. ]$ r; O) C1 @! S9 }
* r; d& e. T, ?7 J#define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz
9 O( {' c# c: X, o' E8 i# f/ [#define UART_CLK PCLK // UART0的时钟源设为PCLK
- l& j0 n7 k1 r#define UART_BAUD_RATE 115200 // 波特率
# [, K$ C! I* f4 f# A( P' F#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
& U) _4 F+ {$ N& v7 L0 n
" R5 J2 y4 W; ~/*
, y6 s& @# s% i- r* 初始化UART0, |0 m5 T( g5 X5 X8 h# A
* 115200,8N1,无流控
6 S7 f6 H# p3 {7 d*/
2 Q, {9 a& P3 Q* vvoid uart0_init(void)8 E$ `: p4 Z2 C6 W2 a$ ^( L
{" ]; f3 p v# j) {0 t+ g
GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
6 w9 y* _, {% b7 z! K GPHUP = 0x0c; // GPH2,GPH3内部上拉
) T/ o$ f+ w6 v7 i; }) z( s" w5 Q+ Y( r: u$ I0 m2 S
ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)* H+ E0 o; H) ~" y7 N+ p) Q% z
UCON0 = 0x05; // 查询方式,UART时钟源为PCLK
! C/ x$ P7 T% |1 \. \) Q UFCON0 = 0x00; // 不使用FIFO: e! C4 o9 s) X
UMCON0 = 0x00; // 不使用流控
* }! ^ S& C3 r( `% O) j, T UBRDIV0 = UART_BRD; // 波特率为115200$ |- }3 d, M, s' W# @
}6 d, R. c" }! b) g& b4 v3 g1 T
9 C/ \% d* Q- |. O3 Q
/*
0 v2 X; [# B( W* 发送一个字符
6 V9 C* |. ^1 _* ]5 Z) U2 g*/' y, R5 K2 G- o: f; o
void putc(unsigned char c)
/ }8 Z: j6 i. K+ A{
5 b& J+ C. d4 B( b1 n /* 等待,直到发送缓冲区中的数据已经全部发送出去 */
" c7 a9 l6 ^2 A while (!(UTRSTAT0 & TXD0READY));# |# o n( K% U: k; P1 g% k
! g L0 c7 {4 J" P6 p9 x; {. m
/* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
0 n$ ~" F9 y& G- N; Z! n UTXH0 = c;
; o+ o# M; N! D$ t$ y2 O. b}
8 ?, V( f" s- h, Y) f }0 x# P4 ~" q$ Q& t3 C6 c7 G
/*# B+ _/ K x s( H( Q/ U: b' W8 i
* 接收字符
8 ~# X' C* L$ v2 n, f8 Z. }*/
0 ]& r2 E8 W6 y1 y. Nunsigned char getc(void)9 T( d* {0 Q' H" g
{
/ d. [ S0 d" z; {# z5 z /* 等待,直到接收缓冲区中的有数据 */
9 c: e3 y1 V- V9 N& ~" [ while (!(UTRSTAT0 & RXD0READY));+ c2 I0 T V# ?' x1 `
Y: E- ]) A$ H: {- X
/* 直接读取URXH0寄存器,即可获得接收到的数据 */" w$ X! W3 _3 i3 S
return URXH0;
% w6 Z, e2 X' X7 B}' G7 A9 g$ K! F
% i$ v( ^6 n3 N/*
8 a% X$ Z3 i8 O, l. ?# X) H( k* 判断一个字符是否数字% j# Q: L- p4 {
*/0 |% @: i1 j6 C
int isDigit(unsigned char c)9 } f# n! O6 T: |( e6 X
{7 C4 ]3 X5 K! }
if (c >= '0' && c <= '9')" r! c, z/ M4 u% n6 }
return 1;( n2 r7 ^/ U" M* e
else \8 B8 B& Z+ Q) ]
return 0;
; ]# U6 \! ^' D: T& t1 ] n5 r; n& @) `}
( z. a+ T+ V9 p( t6 e& ~; r* I$ s# g" [' H* A: o# @
/*% `. D: { S6 D7 G. g" M
* 判断一个字符是否英文字母+ M% A- t, v+ K
*/
+ A: r7 E8 j, D; }int isLetter(unsigned char c)( N2 t3 U4 @; C6 v8 E
{
5 e' n: X. ?) c! X- z3 U8 P if (c >= 'a' && c <= 'z')
2 q2 |0 M$ r$ M* e5 N6 A return 1;& [* D/ g+ o$ w" s6 }. k
else if (c >= 'A' && c <= 'Z')
3 y% d! y5 J& u) r return 1;
/ @% I z1 g# l. w6 T$ v else
( \5 q; ^7 e. z2 i( @3 P- h+ x return 0;
+ N {5 C) r" s6 V# y}% w3 M0 _& j7 q3 I5 D
) G" [; S, j& a: v
/ e4 v; s1 C% S- n# x" Q1 L4.uart.lds
5 @. e( H9 o9 U7 j, RSECTIONS {" \9 O! Q* D' s6 n7 l! S/ k
. = 0x30000000;; p6 W9 |5 ]* u) d9 w/ W% [& ?
.text : { *(.text) }
6 a( s$ m! _$ p( U. b .rodata ALIGN(4) : {*(.rodata)}& ?9 x( \- J% p
.data ALIGN(4) : { *(.data) }7 R: g% i. @ E$ I; h2 y% W7 d
.bss ALIGN(4) : { *(.bss) *(COMMON) }
+ v% ]9 S2 Z' v: U0 V6 |9 ^+ G}
' O7 x, D$ h- o! X* i, _9 B% N6 G" G- y% a h
5.main.c W) [- ?' z9 U0 B8 h' h) ?
#include "serial.h"' `! a8 M- p* E- ^6 A
+ g: e4 q- Y7 y! eint main()
$ a$ K/ B9 p6 J: }8 s{
7 ~$ z1 O& T+ i J unsigned char c;
7 b7 M: L! v: q* D uart0_init(); // 波特率115200,8N1(8个数据位,无校验位,1个停止位)
' }- ~- C! {& }! B% O) C1 k" }) V4 k, c0 @
while(1)
I: d$ \9 [3 ~: z7 n3 g# h9 r {
+ j) b8 [8 p* z6 C/ ~' c0 O // 从串口接收数据后,判断其是否数字或子母,若是则加1后输出
p5 y5 ^$ M9 k6 G$ e( d. ? c = getc();
* T* {& g9 U% L9 m# H* ~ if (isDigit(c) || isLetter(c))9 P) A- f3 e; z" N0 b* X" \
putc(c+1);+ e9 ]; ^6 F' s" b- E
}
0 e& X$ p# Y: h1 q7 x: i# B E' z8 f$ Z0 M% X5 N/ R/ A$ s- R4 ^
return 0;. {9 U- r1 {& H* ?, p8 I
}( X2 |2 |7 Q4 S J- g; d
) t' K# k5 ?& |0 v! V
8 ~8 A7 e( Y4 Z/ \0 i) a# p6.Makefile
3 V2 ] q5 K4 x5 b/ ?/ [objs := head.o init.o serial.o main.o
- ?' ^- G2 s9 Q# q$ h& b( C0 t
' S5 V) i) U# |7 R3 J! muart.bin: $(objs)& z+ w4 [* [9 E5 }3 ^7 v8 \. Z
ARM-linux-ld -Tuart.lds -o uart_elf $^
) y3 |* x- `( D9 g3 S arm-linux-objcopy -O binary -S uart_elf $@& [) |+ `0 U/ J |9 [) j$ d( {
arm-linux-objdump -D -m arm uart_elf > uart.dis
& n* c* y& v- u6 a# R+ Y- W
! k3 O( ^2 L, t4 {6 j%.o:%.c0 n2 Z9 s$ d7 [: b
arm-linux-gcc -Wall -O2 -c -o $@ $<
{' [( ]* S9 l! Y! z Q# [5 f/ y& y+ Y
%.o:%.S
& ^$ q: p- |$ i0 U% ^ P3 b# M8 v arm-linux-gcc -Wall -O2 -c -o $@ $<
) l: i9 v4 K# L0 a: r, M+ \
7 R! r. f6 k f# Y0 Y) oclean:
+ q& C: V* L$ @# ~, Q rm -f uart.bin uart_elf uart.dis *.o |
! v5 c# S i# k* N& Z8 h- l3 [5 C: @. L9 s
0 U1 i- o4 w* H; c# d8 N" M( B* r, H
|
|