一。平台
系统:ubuntu12.04
开发板:jz2440
编译器:gcc
二。时钟系统
后补上
三。代码
Makefile:
1 objs := head.o init.o interrupt.o main.o
2
3 timer.bin: $(objs)
4 arm-linux-ld -Ttimer.lds -o timer_linux $^
5 arm-linux-objcopy -O binary -S timer_linux $@
6 arm-linux-objdump -D -m arm timer_linux > timer.dis
7
8 %.o:%.c
9 arm-linux-gcc -Wall -O2 -c -o $@ $<
10
11 %.o:%.S
12 arm-linux-gcc -Wall -O2 -c -o $@ $<
13
14 clean:
15 rm -f timer.bin timer_linux timer.dis *.o
16
head.S
1 @******************************************************************************
2 @ File:head.S
3 @ 功能:初始化,设置中断模式、系统模式的栈,设置好中断处理函数
4 @******************************************************************************
5
6 .extern main
7 .text
8 .global _start
9 _start:
10 @******************************************************************************
11 @ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用
12 @******************************************************************************
13 b Reset
14
15 @ 0x04: 未定义指令中止模式的向量地址
16 HandleUndef:
17 b HandleUndef
18
19 @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
20 HandleSWI:
21 b HandleSWI
22
23 @ 0x0c: 指令预取终止导致的异常的向量地址
24 HandlePrefetchAbort:
25 b HandlePrefetchAbort
26
27 @ 0x10: 数据访问终止导致的异常的向量地址
28 HandleDataAbort:
29 b HandleDataAbort
30
31 @ 0x14: 保留
32 HandleNotUsed:
33 b HandleNotUsed
34
35 @ 0x18: 中断模式的向量地址
36 b HandleIRQ
37
38 @ 0x1c: 快中断模式的向量地址
39 HandleFIQ:
40 b HandleFIQ
41
42 Reset:
43 ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
44 bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
45 bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK
46 bl memsetup @ 设置存储控制器以使用SDRAM
47 bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
48 ldr pc, =on_sdram @ 跳到SDRAM中继续执行
49 on_sdram:
50 msr cpsr_c, #0xd2 @ 进入中断模式
51 ldr sp, =4096 @ 设置中断模式栈指针
52
53 msr cpsr_c, #0xdf @ 进入系统模式
54 ldr sp, =0x34000000 @ 设置系统模式栈指针,
55
56 bl init_led @ 初始化LED的GPIO管脚
57 bl timer0_init @ 初始化定时器0
58 bl init_irq @ 调用中断初始化函数,在init.c中
59 msr cpsr_c, #0x5f @ 设置I-bit=0,开IRQ中断
60
61 ldr lr, =halt_loop @ 设置返回地址
62 ldr pc, =main @ 调用main函数
63 halt_loop:
64 b halt_loop
65
66 HandleIRQ:
67 sub lr, lr, #4 @ 计算返回地址
68 stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器
69 @ 注意,此时的sp是中断模式的sp
70 @ 初始值是上面设置的4096
71
72 ldr lr, =int_return @ 设置调用ISR即EINT_Handle函数后的返回地址
73 ldr pc, =Timer0_Handle @ 调用中断服务函数,在interrupt.c中
74 int_return:
75 ldmia sp!, { r0-r12,pc }^ @ 中断返回, ^表示将spsr的值复制到cpsr
76
init.c
1 /*
2 * init.c: 进行一些初始化
3 */
4
5 #include "s3c24xx.h"
6
7 void disable_watch_dog(void);
8 void clock_init(void);
9 void memsetup(void);
10 void copy_steppingstone_to_sdram(void);
11 void init_led(void);
12 void timer0_init(void);
13 void init_irq(void);
14
15 /*
16 * 关闭WATCHDOG,否则CPU会不断重启
17 */
18 void disable_watch_dog(void)
19 {
20 WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可
21 }
22
23 #define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))
24 #define S3C2440_MPLL_200MHZ ((0x5c<<12)|(0x01<<4)|(0x02))
25 /*
26 * 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV
27 * 有如下计算公式:
28 * S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
29 * S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
30 * 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
31 * 对于本开发板,Fin = 12MHz
32 * 设置CLKDIVN,令分频比为:FCLK:HCLK:PCLK=1:2:4,
33 * FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
34 */
35 void clock_init(void)
36 {
37 // LOCKTIME = 0x00ffffff; // 使用默认值即可
38 CLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
39
40 /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
41 __asm__(
42 "mrc p15, 0, r1, c1, c0, 0n" /* 读出控制寄存器 */
43 "orr r1, r1, #0xc0000000n" /* 设置为“asynchronous bus mode” */
44 "mcr p15, 0, r1, c1, c0, 0n" /* 写入控制寄存器 */
45 );
46
47 /* 判断是S3C2410还是S3C2440 */
48 if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
49 {
50 MPLLCON = S3C2410_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
51 }
52 else
53 {
54 MPLLCON = S3C2440_MPLL_200MHZ; /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
55 }
56 }
57
58 /*
59 * 设置存储控制器以使用SDRAM
60 */
61 void memsetup(void)
62 {
63 volatile unsigned long *p = (volatile unsigned long *)MEM_CTL_BASE;
64
65 /* 这个函数之所以这样赋值,而不是像前面的实验(比如mmu实验)那样将配置值
66 * 写在数组中,是因为要生成”位置无关的代码”,使得这个函数可以在被复制到
67 * SDRAM之前就可以在steppingstone中运行
68 */
69 /* 存储控制器13个寄存器的值 */
70 p[0] = 0x22011110; //BWSCON
71 p[1] = 0x00000700; //BANKCON0
72 p[2] = 0x00000700; //BANKCON1
73 p[3] = 0x00000700; //BANKCON2
74 p[4] = 0x00000700; //BANKCON3
75 p[5] = 0x00000700; //BANKCON4
76 p[6] = 0x00000700; //BANKCON5
77 p[7] = 0x00018005; //BANKCON6
78 p[8] = 0x00018005; //BANKCON7
79
80 /* REFRESH,
81 * HCLK=12MHz: 0x008C07A3,
82 * HCLK=100MHz: 0x008C04F4
83 */
84 p[9] = 0x008C04F4;
85 p[10] = 0x000000B1; //BANKSIZE
86 p[11] = 0x00000030; //MRSRB6
87 p[12] = 0x00000030; //MRSRB7
88 }
89
90 void copy_steppingstone_to_sdram(void)
91 {
92 unsigned int *pdwSrc = (unsigned int *)0;
93 unsigned int *pdwDest = (unsigned int *)0x30000000;
94
95 while (pdwSrc < (unsigned int *)4096)
96 {
97 *pdwDest = *pdwSrc;
98 pdwDest++;
99 pdwSrc++;
100 }
101 }
102
103 /*
104 * LED1-4对应GPB5、GPB6、GPB7、GPB8
105 */
106 #define GPB5_out (1<107 #define GPB6_out (1<108 #define GPB7_out (1<109 #define GPB8_out (1<110
111 #define GPFCON (*(volatile unsigned long *)0x56000050)
相关文章