RTX筆記14 - RTX5 osThreadNew 函數簡單分析


 1 /// Create a thread and add it to Active Threads.
 2 osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) {
 3   osThreadId_t thread_id;
 4 
 5   EvrRtxThreadNew(func, argument, attr);
 6   if (IsException() || IsIrqMasked()) {
 7     EvrRtxThreadError(NULL, (int32_t)osErrorISR);
 8     thread_id = NULL;
 9   } else {
10     thread_id = __svcThreadNew(func, argument, attr);
11   }
12   return thread_id;
13 }
  OSThreadNew函數原型如上所示。
  EvrRtxThreadNew:事件記錄器(Event Recorder)函數,只有在開啟事件記錄器的時候才有效。
  IsException():檢查是否處於異常處理程序中。如果是,則直接返回中斷錯誤碼。
  IsIrqMasked():從優先級掩碼寄存器primask返回優先級掩碼位的當前狀態。如果primask被設置為1,說明關閉了除 NMI 和硬 fault 之外的所有異常,則直接返回中斷錯誤碼。
  __svcThreadNew:如果中斷檢測通過,則最終調用這個函數創建線程。該函數實現SVC系統調用,編號為0。該函數的具體定義如下:
1 SVC0_3 (ThreadNew,           osThreadId_t,    osThreadFunc_t, void *, const osThreadAttr_t *)
  SVC0_3代表SVC0,系統調用的輸入參數有三個。SVC0_3是一個宏定義函數,原型如下:
 1 #define SVC0_3(f,t,t1,t2,t3)                                                   \
 2 __attribute__((always_inline))                                                 \
 3 __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3) {                             \
 4   SVC_ArgR(0,a1);                                                              \
 5   SVC_ArgR(1,a2);                                                              \
 6   SVC_ArgR(2,a3);                                                              \
 7   SVC_ArgF(svcRtx##f);                                                         \
 8   SVC_Call0(SVC_In3, SVC_Out1, SVC_CL0);                                       \
 9   return (t) __r0;                                                             \
10 }
 1 #define SVC_RegF "r7"
 2 
 3 #define SVC_ArgF(f) \
 4 register uint32_t __rf   __ASM(SVC_RegF) = (uint32_t)f
 5 
 6 #define SVC_ArgR(n,a) \
 7 register uint32_t __r##n __ASM("r"#n) = (uint32_t)a
 8 
 9 #define SVC_Call0(in, out, cl)                                                 \
10   __ASM volatile ("svc 0" : out : in : cl)
  其中SVC_ArgR、SVC_ArgF、SVC_Call0也都是宏定義。將其分別代入之后,得到__svcThreadNew函數的具體實現:
1 __attribute__((always_inline))                                                                                   \
2 __STATIC_INLINE osThreadId_t __svcThreadNew (osThreadFunc_t a1, void * a2, const osThreadAttr_t * a3) {          \
3   register uint32_t __r0 __ASM("r0") = (uint32_t)a1                                                              \
4   register uint32_t __r1 __ASM("r1") = (uint32_t)a2                                                              \
5   register uint32_t __r2 __ASM("r2") = (uint32_t)a3                                                              \
6   register uint32_t __rf   __ASM("r7") = (uint32_t)svcRtxThreadNew                                               \
7  __ASM volatile ("svc 0" : "=r"(__r0) : "r"(__rf),"r"(__r0),"r"(__r1),"r"(__r2) : );                             \
8   return (osThreadId_t) __r0;                                                                                    \
9 }

  可以看出__svcThreadNew函數觸發SVC系統調用之后,最終調用了svcRtxThreadNew函數創建線程。

  注:RTX5的很多API操作都是通過SVC0間接執行的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM