|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
我使用gcc编译,但只能生成,o文件,无法生成.bin文件,什么原因3 \ ]9 p+ N% V2 a1 z1 t. w
.head.s9 D- n3 c) ?3 K$ [; c* D3 M
) S1 i {& j. Q% M; e
@******************************************************************************0 L1 h7 H5 _1 w& S- D) K
@ File:head.S
3 {4 i3 ?9 L. G: s& ]% w@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
! V* ~) i+ a- J4 w@******************************************************************************
* Y- Q+ V: T9 V: Q9 `. f
- s9 g, a( O) j, F$ z6 o.extern main, J; [ m0 G- q* o
.text. p- Q" w# z& z0 e5 p" X
.global _start
- [5 d* J- n) @& k_start:% {6 y6 t2 A5 Z- `6 U i$ f) L
Reset:
$ e+ a$ ]9 \& _- p0 u ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
1 j- h8 Z, a/ P% @( a bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
y; e. o4 s2 N) U# X) m) ^ // bl是位置无关码,相当于:PCnew = PC + 偏移: W5 ^6 l3 d0 t. u) M; v, i
// PCnew = (4+8) + 0x28 = 0x34 W; h# ^! G" P
2 e# \; O! S8 l$ H: w7 P
ldr pc, =disable_watch_dog
+ n1 |% f- }+ [# Q: \" L * A3 v1 r# z# }# m; }
bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK% f* ?) F2 u( d+ G
bl memsetup @ 设置存储控制器以使用SDRAM
; h; X) L) c2 n& |! K, n' |- D bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中% N9 f9 \* [4 }# ^1 E/ `' Y: w
ldr pc, =on_sdram @ 跳到SDRAM中继续执行: @( w: h. U9 G e
on_sdram:
+ r% m$ C* |$ P7 s/ b1 W ldr sp, =0x34000000 @ 设置栈指针
. L: f6 `/ O# u ldr lr, =halt_loop @ 设置返回地址% v# ^% o+ a# t! q" I* m* u
ldr pc, =main @ 调用main函数( ?) l2 H5 ` C) j; C$ n8 r2 E$ h
halt_loop:7 ~5 F! R( {9 g# y
b halt_loop) O6 R& M+ b) O- M
- ]' i% o. R. C
2.init.c
( o$ j. h" f) u- ]2 O: w5 i/** W+ z7 a+ S! H
* init.c: 进行一些初始化. Z7 W4 v( [/ ~, g* k. {$ }
*/' b7 m2 w# }& A: u9 Y
; M% g( l% {6 s f+ Q* c#include "s3c24xx.h"
& {9 L# Q, X2 f* c( u w" v1 O3 L7 |4 J! }9 U
void disable_watch_dog(void); w' @2 f' h- N$ ^
void clock_init(void);
6 w9 j- z/ U. l6 u! Svoid memsetup(void);$ _! b& }, ?0 ~! L/ V: `
void copy_steppingstone_to_sdram(void);
# J$ x5 z6 s& _; b7 \% c
9 V& M1 k; L( E8 h: T1 ~/*
+ g5 d- r4 v$ H4 j* 关闭WATCHDOG,否则CPU会不断重启7 G X4 l; d6 l6 @* z) A
*/0 f W. D4 S- _& e1 K. C
void disable_watch_dog(void)3 [, Y% F4 R7 Z+ i+ w- V
{+ M2 ~6 u& w) z6 j5 V6 m
WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可; w# s: ~" O: R: g) j Z# [
}
* @: E0 ^! K j. B; v5 B8 q3 [
2 ~- M+ @! O! H8 U#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))0 a- Z9 x! q7 g+ e
#define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))2 d4 ^; S% f4 _8 F& T2 m# I
/*
' p' B( q0 U, V8 b+ e' [7 Z* 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV8 H- k& B8 l, _6 r& U% |
* 有如下计算公式:" l9 K/ a8 a% L( m) X6 S3 `
* S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
1 N) t W+ {9 X; Z* |) ~* S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)* `) L! w1 I( H4 G( Z! r: ?" r; |
* 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
8 i8 Q, V5 V0 W6 z* 对于本开发板,Fin = 12MHz! Q) E3 W4 a3 a8 A9 i
* 设置CLKDIVN,令分频比为:FCLK:HCLK CLK=1:2:4,7 |! @. e, W7 C4 J* _2 W+ p
* FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
2 W& R. O) E/ I*/* M* e; @# O! c$ o4 ]. R* Z+ p6 z
void clock_init(void)0 d. ]* T8 s7 k8 p' Q
{: ~ R: [. m0 t F, U
// LOCKTIME = 0x00ffffff; // 使用默认值即可
' t0 A3 Z8 o9 d! O& a; m. x CLKDIVN = 0x03; // FCLK:HCLK CLK=1:2:4, HDIVN=1,PDIVN=1
& v7 c* i8 k" t6 ?
& G3 f( |! W8 Q; A. n: R+ s/ U! { /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
+ B9 g+ O/ S/ r, _# P" b__asm__(
% H1 N; o& c4 B "mrc p15, 0, r1, c1, c0, 0\n" /* 读出控制寄存器 */ D+ `) `# ^" T5 @1 F
"orr r1, r1, #0xc0000000\n" /* 设置为“asynchronous bus mode” */
( ^/ f- l0 N; O; F2 x2 }( S1 O "mcr p15, 0, r1, c1, c0, 0\n" /* 写入控制寄存器 */( K( G9 k6 s; R6 }
);6 s& y4 x* R. V9 {+ O! |. {/ a
' y* i( n6 Y2 G0 N0 X( |
/* 判断是S3C2410还是S3C2440 */( _- a4 k1 f9 k. }1 h
if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
# z$ j; {' p5 W v0 e+ u {
) E4 n0 P5 K7 n: j9 } MPLLCON = S3C2410_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */8 I4 f% i3 z+ q" @/ u
}
: B0 f& ?$ S N0 X/ {" a4 ? else; c! I( Y& R$ x$ |* J& z
{
0 K! N4 K5 ?- r MPLLCON = S3C2440_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
0 e% z5 a9 O6 @ ?, _ }
" J) ^# k) i% O4 ]}7 x# x" w6 f p# T
; W9 L7 u: T+ M/ E% S
/*
; d# ^# H7 c: ]7 I% Y- ]7 h* V* 设置存储控制器以使用SDRAM' n; w/ N% z* [7 a! ~: _3 [9 ^
*/$ t7 L4 {" ~: I- q" w4 @
void memsetup(void)
3 E% o3 g- d$ F8 c7 V2 D{6 z+ P5 m) ]6 K$ s
volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
* y) c# P8 Q4 i4 l/ g
' \% ^( f, Z0 S; J /* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值
1 G$ _" ~ E% K: Z+ O; F6 v * 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到* s; I" w) _7 t
* SDRAM之前就可以在steppingstone中运行3 }6 x3 }: p/ n4 \ R% Z
*/8 X0 ]1 H! Q. f- {7 t; a7 y; A
/* 存储控制器13个寄存器的值 */
2 ]8 v4 y7 {2 M p[0] = 0x22011110; //BWSCON. y3 j0 V+ Z% i% `* {0 y. f
p[1] = 0x00000700; //BANKCON0% |* t3 X& {8 c4 E/ e9 `
p[2] = 0x00000700; //BANKCON1
; g. w1 |6 s! y- Z1 [ p[3] = 0x00000700; //BANKCON2
/ Y, O- Z4 A/ g9 o7 Z* w( _ p[4] = 0x00000700; //BANKCON3 ) y, I4 K) x% w, i' `; u. W' y
p[5] = 0x00000700; //BANKCON42 W/ G6 U0 g% Q- D S; I7 l# ]) y
p[6] = 0x00000700; //BANKCON5
% P; _3 I) ^' c% L s0 o& H p[7] = 0x00018005; //BANKCON6
0 Z0 j, X1 ]3 U5 |% t9 \$ Y; u p[8] = 0x00018005; //BANKCON7& j( U y3 d; Z1 N( W
+ [; i/ k8 v% A9 ]" A
/* REFRESH,$ K6 {* v9 r1 v4 i8 I3 f5 _; d
* HCLK=12MHz: 0x008C07A3,
, k& o) M- M9 r% L A; t * HCLK=100MHz: 0x008C04F48 i& S5 K S' r$ y+ }5 z/ `1 s' a0 ?1 H+ y6 q
*/% a9 s* `( P6 j# c% z
p[9] = 0x008C04F4;' s- f# Q9 n6 |# F; j' O5 E
p[10] = 0x000000B1; //BANKSIZE
0 z+ c# K8 t" i' }" R8 d* L3 | p[11] = 0x00000030; //MRSRB6% L) L; G! L& C
p[12] = 0x00000030; //MRSRB7
3 K$ Y3 \4 M6 h}
" t% e7 i+ p$ i" U3 k& \3 l- C# N) f; u! C; m# p9 q( ^
void copy_steppingstone_to_sdram(void)
" A7 {/ x% h0 a/ i{2 [3 t |4 m# ]" C7 C
unsigned int *pdwSrc = (unsigned int *)0;
# w& \" i/ D9 D" y unsigned int *pdwDest = (unsigned int *)0x30000000;) K i. X/ w% V3 X( E9 P0 J
, p5 X U5 ]9 w4 \, a while (pdwSrc < (unsigned int *)4096)
L9 Y5 H. h$ Z# ~' t N: [ {8 Z- G% y, A* `% h7 e
*pdwDest = *pdwSrc;/ s/ _ J) ~" P4 r
pdwDest++;
4 [. I+ a" U6 t) ` pdwSrc++;
0 X' P' y" O# S) h+ V9 | } T9 o: _# h; ~& Y* I
}" ^. O o l. P9 s7 {6 N- J
) O `" W J% ]6 k
3.uart.c
& d# |, k/ ]+ N! d#include "s3c24xx.h"
0 k8 o, i( a" e# g6 ^4 J4 m& J#include "serial.h"
; ]' V! u$ i o; z) n y) D4 s$ f l1 F6 E( _/ N" y1 s+ w1 i
#define TXD0READY (1<<2)
; `; ?- V/ C3 n1 V" D#define RXD0READY (1)/ a- O" q' l; n k1 w3 r6 \7 z
1 D0 l) @1 e O" H$ o
#define PCLK 50000000 // init.c中的clock_init函数设置PCLK为50MHz
* x; c5 J, }1 _#define UART_CLK PCLK // UART0的时钟源设为PCLK3 I2 v& f0 v0 _) C4 T0 U
#define UART_BAUD_RATE 115200 // 波特率 O: y4 _% q2 v! z! |
#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)
; ]; B4 G; ], W. @! k, q1 D2 e4 [
, M z7 {/ H% ~" Q* T) G! p/*
K6 c3 X2 R, P6 L4 i* 初始化UART0: `/ W+ Z' j z% q _ d
* 115200,8N1,无流控
7 h8 X! D6 M8 Q1 F4 Y*/7 I* [7 X( q0 U* C
void uart0_init(void)
* h& B6 m# H; g{: i% d- V* n& |0 `
GPHCON |= 0xa0; // GPH2,GPH3用作TXD0,RXD0
( j! }1 b1 E1 c; u0 w1 B GPHUP = 0x0c; // GPH2,GPH3内部上拉
) R0 A% _" O6 m$ t9 ?' d
- v# p2 N& K% H( Q ULCON0 = 0x03; // 8N1(8个数据位,无较验,1个停止位)/ t/ K7 T2 K& x3 [1 b
UCON0 = 0x05; // 查询方式,UART时钟源为PCLK1 V3 p9 t1 x F( H; i
UFCON0 = 0x00; // 不使用FIFO+ S M4 G$ ~& h: p5 v6 I
UMCON0 = 0x00; // 不使用流控' }% _' g$ K" S) W; O4 K
UBRDIV0 = UART_BRD; // 波特率为115200% n& G( d: ~7 t) f) s. w4 B
}
$ x/ U7 c# b" m- ~; F x" P2 T$ k/ q1 H8 a
/*: ?& X9 w' f9 Q8 G1 l
* 发送一个字符
- V. ?- p k3 I \) H! c/ \4 `*/
% n, X" b) b6 s7 f5 s8 S+ Nvoid putc(unsigned char c)) b. u. ^/ U( {; l* y3 |! u! `
{) ?' p, H% v1 {. T! n
/* 等待,直到发送缓冲区中的数据已经全部发送出去 */
3 C% J/ ? X" I while (!(UTRSTAT0 & TXD0READY));
0 _: y. X; Y; Z" f# e8 D# b
+ F0 [5 [% G7 Z Q) h# g /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
3 J9 f. Z0 K, M( ]9 j UTXH0 = c;
6 ?0 J4 s7 Z' Y( X}6 D6 H B1 V# H, M4 o
6 l" O+ b9 @) W1 D
/*
, d8 g2 h! Q4 t! N. N: g* 接收字符
( K0 y4 o( x6 N1 M7 S7 c1 V*/
6 W9 }# X3 H# Q2 runsigned char getc(void). }. a% s% G2 z& R
{
1 w2 J7 _6 m0 s+ I5 X) [9 c /* 等待,直到接收缓冲区中的有数据 */
; z. j7 i; ?8 C5 |9 n3 j while (!(UTRSTAT0 & RXD0READY));
$ C" i; ]" w/ `7 ]; I, W
& D7 ^1 `" |$ ^: R /* 直接读取URXH0寄存器,即可获得接收到的数据 */2 K7 w% E0 V0 Y# y, J
return URXH0;; y) U" p6 T# H9 D$ n
}1 V9 R# @' x* D1 q7 k9 L
% t" y4 Q! D# N/ l- Y+ M* c/*$ \) J/ p5 m. A. I* t6 p
* 判断一个字符是否数字/ f0 i$ M; G( H/ a, w P p; S
*/6 u; G. N" b/ u
int isDigit(unsigned char c)/ f: F: ^6 m2 M* z
{$ k5 b- e7 t) i9 L* L$ ]
if (c >= '0' && c <= '9')
; k) m7 o" x0 [% X1 d4 J return 1;
0 ^6 n& m3 O. J1 o else2 y- P* T5 ^/ }- b
return 0; . F) L" p7 J* L4 w) [4 S
}9 u6 m, Q6 q4 D0 C2 Q$ o
, \6 X" i- a. A* \- `0 H/*
0 r& D8 }5 N8 U/ A q5 ?. t/ m7 q1 O* 判断一个字符是否英文字母& |2 D$ c D) z: F5 K* u( b
*/
5 n9 U1 |7 g" g! I C: s- v3 [- gint isLetter(unsigned char c)
; E/ Q0 `) z$ B: g$ g6 [" v* w4 X& d{* c; r3 {$ p$ Z# ^& ^7 x4 g; I2 p& e- r
if (c >= 'a' && c <= 'z')
) Z/ s$ s- n- R: z, I9 L2 _ return 1;
0 |7 m6 A" j5 x else if (c >= 'A' && c <= 'Z')
4 c. Y; X/ u! |( I% @ return 1; # H4 @* ^, U3 [3 q' A" v" N- P
else
" j2 s5 q* m# {) a return 0;
0 ^3 h! x6 Y# F: v& n% k. d}- ^; ]2 d( t( F! z
7 {6 n+ X1 y( ~9 V$ h, D# l3 X7 }+ R" c
4.uart.lds
' }3 ?1 J, J/ mSECTIONS {; t( G8 J, F ]* C
. = 0x30000000;! y7 V1 ?6 [2 ?& w0 {4 c$ i# Y! `8 @
.text : { *(.text) }* I: {/ b8 p; ^9 \4 v
.rodata ALIGN(4) : {*(.rodata)}
# i2 k9 d+ r( L5 z$ }, a .data ALIGN(4) : { *(.data) }
# ]0 e4 f1 j0 t8 ^6 z: @) ~ .bss ALIGN(4) : { *(.bss) *(COMMON) }
0 Q0 ?9 j5 U* u2 A8 e7 l/ L}
0 N# M# W/ _8 p
/ _# g9 V) I, m4 d! c6 Q$ _4 W5.main.c8 {: M" e1 P/ R: \% T, N: j
#include "serial.h"" {+ P0 [3 M9 a( t- F
7 i$ E2 D6 a) kint main()7 n0 n* Z& A ^- A" f) y" I2 {
{7 j* @3 v& v$ |5 s4 l: D. D( |
unsigned char c;$ L/ G1 e- e1 B2 c
uart0_init(); // 波特率115200,8N1(8个数据位,无校验位,1个停止位) W* f- b2 a4 l3 K
$ @! ]* I8 P5 ~* E" m( s
while(1). p/ }( d8 l$ k5 s; R
{
/ ?% S3 R( k$ I e; Y6 E$ l7 m // 从串口接收数据后,判断其是否数字或子母,若是则加1后输出% ^: |8 L) g9 Z0 N/ B1 s
c = getc();5 H: }5 j7 L8 ?, M+ o( L! i
if (isDigit(c) || isLetter(c))
9 Y3 T0 x! r7 R7 U) Q putc(c+1);: U" z, d- x, v& q9 X
}
& T% T' b2 W! U2 E4 W0 C; q2 H, b4 l& H* |' _
return 0;
" T! \- s: x/ z# @$ H. `}( F4 M( S+ C* f! Z
/ X5 g; l+ \$ u# x4 S
8 s. u9 I6 g% V% k3 ~
6.Makefile
$ V' W) o; T" e& wobjs := head.o init.o serial.o main.o
' E( J0 o9 D+ m5 E& L+ r- S8 x* h/ e. T: C
uart.bin: $(objs)
: G8 T% e! @; i ARM-linux-ld -Tuart.lds -o uart_elf $^
% d% @7 z, H+ y/ s arm-linux-objcopy -O binary -S uart_elf $@
$ F$ W% v( P5 A9 L arm-linux-objdump -D -m arm uart_elf > uart.dis9 k; n! I' k! e! Y3 w
6 ^9 b# {* O+ u' Q& g; P%.o:%.c
; l; j+ g0 `) }* b: M arm-linux-gcc -Wall -O2 -c -o $@ $<! c( x# w7 G7 {! `4 \/ Y; X' N8 _
' r) m q1 W+ ~7 ^7 _+ ~5 N
%.o:%.S8 m8 r f: _, |- o& c w$ r
arm-linux-gcc -Wall -O2 -c -o $@ $<9 \) [# k0 B$ u6 |( ~
) I6 f ?* s! V% K7 Xclean:
: r+ f) j+ k( x/ P rm -f uart.bin uart_elf uart.dis *.o | . H! d2 @7 h+ g0 B
% f, R/ ~7 [2 m% Z
6 U" h4 k+ z8 ?5 R7 q: _; t |
|