S3C2440的裸奔--系统时钟篇
S3C2440的裸奔
--系统时钟篇
Author : He YiJun (storysnail<at>gmail.com QQ:363559089)
LingYing Develop Team : 7fane Team (http://www.7fane.com) Editor : Yang QiuXi Art Designer : He YiJun License : 7fane Team License 1.0 Last Update : 2012-06-07
参考书目:
人民邮电出版社 《嵌入式Linux应用开发完全手册》 --韦东山著
机械工业出版社 《嵌入式Linux应用开发全程解析与实战》 --吴士力、刘奇、朱兰著
电子工业出版社 《嵌入式Linux系统实用开发》 --何永琪等著
人民邮电出版社 《Linux设备驱动开发详解》 --宋宝华著
电子工业出版社 《ARM嵌入式常用模块与综合系统设计实例精讲》--张绮文、解书钢著
电子工业出版社 《嵌入式系统Linux内核开发实战指南》 --王洪辉著
北京航空航天大学出版社 《ARM LINUX入门与实践》 --方强、程昌南著
北京航空航天大学出版社 《嵌入式底层软件开发》 --杨铸、唐攀著
可能是宅的太久了吧,这几天情绪非常低落,直接影响我的学习进度,所以只是看了那么一点点内容!mini2440在没有开启时钟前,全靠一个板载的
12MHz晶振提供频率来运行。也就是CPU,内存,UART等等都运行在12MHz下面,这显然效率非常低,要知道S3C2440正常可以工作在
400MHz下呢,两者相差非常之大。
s3c2440的时钟系统由3部分组成,
内核工作频率:由FCLK提供,最高400MHz,为ARM920T内核使用的工作频率
AHB总线频率:由HCLK提供,最高100MHz,为AHB总线上挂接的硬件提供工作频率,例如内存,NAND,LCD控制器等硬件
APB总线频率:由PCLK提供,最高50MHz,为APB总线上挂接的硬件提供工作频率,例如UART串口,WATCHDOG等
s3c2440的PLL:
s3c2440时钟源为板载的12MHz晶振,为了得到更高的时钟频率,可通过PLL来提高频率,PLL有如下两种:
MPLL:用来产生FCLK、HCLK、PCLK
UPLL:用来产生USB设备的工作频率
寄存器设置部分略,详见手册或相关书籍。
下面是启动代码:
@****************************************************************************** @ File:crt0.S @ 功能:初始化系统时钟,然后转入C程序 @****************************************************************************** .equ WTCON, 0x53000000 @看门狗控制寄存器 .equ WTDAT, 0x53000004 @看门狗数据寄存器 .equ WTCNT, 0x53000008 @看门狗计数寄存器 .equ LOCKTIME, 0x4c000000 @变频锁定时间寄存器 .equ MPLLCON, 0x4c000004 @MPLL寄存器 .equ CLKDIVN, 0x4c000014 @分频比寄存器 .text .global _start _start: ldr r0, =WTCON @ 关闭WATCHDOG mov r1, #0x0 str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启 bl init_clock @初始化系统时钟 ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K bl main @ 调用C程序中的main函数 halt_loop: b halt_loop init_clock: @ 设置锁频时间 ldr r0, =LOCKTIME @取得LOCKTIME寄存器地址 ldr r1, =0x00ffffff @设置锁定时间 str r1, [r0] @将r1中的数据写入r0 @设置FCLK,HCLK,PCLK三者之间的比例,本来还需要设置CAMDIVN寄存器, @但这里设置成1:4:8,所以CAMDIVN使用默认值就可以了! ldr r0, =CLKDIVN @取得CLKDIVN寄存器地址 mov r1, #0x05 @设定比例 str r1, [r0] @修改CPU总线模式 mrc p15, 0, r1, c1, c0, 0 orr r1, r1, #0xc0000000 mcr p15, 0, r1, c1, c0, 0 @倍频到400MHz ldr r0, =MPLLCON @MPLL控制寄存器 ldr r1, =0x0005c011 str r1, [r0] mov pc, lr @ 返回 @******************************************************************************
下面是C程序,其实就是上次那个leds.c程序,只是更改个名字而已!
/****************************************************************************** SysClk.c ******************************************************************************/ #define GPBCON (*(volatile unsigned *)0x56000010) #define GPBDAT (*(volatile unsigned *)0x56000014) #define GPBUP (*(volatile unsigned *)0x56000018) #define GPB5_out (1<<(5*2)) #define GPB6_out (1<<(6*2)) #define GPB7_out (1<<(7*2)) #define GPB8_out (1<<(8*2)) void delay(unsigned long dly) { for(;dly>0;dly--); } int main(void) { GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; //GPBUP=0xFFFF; GPBUP=0x0000; while(1) { GPBDAT&=~0x20; delay(30000); GPBDAT&=~0x60; delay(30000); GPBDAT&=~0xE0; delay(30000); GPBDAT&=~0x1E0; delay(30000); GPBDAT|=0x20; delay(30000); GPBDAT|=0x60; delay(30000); GPBDAT|=0xE0; delay(30000); GPBDAT|=0x1E0; delay(30000); } return 0; } /******************************************************************************/
然后是编译用的Makefile.
#****************************************************************************** #Makefile #****************************************************************************** CFLAGS := -Wall -Wstrict-prototypes -fomit-frame-pointer -ffreestanding SysClk.bin : crt0.S SysClk.c arm-linux-gcc $(CFLAGS) -c -o crt0.o crt0.S arm-linux-gcc $(CFLAGS) -c -o SysClk.o SysClk.c arm-linux-ld -Ttext 0x0000000 crt0.o SysClk.o -o SysClk_elf arm-linux-objcopy -O binary -S SysClk_elf SysClk.bin arm-linux-objdump -D -m arm SysClk_elf > SysClk.dis clean: rm -f SysClk.dis SysClk.bin SysClk_elf *.o #******************************************************************************
编译之后运行一下,比原来的leds快了很多吧!


浙公网安备 33010602011771号