关于uboot移植 CAMDIVN与时钟

合集下载

S3C2440时钟问题uboot乱码

S3C2440时钟问题uboot乱码

S3C2440始终设置问题2440的PLL分为两种,MPLL和UPLL,MPLL用来做系统时钟,UPLL则是USB时钟(必须为48M),两种时钟的计算方法一样:M pll=(m×F osc×2)÷(p×2^s)记住是2的s次幂2410 不必乘2 m=MDIV+8p=PDIV+2s=SDIVU pll=(m×F osc×2)÷(p×2^s)这里的m,p,s 分别都在MPLLCON 寄存器的[19:12],[9:4],[1:0]或UPLLCON寄存器的[19:12],[9:4],[1:0]里进行设置,他们的取值详见官方的推荐表:MPLLCON和UPLLCON的值根据上面的两个公式计算而来,而这两个寄存器的设置值决定了系统的工作主频,和USB的主时钟分频前的频率。

如果用到USB或串口的话,那就需要小心的设置CLKDIVN寄存器了,这个寄存器的DIVN_UPLL位决定了USB的时钟,且必须为48M,例如:你的UPLL设置为48M时则不需要分频,DIVN_UPLL位为0就可以了,反之,如果你的UPLL设置为96M时,为保持USB时钟为48M,这里的DIVN_UPLL必须设置为1.HDIVN设置则要稍微复杂些,需要根据CAMDIVN[9]来综合决定,原则是首先确定你想要的HCLK频率,然后再结合系统的频率限制合理的来设置。

PDIVN设置直接决定你的串口能否正常工作了,同样举个例子:当前系统的主频为MPLL 为400M ,UPLL为48M,CAMDIVN[9]位为0,那么想得到115200的波特率,CLKDIVN寄存器应该设置为多少?首先可以确定DIVN_UPLL位为0,解释见上面,接下来确定HDIVN 和PDIVN了,s3c24x0的波特率计算公式为UBRDIV=PCLK/(baudrate×16)-1波特率直接和PCLK有关,假设UBRDIV设置为0x1A,则PCLK为50M,是FCLK的1/8,所以HDIVN=2 PDIVN=1。

移植u-boot详细过程

移植u-boot详细过程

