RT-Thread源碼學習第三篇,$Sub$$main與$Super$$main擴展main函數

MDK5的__main函數是自動生成的,且沒法修改源碼。同時,MDK5提供了一對符號$Sub$$和$Super$$來擴展函數。這一對符號做用在鏈接器,當鏈接器鏈接到func時,若是發現存在$Sub$$func函數,會先鏈接$Sub$$func函數,一直到出現$Super$$func爲止,$Super$$func是func函數的新的入口。函數

Keil官網給的例子:測試

extern void ExtraFunc(void); extern void $Super$$foo(void):
/* this function is called instead of the original foo() */
void $Sub$$foo(void)
{
  ExtraFunc();    /* does some extra setup work */
  $Super$$foo();  /* calls the original foo() function */
                  /* To avoid calling the original foo() function
                   * omit the $Super$$foo(); function call.
                   */
}

$Sub$$和$Super$$符號能夠在不修改原程序的狀況下添加新功能,rtt就使用了這對符號來擴展main函數。this

作一個簡單的例子來測試一下這種擴展:code

int i = 0;

void $Super$$main(void);
void $Sub$$main(void)
{
    i++;
    $Super$$main();
}

int main(void)
{
    i++;
    while(1)
    {
        
    }
}

看反彙編(assembly mode),原來跳轉到main函數變成了跳轉到$Sub$$main函數:blog

__rt_entry_main:
0x08000172 F000F867  BL.W     $Sub$$main (0x08000244)
0x08000176 F000F84F  BL.W     exit (0x08000218)

 $Sub$$main函數:源碼

$Sub$$main:
0x08000244 B510      PUSH     {r4,lr}
0x08000246 4804      LDR      r0,[pc,#16]  ; @0x08000258
0x08000248 6800      LDR      r0,[r0,#0x00]
0x0800024A 1C40      ADDS     r0,r0,#1
0x0800024C 4902      LDR      r1,[pc,#8]  ; @0x08000258
0x0800024E 6008      STR      r0,[r1,#0x00]
0x08000250 F000F8A8  BL.W     main (0x080003A4)
0x08000254 BD10      POP      {r4,pc}
0x08000256 0000      DCW      0x0000
0x08000258 0000      DCW      0x0000
0x0800025A 2000      DCW      0x2000

這樣作,能夠保持啓動代碼不變,而同時實現對main函數的擴展。rtt的調度器就是這樣作的。it

相關文章
相關標籤/搜索