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間接執行的。