编译信息最后两行:
arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
到此交叉编译成功。
三.开始针对自己的开发板移植
B 是最简单的跳转指令。要注意的是,跳转指令的实际值不是绝对地址,而是相对地址——
是相对当前 PC 值的一个偏移量,它的值由汇编器计算得出。
BL 非常常用。它在跳转之前会在寄存器 LR(R14)中保存 PC 的当前内容。BL 的经典用法如下:
bl NEXT ; 跳转到 NEXT
……
NEXT
……mov pc, lr源自; 从子程序返回。ldr pc, _start_armboot
_start_armboot: .word start_armboot
这两条语句,ldr
pc, _start_armboot 指令把_start_armboot 这个标签的地方存放的内
容(也即是 start_armboot)移到 PC 寄存器里面,start_armboot 是一个函数地址,在编译的时
sbc2410x_config: unconfig @$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0 qljt2440_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t qljt2440 qljt s3c24x0 /* 各项的意思如下:
1. 修改/cpu/arm920t/start.S 1.1 修改寄存器地址定义

ARM 2440 uboot移植过程

ARM 2440 uboot移植过程

详细的boorloader的移植(1)北京顶嵌嵌入式培训机构 2009-09-14 16:52:23 作者:赵老师来源:顶嵌技术部文字大小:[大][中][小]一.BootLoader简介简单的说bootloader是一段程序,它的作用就是加载操作系统,BootLoader(引导加载程序)是系统加电后运行的第一段软件代码。

通过这段代码实现硬件的初始化,建立内存空间的映射图,为操作系统内核准备好硬件环境并引导内核的启动。

如右图所示的那样在设备的启动过程中bootloader位于最底层,首先被运行来引导操作系统运行,很容易可以看出 bootloader是底层程序所以它的实现严重地依赖于硬件,特别是在嵌入式世界。

因此,在嵌入式世界里建立一个通用的BootLoader几乎是不可能的。

尽管如此,一些功能强大、支持硬件环境较多的BootLoader也被广大的使用者和爱好者所支持,从而形成了一些被广泛认可的、较为通用的的bootlo ader实现。

简单的介绍几种:1.U-BOOTuboot是一个庞大的公开源码的软件。

他支持一些系列的arm体系,包含常见的外设的驱动,是一个功能强大的板极支持包。

其代码可以从下载U-BOOT是由PPCBO OT发展起来的,是PowerPC、ARM9、Xscale、X86等系统通用的Boot方案,从官方版本0.3.2开始全面支持SC系列单板机。

u-boot是一个开源的bootloader。

2.vivivivi是韩国mizi 公司开发的bootloader, 适用于ARM9处理器。

Vivi有两种工作模式:启动加载模式和下载模式。

启动加载模式可以在一段时间后(这个时间可更改)自行启动linux内核,这是vivi的默认模式。

如果修改或更新需要进入下载模式,在下载模式下,vivi为用户提供一个命令行接口通过接口可以使用vivi提供的一些命令,来实现flash的烧写、管理、操作mtd分区信息、启动系统等功能。

uboot学习与移植笔记整理

uboot学习与移植笔记整理

Part1:remap.remap比较简单,和MMU的功能可以看做是等价的,只是一般remap地址估定为0x0 ,网上有个帖子叫<<ARM remap与重定位摘抄>>专门讲了它对remap的理解,对remap的作用是这样讲的: 当ARM处理器上电或者Reset之后,处理器从0x0取指。

因此,必须保证系统上电时,0x0处有指令可以执行。

所以,上电的时候,0x0地址处必定是ROM或者Flash(NOR)。

但是,为了加快启动的速度,也方便可以更改异常向量表,加快中断响应速度,往往把异常向量表映射到更快、更宽(32bit/16bit)的RAM中。

但是异常向量表的开始地址是由ARM架构决定的,必须位于0x0处,因此,必须把RAM映射到0x0。

文中提到了ARM处理器remap的三种情况,如下1)如果处理器有专门的寄存器可以完成Remap。

那么Remap是通过Remap寄存器的相应bit置1完成的。

如Atmel AT91xx2)如果处理器没有专门的寄存器,但是memory的bank控制寄存器可以用来配置bank的起始地址,那么只要把RAM的起始地址编程为0x0,也可以完成remap。

如samsung s3c4510 .3)如果上面两种机制都没有,那么Remap就不要做了。

因为处理器实现决定了SDRAM对应的bank地址是不能改变的。

如Samsung S3c2410.不过我的看法有点稍微不一样,如果上面两种机制都没有,那么Remap就不要做了,它给的典型例子是Samsung S3c2410 ,2410虽然sdram对应的bank地址不能改变,但它有MMU功能, MMU可以起到remap的作用,常用的最典型的应该是例子Samsung S3c44b0,它既没有mmu,又SDRAM对应地址有没办法改变.顺便补充下除了4510可以改变每个bank的地址,还有华邦的w90P740(arm7),呵呵,我现在用的U就是这款U,可以把bank的地址随意的设置.2.relocate .relocate (地址重定位),个人觉得这个是boot里面最麻烦也是最核心的部分,刚开始看boot代码的时候,它简直是我的噩梦,不知道大家分析boot的源码流程是否这样,也可能我大学不是计算机的,没学过编译原理(现在也没看过)对链接和加载一无所知,有两个星期非常痛苦,就是不懂人家boot里面的链接脚本为什么要那样写.网上关于uboot的帖子很多,但对链接加载这块,始终写的不详细,不知道是不是太过于基础了,高手都不愿意讲,最后自己找资料,发现其实一切痛苦的根源都是对链接和加载不太清楚造成的,但个人感觉boot除了初始化以外就是搬运程序,如何搬运?为什么要那样搬运都需要对硬件板的地址分布很清楚?而这些都是链接决定的,所以非弄清楚不可!1.我们为什么需要relocate ? 经济方面,(nandflash和norflash 每兆价格相差悬殊),把boot代码放在norflash里面(为什么不放在nandflash里面,因为nandflash读需要驱动支持,norflash可以直接访问),boot通常很小,只需要占用几十k的空间,所以只需要很小的norflash芯片,这样很便宜,而把应用程序通常很大,所以用价格低廉nandflash来储存,实际应用,通过执行boot程序,把nandflash里面代码和数据搬运到内存中来执行,这样比程序直接放在norflash里执行,可以.另外还有运行速度方面的差别,程序在norflash里执行的速度远远小于在sdram中执行的速度,为了追求更高的速度,也需要relocate,让程序在sdram里面执行.2.关于加载域(VMA)和运行域(LMA)(加载域和运行域,加载域是程序代码在ROM、FLASH中的排列次序及地址安排,运行域是程序运行时代码在SRAM、SDRAM中地址安排;存储代码时按照加载域存放在FLASH中,运行时再从FLASH中取出代码到RAM运行域运行,一段代码的加载域和存储域可以不同),杜春雷在它那本经典的<<arm体系结构与编程>>一书专门有一章来讲加载域和运行域不一致的情况,但我当初接触了它的这些加载域和运行域后,看uboot的lds ,uboot的lds没有设置LMA,只是设置了VMA,为此我疑惑很久.直到耐心的看了那本链接器和加载器的书才豁然明白( /viewthread.php?tid=817770 ),任何一个链接器和加载器的基本工作都非常简单: 将更抽象的名字与更底层的名字绑定起来,好让程序员使用更抽象的名字编写代码,链接器的就是把源文件进行符号解析,把解析出来的符号和地址的进行绑定,把全局变量,函数,标号等等这些符合和地址绑定起来.3.boot上电后开始能够正确执行还有个很重要的原因,是要保证boot在系统加电或复位后最初执行的代码是跟地址无关的,(即在代码搬运前所执行的代码是与地址无关),地址无关即地址无关代码生成的这个映象文件可以被放在内存中的任何一个地址上运行。

uuboot 移植流程

uuboot 移植流程

uuboot 移植流程U-Boot 移植流程介绍U-Boot是一个开源的引导加载程序,常用于嵌入式系统中。

移植U-Boot可以将其适配到不同的硬件平台上,以满足特定需求。

本文将详细说明U-Boot移植的流程。

准备工作1.硬件选型:根据项目需求,选择适合的硬件平台。

2.获取源代码:从U-Boot官方网站或仓库下载最新版本的源代码。

3.安装交叉编译工具链:根据目标硬件平台的指令集架构,选择合适的交叉编译工具链,并进行安装。

4.了解目标硬件平台:熟悉目标硬件平台的架构、引导方式、存储器布局等相关信息。

移植流程1.配置编译环境:设置交叉编译工具链的环境变量,以确保正确编译U-Boot源代码。

2.配置U-Boot:修改U-Boot源代码中的配置文件,根据目标硬件平台的特性和需求进行相应配置。

–配置目标硬件平台的处理器类型、存储器布局等基本信息。

–配置启动方式,如通过网络(TFTP)或存储介质(SD卡、NAND Flash)等进行启动。

–配置启动流程,如引导加载程序的加载顺序、启动脚本等。

3.添加适配代码:根据目标硬件平台的需求,编写适配代码,包括引导加载程序和设备驱动等。

–引导加载程序:为目标硬件平台选择合适的程序入口点,配置启动参数,加载适配的设备驱动等。

–设备驱动:根据目标硬件平台的外设,编写相应的设备驱动代码,以支持外设的初始化和操作。

4.编译U-Boot:使用交叉编译工具链,编译修改后的U-Boot源代码。

–执行make clean清除之前的编译结果。

–执行make命令编译U-Boot源代码。

5.烧录和运行:将编译生成的U-Boot镜像烧录到目标硬件平台,并进行测试。

–根据目标硬件平台的烧录方式(串口、JTAG等),将U-Boot镜像烧录到目标设备。

–启动目标设备,观察U-Boot的启动信息是否正常输出,检查设备驱动是否正常加载。

6.调试和优化:根据实际情况,进行U-Boot的调试和性能优化。

–使用调试工具进行调试,如调试器、串口打印信息等。

UBoot移植详解

UBoot移植详解

u-boot 移植步骤详解1 U-Boot简介U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。

从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。

其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。

但是U-Boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。

其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。

这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。

这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。

就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。

其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT 改名为U-Boot后逐步扩充的。

从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。

当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。

U-boot移植

移植U-Boot2009-01到阳初S3C2440超值版支持NAND启动,支持YAFFS文件系统参考了《移植U-Boot-2008.10到友善之臂mini2440》要知道需要修改那些文件就要分析顶层Makefile【bootloader是什么?分为几个阶段?每阶段分别完成什么任务?】根据README,先要运行make <board_name>_config然后再运行make来生成uboot执行文件,根据makefile的语法这个<board_name>_config必然是makefile中定义的一个target,那么我们就要①仿照其他的开发板来建立自己开发板的<board_name>_config,与我的开发板最相近的为smdk2410,所以根据smdk2410_config来写自己的gateway_config并加入到顶层makefile中;从顶层makefile中<board_name>_config目标的执行命令可以看出调用了mkconfig脚本,正常执行本脚本后应该会在./include中生成两个文件:config.mk和config.h并且会将输入的参数传递到ARCH、CPU、BOARD、VENDOR、SOC几个变量中,且在生成的config.h文件中将包含configs/$1.h文件,所以我们要②在configs下建立自己开发板的.h头文件,可以通过拷贝相似开发板的头文件;③修改子目录下的makefile;④修改源文件中与2440不符的内容。

一个调试方法就是用板子上已能正常跑起来的bootloader将刚改过编译好的uboot下载到内存中运行,具体操作为:定义CONFIG_SKIP_LOWLEVEL_INIT为“1”,或者注释掉start.s中#ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_crit#endif这三句中间的那句跳转,然后修改当前开发板目录下的config.mk中的text_base为0x33000000,使用vivi 命令load ram 0x33000000 0x17ea8 x将u-boot.bin装入内存。

uboot移植(深入浅出)

移植U-Boot.1.3.1到S3C244和S3C2410首先,U-Boot1.3.1还没有支持s3c2440,移植仍是用2410的文件稍作修改而成的。

2440和2410的区别在我移植1.2.0的文章中已经写了,这里不再赘述。

对于1.3.1和1.2.0的差别,我初看了一下,(对于ARM920T内核)应该是增加了对A TMEL 公司的A T91RM9200系列处理器的支持。

至于S3C24X0系列的芯片,原理上并没有什么大的变化。

一、在U-Boot中建立自己的开发板类型,并测试编译。

我为开发板取名叫: tekkaman24400 在工作目录下解压U-Boot。

[tekkamanninja@ARM9-Host working]$ tar -xjvf u-boot-1.3.1.tar.bz21 进入U-Boot目录,修改Makefile(我在fedora 8 下,比较喜欢使用KWrite)[tekkamanninja@ARM9-Host working]$ cd u-boot-1.3.1[tekkamanninja@ARM9-Host u-boot-1.3.1]$ kwrite Makefile#为tekkaman2440建立编译项sbc2410x_config: unconfig@$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0tekkaman2440_config : unconfig@$(MKCONFIG) $(@:_config=) arm arm920t tekkaman2440 tekkaman s3c24x0LSD1808_config: unconfig@$(MKCONFIG) $(@:_config=) arm arm926ejs lsd1808 NULL am1808各项的意思如下:arm: CPU的架构(ARCH)arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。

ARM9时钟说明

S3C2440的时钟设置时间:一个嵌入式系统中,晶振就像心脏。

必须先确定晶振,设置好系统的时钟,WDT,UART,PWM,TIMER等模块才能正常工作。

和51系列单片机相比,S3C2440的时钟电路很复杂。

首先通过引脚OM2,OM3来选择时钟源。

以TQ2440开发板为例,OM2,OM3都接地,外接12M晶振,主时钟源和USB时钟源都是外部晶振。

S3C2440具有2个PLL(Phase Locked Loop:用来产生高频的电路),一个是MPLL, 用于产生FCLK,HCLK,PCLK三种频率,这三种频率分别有不同的用途:FCLK是CPU提供的时钟信号,如果提到CPU的主频是400MHz,就是指的这个时钟信号。

HCLK是为AHB总线提供的时钟信号,Advanced High-performance Bus,主要用于高速外设,比如内存控制器,中断控制器,LCD控制器,DMA 以及USB host 。

PCLK是为APB总线提供的时钟信号,Advanced Peripherals Bus,主要用于低速外设,比如WATCHDOG,IIS, I2C,SDI/MMC, GPIO,RTC ,UART,PWM,ADC and SPI等等。

另外一个是UPLL,专门用于驱动USB host/Device。

并且驱动USB host/Device的频率必须为48MHz。

时钟电路相关寄存器总共有7个,下面分别介绍。

MPLLCON(0X4C00 0004)和UPLLCON(0X4C00 0008)这两个寄存器用来设置主锁相环产生的时钟和USB锁相环产生的时钟。

MPLL=(2*m*Fin)/(p*2^s) UPLL=(m*Fin)/(p*2^s)其中m=(MDIV+8),p=(PDIV+2),s=SDIVP,M范围:1<=P<=62,1<=M<=248注意:MDIV【19:12】,PDIV【9:4】,SDIV【1:0】,当设置MPLL和UPLL值的时候,需要先设置UPLL再设置MPLL。

u-boot移植5--从nandflash启动甄选

u-boot移植5--从nandflash启动(优选.)Uboot移植5--支持从nand flash启动同时支持norflash和nandflash启动方法一:在时钟修改方法一条件下:修改cpu/arm920t/start.S/*#ifndef CONFIG_SKIP_RELOCATE_UBOOTrelocate: */ /* relocate U-Boot to RAM */adr r0, _start /* r0 <- current position of code */ldr r1, _TEXT_BASE /* test if we run from flash or RAM */cmp r0, r1 /* don't reloc during debug */beq stack_setup/*check code position*/ldr r0,=48000000ldr r0,[r0]ands r0,r0,#6bne nor_boot#define LENGTH_UBOOT 0x60000#define NAND_CTL_BASE 0x4e000000/*offset*/#define oNFCONF 0x00#define oNFCONT 0x04#define oNFCMD 0x08#define oNFSTAT 0x20nand_boot:mov r1,#NAND_CTL_BASEldr r2,=((7<<12)|(7<<8)|(7<<4))str r2,[r1,#oNFCONF]ldr r2,[r1,#oNFCONF]ldr r2,=((1<<4)|(0<<1)|(1<<0))str r2,[r1,#oNFCONT]ldr r2,[r1,#oNFCONT]ldr r2,=(0x6)str r2,[r1,#oNFSTAT]ldr r2,[r1,#oNFSTAT]mov r2,#0xffstr r2,[r1,#oNFCMD]mov r3,#0nand1:add r3,r3,#0x1cmp r3,#0xablt nand1nand2:ldr r2,[r1,#oNFSTAT]tst r2,#0x4beq nand2ldr r2,[r1,#oNFCONT]orr r2,r2,#0x2str r2,[r1,#oNFCONT]ldr sp, DW_STACK_STARTmov fp, #0ldr r0, =TEXT_BASEmov r1, #0x0mov r2, #LENGTH_UBOOTbl nand_read_lltst r0, #0x0beq ok_nand_readbad_nand_read:loop2:b loop2ok_nand_read:mov r0, #0ldr r1, =TEXT_BASEmov r2, #0x400go_next:ldr r3, [r0], #4ldr r4, [r1], #4teq r3, r4bne notmatchsubs r2, r2, #4beq stack_setupbne go_nextnotmatch:loop3:b loop3nor_boot:adr r0, _start /* r0 <- current position of code */ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ldr r2, _armboot_startldr r3, _bss_startsub r2, r3, r2 /* r2 <- size of armboot */add r2, r0, r2 /* r2 <- source end address */copy_loop:ldmia r0!, {r3-r10} /* copy from source address [r0] */stmia r1!, {r3-r10} /* copy to target address [r1] */cmp r0, r2 /* until source end addreee [r2] */ble copy_loop/* Set up the stack */接着在board/mao2440下新建文件nand_boot.c,代码如下。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于uboot移植 CAMDIVN与时钟2010-03-09 19:57在该文件的122行附近有这样一个结构体typedef struct {S3C24X0_REG32 LOCKTIME;S3C24X0_REG32 MPLLCON;S3C24X0_REG32 UPLLCON;S3C24X0_REG32 CLKCON;S3C24X0_REG32 CLKSLOW;S3C24X0_REG32 CLKDIVN;} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;是用来封装时钟寄存器的,我们要在其中增加一项S3C24X0_REG32 CAMDIVN,为什么加这么一个呢?因为这个寄存器是2410所没有的,而2440在配置时钟的时候又必须用到,看名字我们就知道是用来配置CAMERA时钟的,也就是配置摄像头的时钟的。

