RT-Thread
|
2018-11-15
|
350
在 RT-Thread 的 kernel 中,許多副程式的結尾都有 RTM_EXPORT
,如:
void rt_enter_critical(void) { register rt_base_t level;
level = rt_hw_interrupt_disable();
rt_scheduler_lock_nest ++;
rt_hw_interrupt_enable(level); } RTM_EXPORT(rt_enter_critical);
|
RTM_EXPORT
是在 rtm.h 中所定義的一個巨集。
File: rtm.h
1. _MSC_VER
20 21 22 23 24
| #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_
26 27
| #elif defined(__MINGW32__) #define RTM_EXPORT(symbol)
|
3. else
29 30 31 32 33 34 35 36 37
| #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],即模組化