Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14293
  • 博文数量: 5
  • 博客积分: 255
  • 博客等级: 二等列兵
  • 技术积分: 55
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-14 10:15
文章存档

2010年(5)

我的朋友

分类: 嵌入式

2010-05-14 10:34:46

 

U-boot存储器映射图:

下面注释有不对的地方,请朋友指正.谢谢~ (说明:部分注释源于网络!)

uboot中一段源码如下,位于lib_arm/board.c

typedef int (init_fnc_t) (void);    //自定义新的数据类型init_fnc_t,这个数据类型是参数为空,返回值为int的函数

PS:注意init_fnc_t并不是函数指针!!! 如果这样写就表示函数指针 typedef int (*init_fnc_t) (void);

//init_sequence 是一个指针数组(数组元素为指针变量),指向的是init_fnc_t类型的函数(为什么是函数呢?因为指向的新的数据类型 init_fnc_t是参数为空,返回值为int的函数)
init_fnc_t *init_sequence[] = {        //int *init_sequence[i]表示指针数组,也就是数组元素是指针变量(函数的入口地址)!!!
#if defined(CONFIG_ARCH_CPU_INIT)
    arch_cpu_init,        /* basic arch cpu dependent setup 基本的处理器相关配置 -- cpu/s3c44b0/cpu.c */
#endif
    board_init,        /* basic board dependent setup 基本的板级相关配置 -- board/samsung/smdk2410/smdk2410.c */
#if defined(CONFIG_USE_IRQ)
    interrupt_init,        /* set up exceptions 初始化例外处理 -- cpu/s3c44b0/interrupt.c */
#endif
    timer_init,        /* initialize timer */
    env_init,        /* initialize environment 初始化环境变量 -- common/env_flash.c  */
    init_baudrate,        /* initialze baudrate settings 初始化波特率设置 -- lib_arm/board.c*/
    serial_init,        /* serial communications setup 串口通讯设置 -- cpu/s3c44b0/serial.c */
    console_init_f,        /* stage 1 init of console 控制台初始化阶段1 -- common/console.c*/
    display_banner,        /* say that we are here 打印u-boot信息 -- lib_arm/board.c*/
#if defined(CONFIG_DISPLAY_CPUINFO)
    print_cpuinfo,        /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
    checkboard,        /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
    init_func_i2c,
#endif
    dram_init,        /* configure available RAM banks 配置可用的RAM -- board/samsung/smdk2410/smdk2410.c*/
#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
    arm_pci_init,
#endif
    display_dram_config,        //显示RAM的配置大小 -- lib_arm/board.c
    NULL,
};

 //init_fnc_t 为指向函数指针的指针
    init_fnc_t **init_fnc_ptr;    //init_fnc_ptr是函数指针的指针,"函数指针"表示指向的内容;后面的"指针"表示init_fnc_ptr本身为一个指针变量

    /*init_fnc_ptr初始化指向init_sequence指针数组,下 面的循环遇到NULL结束*/
    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {  
        if ((*init_fnc_ptr)() != 0) {    /* (*init_fnc_ptr)()为C中调用指针指向的函数,例如 arch_cpu_init()*/
            hang ();        //打印错误信息并死锁
        }
    }

PS:指针数组和指向指针的指针 两者的主要区别(现在只悟到了这么一点)

就是,指针数组的数组名不能进行++操作(因为数组名仅仅代表一个地址!是一个常量!!),而指向指针的指针是 可以++的(因为它是一个变量!),所以这段源代码中,重新定义了一个指向函数指针的指针init_fnc_ptr来对指针数组 (init_sequence)进行操作. 操作也就是将各个准备初始化的函数的入口地址依次赋给init_fnc_ptr!而*init_fnc_ptr就正好对应arch_cpu_init这些 东西了,那么(*init_fnc_ptr)()就相当于arch_cpu_init() 了.

PS:函数指针就是函数的入口地址,指针就是地址,貌似可以这么来理解!呵呵

自 己都整晕了 不知道叙述明白了没有~~~ 

网络上的两个测试例子:

测试程序一:

#include<stdio.h>
int test0 (void);
int test1 (void);
typedef int (*test_fnc_t) (void);
test_fnc_t test_sequence[] = {
    test0,        
    test1,        
    NULL,
};

int main()
{
    test_fnc_t *test_fnc_ptr;

    for (test_fnc_ptr = test_sequence; *test_fnc_ptr; ++test_fnc_ptr) {
        if ((*test_fnc_ptr)() != 0) {
            printf("error here!");
        }
    }
    return 0;
}

int test0 (void)
{
    printf("test0\n");
    return 0;
}

int test1 (void)
{
    printf("test1\n");
    return 0;
}

测试程序二:

#include<stdio.h>
int test0 (void);
int test1 (void);
typedef int (test_fnc_t) (void);
test_fnc_t *test_sequence[] = {
    test0,        
    test1,        
    NULL,
};

int main()
{
    test_fnc_t **test_fnc_ptr;

    for (test_fnc_ptr = test_sequence; *test_fnc_ptr; ++test_fnc_ptr) {
        if ((*test_fnc_ptr)() != 0) {
            printf("error here!");
        }
    }
    return 0;
}

int test0 (void)
{
    printf("test0\n");
    return 0;
}

int test1 (void)
{
    printf("test1\n");
    return 0;
}

上面两个测试代码,输出结果一样的,都输出

test0

test1

阅读(2148) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:ARM汇编中.word含义的深度剖析(uboot源码)

给主人留下些什么吧!~~