貌似和配置uboot启动的时钟没有关系?其实不然,我们在修改下一个文件的时候就可以看到其用途了,此结构体修改后的结果为typedef struct {S3C24X0_REG32 LOCKTIME;S3C24X0_REG32 MPLLCON;S3C24X0_REG32 UPLLCON;S3C24X0_REG32 CLKCON;S3C24X0_REG32 CLKSLOW;S3C24X0_REG32 CLKDIVN;S3C24X0_REG32 CAMDIVN;} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;第二个文件..\cpu\arm920t\s3c24x0\speed.c在这个文件中需要修改两个函数第一个函数在54行附近:static ulong get_PLLCLK(int pllreg)由于S3C2410和S3C2440的MPLL、UPLL计算公式不一样,所以get_PLLCLK 函数也需要修改:修改前为static ulong get_PLLCLK(int pllreg){S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); ulong r, m, p, s;if (pllreg == MPLL)r = clk_power->MPLLCON;else if (pllreg == UPLL)r = clk_power->UPLLCON;elsehang();m = ((r & 0xFF000) >> 12) + 8;p = ((r & 0x003F0) >> 4) + 2;s = r & 0x3;return((CONFIG_SYS_CLK_FREQ * m) / (p << s));}修改后为static ulong get_PLLCLK(int pllreg){S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); ulong r, m, p, s;if (pllreg == MPLL)r = clk_power->MPLLCON;else if (pllreg == UPLL)r = clk_power->UPLLCON;elsehang();m = ((r & 0xFF000) >> 12) + 8;p = ((r & 0x003F0) >> 4) + 2;s = r & 0x3;if (pllreg == MPLL)return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));else if (pllreg == UPLL)return((CONFIG_SYS_CLK_FREQ * m) / (p << s));}为什么要再返回时加一个判断呢?因为在2440中MPLL的时钟为UPLL时钟的2倍,在s3c2440的数据手册里的227页这样写到MPLL和UPLL的计算方法MPLL Control RegisterMpll = (2 * m * Fin) / (p * 2s)m = (MDIV + 8), p = (PDIV + 2), s = SDIVUPLL Control RegisterUpll = (m * Fin) / (p * 2s)m = (MDIV + 8), p = (PDIV + 2), s = SDIV这个就是修改此函数的缘由。

