• ecos代码分析(3)


    ecos代码分析(3)

    在看cyg_start()之前,先要解决3个问题:

    1. __startup_stack在哪里定义?

    2. cyg_hal_invoke_constructors()这个机制是如何使用?

    3. CALL_IF*机制是如何实现?

     

    1. __startup_stack在哪里定义?

    PTR(__startup_stack)

    #define PTR(name) .##name: .word  name

    等价于 .__startup_stack: .word __startup_stack

    后面有

            .section ".bss"

            .balign 16

    __startup_stack_base:

    #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK

            .rept 512

    #else

            .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE

    #endif

            .byte 0

            .endr

            .balign 16

    __startup_stack:

    #endif                               

    说明__startup_stack这个标号在.bss段中,和__startup_stack_base一起限定__startup_stack的范围。

    汇编.rept.endr之间的语句count次,即运行”.byte 0” 512次,相当于申请了512byte的空间,作为stack空间。

    __startup_stack上面还有很多stack的定义,都一样的,没啥好说的。

    没看懂这个,at&t汇编的伪指令要看看了。

     

    2. cyg_hal_invoke_constructors()这个机制是如何使用?

    void cyg_hal_invoke_constructors (void)

    {

        pfunc *p;

        for (p = &CONSTRUCTORS_START; p != CONSTRUCTORS_END; NEXT_CONSTRUCTOR(p))

            (*p)();

    }

    // EABI uses different symbols, and constructors are in opposite order.

    #ifdef CYGBLD_HAL_ARM_EABI

    extern pfunc __init_array_start__[];

    extern pfunc __init_array_end__[];

    #define CONSTRUCTORS_START  (__init_array_start__[0])

    #define CONSTRUCTORS_END    (__init_array_end__)

    #define NEXT_CONSTRUCTOR(c) ((c)++)

    #else

    extern pfunc __CTOR_LIST__[];

    extern pfunc __CTOR_END__[];

    #define CONSTRUCTORS_START  (__CTOR_END__[-1])

    #define CONSTRUCTORS_END    (&__CTOR_LIST__[-1])

    #define NEXT_CONSTRUCTOR(c) ((c)--)

    #endif

     

    #define SECTION_text(_region_, _vma_, _lma_) \

        SECTION_ARM_extab(_region_, _vma_, _lma_) \

        SECTION_ARM_exidx(_region_, ALIGN(AAPCS_ALIGN), FOLLOWING_ALIGNED(.ARM.extab, AAPCS_ALIGN)) \

        .text ALIGN(AAPCS_ALIGN) : FOLLOWING_ALIGNED(.ARM.exidx, AAPCS_ALIGN) \

        { \

        *(.text*) *(.gnu.warning) *(.gnu.linkonce.t.*) *(.init) \

        *(.glue_7) *(.glue_7t)  \

        __CTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.ctors*))) __CTOR_END__ = ABSOLUTE (.); \

        __DTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.dtors*))) __DTOR_END__ = ABSOLUTE (.); \

        } > _region_ \

        _etext = .; PROVIDE (__etext = .);

    查遍整个工程,也找不到相关的内容。

    在网上找到一篇关于C++全局构造函数的文章,里面有写到:

    .ctors  section保存着程序的全局的构造函数的指针数组。

    .dtors  section保存着程序的全局的析构函数的指针数组。  

    这个段是由编译器自己填充的,不必由代码显示的说明。

    运行cyg_hal_invoke_constructors()就是把全局构造函数全都运行一下,都构造好。

    可以想象,退出的时候,是要把全局析构函数全都运行一下。

     

    3. CALL_IF*机制是如何实现?

    首先IF应该是interface的缩写

    都在diag_if.h中定义,挑几个出来看看。

    #define CYGACC_CALL_IF_VERSION() \

     CYGACC_DATA_VV(__call_if_version_t, CYGNUM_CALL_IF_VERSION)

    __data_VV(CYGNUM_CALL_IF_VERSION, __call_if_version_t)

    #define CYGACC_CALL_IF_VERSION_SET(_x_) \

     hal_virtual_vector_table[CYGNUM_CALL_IF_VERSION]=(CYG_ADDRWORD)(_x_)

    两个是一对,前面定义调用,后面定义调用的函数

    hal_virtual_vector_table[]是一个全局的系统调用接口数组,每一个成员对一个系统调用。这个前面提到了。

    #define CYGNUM_CALL_IF_VERSION                    0

    这里就是定义0号调用,调用到的函数就是参数_x_

    hal_virtual_vector_table[0]=(CYG_ADDRWORD)(_x_)

    #define CYGACC_DATA_VV(t,e)              __call_vv_##e()

    #define __data_VV(_n_,_tt_)                             \

    static __inline__ _tt_                                  \

    __call_vv_##_n_(void)                                   \

    {                                                       \

        return ((_tt_)hal_virtual_vector_table[_n_]);       \

    }

    所以前面的展开就是:

    #define CYGACC_CALL_IF_VERSION() __call_vv_0()

    static __inline__ __call_if_version_t __call_vv_0(void)

    {

             return ((__call_if_version_t)hal_virtual_vector_table[0]);

    }

    这样一个设置一个调用。

    可能还有类似的东西,以后看到再说。

    http://blog.sina.com.cn/s/blog_559f6ffc0100mk54.html

  • 相关阅读:
    Linux.超级管理员root-密码破解
    Hibernate.基础篇《一》.Hibernate工具类.
    不同版本Hibernate.获取SessionFactory的方式
    Hibernate.编写xml文件无自动提示信息
    ubantu中安装TensorFlow遇到的问题
    Ubuntu中安装python3.6(转)
    Linux 用户管理
    虚拟机中Linux安装(转)
    红黑树(转)
    树的遍历方法(转)
  • 原文地址:https://www.cnblogs.com/kuainiao/p/2861372.html
Copyright © 2020-2023  润新知