Try  HackMD Logo HackMD

RT-Thread 理解 RTM_EXPORT

在 RT-Thread 的 kernel 中,許多副程式的結尾都有 RTM_EXPORT,如:

/** 
 * This function will lock the thread scheduler.
 */
void rt_enter_critical(void)
{
    register rt_base_t level;

    /* disable interrupt */
    level = rt_hw_interrupt_disable();

    /*
     * the maximal number of nest is RT_UINT16_MAX, which is big
     * enough and does not check here
     */
    rt_scheduler_lock_nest ++;

    /* enable interrupt */
    rt_hw_interrupt_enable(level);
}
RTM_EXPORT(rt_enter_critical);

RTM_EXPORT 是在 rtm.h 中所定義的一個巨集。

File: rtm.h

  • RTM_EXPORT 可被定義的方式有三種:

1. _MSC_VER

#if defined(_MSC_VER) #pragma section("RTMSymTab$f",read) #define RTM_EXPORT(symbol) \ __declspec(allocate("RTMSymTab$f"))const char __rtmsym_##symbol##_name[] = "__vs_rtm_"#symbol; #pragma comment(linker, "/merge:RTMSymTab=mytext")

2. _MINGW32

#elif defined(__MINGW32__) #define RTM_EXPORT(symbol)

3. else

#else #define RTM_EXPORT(symbol) \ const char __rtmsym_##symbol##_name[] SECTION(".rodata.name") = #symbol; \ const struct rt_module_symtab __rtmsym_##symbol SECTION("RTMSymTab")= \ { \ (void *)&symbol, \ __rtmsym_##symbol##_name \ }; #endif
  • ## 為連字符[1],作用是將指定文字帶到變數名稱裡;如:當傳進來的 symbol 值是 rt_enter_critical 時,此字串的變數名會被宣告成 __rtmsym_rt_enter_critical_name
  • SECTION__attribute__((section)) 的巨集寫法
  • # 為字串話操作符,作用是將後面的變數轉換成字串;如當傳進來的 symbol 值是 rt_enter_critical 時,#symbol 會被轉換成 "rt_enter_critical"
  • 綜合以上,我們可以將原來的 RTM_EXPORT(rt_enter_critical) 透過 define 轉換成以下程式碼:
const char __rtmsym_rt_enter_critical_name[] __attribute__((section(".rodata.name"))) \
= "rt_enter_critical";
const struct rt_module_symtab __rtmsym_rt_enter_critical  \
 __attribute__((section("RTMSymTab")))=
{                                                                     
    (void *)&rt_enter_critical,                                                  
    __rtmsym_rt_enter_critical_name                                          
};
struct rt_module_symtab
{
    void       *addr;
    const char *name;
};

用意

  • linux 系統中,有 EXPORT_SYMBOL,其中的用意是為了在撰寫程式時能夠方便呼叫這些副程式[2],即模組化
tags: RT-Thread kernel

  1. C/C++ 的預處理定義 : # , #@ , ## ↩︎

  2. EXPORT_SYMBOL解析 ↩︎