第二个函数在82行附近:ulong get_HCLK(void)此函数修改前为ulong get_HCLK(void){S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK()); }修改后为ulong get_HCLK(void){S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER(); if (clk_power->CLKDIVN & 0x6){if ((clk_power->CLKDIVN & 0x6)==2) return(get_FCLK()/2);if ((clk_power->CLKDIVN & 0x6)==6) return((clk_power->CAMDIVN &0x100) ?get_FCLK()/6 : get_FCLK()/3);if ((clk_power->CLKDIVN & 0x6)==4) return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);return(get_FCLK());}else return(get_FCLK());}这里我们就用到了在修改speed.c文件时所添加的CAMDIVN 项了,因为这一项的值决定了我们的时钟配置。

这样修改的原因是在s3c2440的数据手册的231页有这样一段话CLOCK DIVIDER CONTROL (CLKDIVN) REGISTERRegister Address R/W Description Reset ValueCLKDIVN 0x4C000014 R/W Clock divider control register 0x00000000 CLKDIVN Bit DescriptionDIVN_UPLL [3] UCLK select register(UCLK must be 48MHz for USB)0:UCLK = UPLL clock1:UCLK = UPLL clock / 2Set to 0, when UPLL clock is set as 48MhzSet to 1. when UPLL clock is set as 96Mhz.HDIVN [2:1] 00 : HCLK = FCLK/1.01 : HCLK = FCLK/2.10 : HCLK = FCLK/4 when CAMDIVN[9] = 0.HCLK= FCLK/8 when CAMDIVN[9] = 1.11 : HCLK = FCLK/3 when CAMDIVN[8] = 0.HCLK = FCLK/6 when CAMDIVN[8] = 1.PDIVN [0] 0: PCLK has the clock same as the HCLK/1.1: PCLK has the clock same as the HCLK/2.我们到底应该返回FCLK的几分之一在这里就有秒数,其中必须根据HDIVN的值与CAMDIVN的值来判断。

