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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值