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间接执行的。

posted @ 2021-10-06 18:02  Ivan0512  阅读(2044)  评论(0编辑  收藏  举报