附录:关于S3C2440时钟设置的理解工作技术-嵌入式 2008-10-24 22:36:32 阅读1293 评论4 字号:大中小订阅关于S3C2440时钟设置的理解1)FLCK、HCLK和PCLK的关系S3C2440有三个时钟FLCK、HCLK和PCLK手册上说P7-8写到:FCLK is used by ARM920T,内核时钟,主频。

HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controller, the LCD controller, the DMA and USB host block. 也就是总线时钟,包括USB时钟。

PCLK is used for APB bus, which is used by the peripherals such as WDT, IIS, I2C, PWM timer, MMC interface,ADC, UART, GPIO, RTC and SPI.即IO接口时钟,例如串口的时钟设置就是从PCLK来的;那么这三个时钟是什么关系呢?这三个时钟通常设置为1:4:8,1:3:6的分频关系,也就说如果主频FLCK是400MHz,按照1:4:8的设置,那么HLCK是100MHz,PLCK是50MHz 寄存器CLKDIVN表明并设置了这三个时钟的关系如果CLKDIVN设置为0x5,那么比例即为1:4:8,前提是CAMDIVN[9]为0.2)输入时钟FIN与主频FCLK的关系现代的CPU基本上都使用了比主频低的多的时钟输入,在CPU内部使用锁相环进行倍频。

