/* 用循环调用所有初始化函数 */
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
{
if ((*init_fnc_ptr)() != 0)
{
/* 当每个函数初始化失败时,就会挂机在这里。 */
hang();
}
}
上次说到在函数指针数组里,不断地调用所有初始化函数进行初始化,下面就来仔细地分析一下,它们到底是做什么的,做什么样的初始化,怎么样为后面做好运行的准备工作。看到第一个初始化函数,就是CPU初始化(cpu_init),这个函数是在cpu/s3c44b0/cpu.c里,它的作用就是进行S3C44B0初始化工作。看到这个函数内容如下:
/*
CPU初始化。
蔡军生 2005/07/23
*/
int cpu_init (void)
{
/* 清空缓冲区 */
icache_enable();
return 0;
}
它在里面调用了函数icache_enable(),它就是用来初始化S3C44B0的缓冲区,并且启用CPU缓冲区。因为CPU在加电之后,它的初始化值是不启用内部的8K缓冲区的,必须由程序进行设置。接着看看那个调用的函数又是怎么样初始化内部缓存区的呢?
/*
CPU内存的缓冲初始化。
蔡军生 2005/07/23
*/
void icache_enable (void)
{
ulong reg;
/* 清空内存的缓冲区. */
s3c44b0_flush_cache();
/*
初始化缓冲区,
设置非缓冲区的起始地址和结束地址。
第一个寄存器指明下面的地址不要缓存,低16位是起始地址,
高16位是结束地址。并且空间大小都是以4K为界。
0x0000:0000 - 0x0C00:0000
*/
NCACHBE0 = 0xC0000000;
NCACHBE1 = 0x00000000;
/*
设置SYSCFG寄存器启用8K缓冲区。
*/
reg = SYSCFG;
reg |= 0x00000006; /* 8kB */
SYSCFG = reg;
}
在这个函数里,第一个先调用函数是进行缓冲区清0的工作,它有一些特别的地方,如下:
/*
CPU的内部缓冲初始化。
蔡军生 2005/07/23
*/
static void s3c44b0_flush_cache(void)
{
volatile int i;
/* 清空缓冲区,每次要按4个32位来读写,所以要加16. */
for( i = 0x10002000; i < 0x10004800; i += 16 )
{
*((int *)i)=0x0;
}
}
它用一个for循环进行内部的缓冲区初始化,由于S3C44B0决定每次读写都是按16字节进行的。因此,这里的i就是不断地加16个字节。不过,这里为什么不清除0x10000000到0x10001fff区域呢?这个我也没有搞清楚,等我有空试试清除有没有问题!
到现在为止,缓冲区已经清空,就要设置那些内存区域是不要进行缓存的。因为不是所有内存都需要进行缓冲的,比如读取外面的IO,就不需要进行缓冲;读取FLASH也不需要。因此,设置第一个非缓冲区的起始地址为NCACHBE0 = 0xC0000000,这个值里的低16位是起始地址0x0000,它的32位地址就是从0x00000000开始。它的高16位是结束地址0Xc000,它的32位地址就是从0Xc0000000结束。最后就是通过设置SYSCFG寄存器的[2:1]位的值为11,就启用了8K内存数据和指令缓冲区。到这里为止,就已经设置好CPU的缓冲区初始化和启用。
上一篇:学习ARM开发(11)
下一篇:最后一页
推荐阅读最新更新时间:2024-11-14 11:24
设计资源 培训 开发板 精华推荐
- LTC4162EUFD-FST 9V 至 35V 2 节 3.2A 充电器的典型应用,具有 PowerPath 和 2A 输入限制
- LT3692A 演示板,7V 至 36V 输入至 5V at 3A/3.3V at 3A
- NCP12700POE45W24VGEVB:45 W、24 V 以太网供电 (PoE) 评估板
- 433MHz接收模块控制4路继电器
- TS34063 单片开关稳压器和子系统的典型应用,用作 DC 到 DC 转换器
- 实验板开发
- 使用 NXP Semiconductors 的 MC34PF3000A6EP 的参考设计
- 52单片机打地鼠
- #第七届立创电赛#姿态显示
- 使用 ROHM Semiconductor 的 BD4825 的参考设计