对于S3C2440,常用的输入时钟FIN有两种:12MHz和16.9344MHz,那么CPU是如何将FIN倍频为FCLK的呢?S3C2440使用了三个倍频因子MDIV、PDIV和SDIV来设置将FIN倍频为MPLL,也就是FCLKMPLL=(2*m*FIN)/(p*2^s) where m=(MDIV+8), p=(PDIV+2), s=SDIV寄存器MPLLCON就是用来设置倍频因子的理论上,你可以通过设置该寄存器来实现不同的频率,然而,由于实际存在的各种约束关系,设置一个适当的频率并不容易,手册上列出了一些常用频率的表格,例如,假设输入时钟FIN=16.9344M,MDIV=110, PDIV=3, SDIV=1,利用上面的公式,FCLK=2*16.9344*(110+8)/((2+3)*2)=399.653)关于USB时钟S3C2440有两个锁相环,一个主锁相环MPLL提供给FCLK的,另外一个UPLL 是提供给USB时钟(48MHz)的,与MPLL一样,UPLL的产生也是通过UPLLCON寄存器设置分频因子得到,计算公式稍有不同:UPLL=(m*FIN)/(p*2^s) where m=(MDIV+8), p=(PDIV+2), s=SDIV,同样,可以通过查表得到一个合适的值。

相关文档
最新文档