天天看点

RTX笔记2 - thread 管理

Thread states

  RUNNING:thread正在运行

  READY:线程准备就绪,等待执行

  BLOCKED:线程处于阻塞状态,可能在延时、等待时间的发生或者挂起

  TERMINATED:终止状态,资源还未释放

  INACTIVE:线程还未创建或者已经终止,并且资源已经释放

RTX笔记2 - thread 管理

1 enum      osThreadState_t {
2   osThreadInactive = 0,
3   osThreadReady = 1,
4   osThreadRunning = 2,
5   osThreadBlocked = 3,
6   osThreadTerminated = 4,
7   osThreadError = -1,
8   osThreadReserved = 0x7FFFFFFF
9 }      

Threads priority

  线程创建时的默认优先级是osPriorityNormal。如果一个活动线程已经就绪,并且它的优先级高于当前正在运行的线程,则会立即发生线程切换。系统继续执行优先级高的线程。

  为了防止优先级倒置,CMSIS-RTOS 兼容的操作系统可以选择性地实现优先级继承方法。当高优先级线程正在等待由低优先级线程控制的资源或事件时,就会发生优先级倒置。从而导致高优先级线程可能永远被另一个低优先级线程阻塞。为了解决这个问题,应该将控制资源的低优先级线程视为具有高优先级,直到它释放资源。

enum      osPriority_t {
  osPriorityNone = 0,
  osPriorityIdle = 1,
  osPriorityLow = 8,
  osPriorityLow1 = 8+1,
  osPriorityLow2 = 8+2,
  osPriorityLow3 = 8+3,
  osPriorityLow4 = 8+4,
  osPriorityLow5 = 8+5,
  osPriorityLow6 = 8+6,
  osPriorityLow7 = 8+7,
  osPriorityBelowNormal = 16,
  osPriorityBelowNormal1 = 16+1,
  osPriorityBelowNormal2 = 16+2,
  osPriorityBelowNormal3 = 16+3,
  osPriorityBelowNormal4 = 16+4,
  osPriorityBelowNormal5 = 16+5,
  osPriorityBelowNormal6 = 16+6,
  osPriorityBelowNormal7 = 16+7,
  osPriorityNormal = 24,
  osPriorityNormal1 = 24+1,
  osPriorityNormal2 = 24+2,
  osPriorityNormal3 = 24+3,
  osPriorityNormal4 = 24+4,
  osPriorityNormal5 = 24+5,
  osPriorityNormal6 = 24+6,
  osPriorityNormal7 = 24+7,
  osPriorityAboveNormal = 32,
  osPriorityAboveNormal1 = 32+1,
  osPriorityAboveNormal2 = 32+2,
  osPriorityAboveNormal3 = 32+3,
  osPriorityAboveNormal4 = 32+4,
  osPriorityAboveNormal5 = 32+5,
  osPriorityAboveNormal6 = 32+6,
  osPriorityAboveNormal7 = 32+7,
  osPriorityHigh = 40,
  osPriorityHigh1 = 40+1,
  osPriorityHigh2 = 40+2,
  osPriorityHigh3 = 40+3,
  osPriorityHigh4 = 40+4,
  osPriorityHigh5 = 40+5,
  osPriorityHigh6 = 40+6,
  osPriorityHigh7 = 40+7,
  osPriorityRealtime = 48,
  osPriorityRealtime1 = 48+1,
  osPriorityRealtime2 = 48+2,
  osPriorityRealtime3 = 48+3,
  osPriorityRealtime4 = 48+4,
  osPriorityRealtime5 = 48+5,
  osPriorityRealtime6 = 48+6,
  osPriorityRealtime7 = 48+7,
  osPriorityISR = 56,
  osPriorityError = -1,
  osPriorityReserved = 0x7FFFFFFF
}      

Threads create

1 osThreadId_t osThreadNew ( osThreadFunc_t         func,
2                            void *                 argument,
3                            const osThreadAttr_t * attr
4 )           
  func:线程函数
  argument:传递给线程函数的参数指针
  attr:线程属性;NULL:使用默认线程属性
  返回值:thread ID,可以被其他函数引用,NULL:创建失败      
struct osThreadAttr_t Data Fields
const char * name

name of the thread

Pointer to a constant string with a human readable name (displayed during debugging) of the thread object.

Default: NULL no name specified (debugger may display function name instead).

uint32_t attr_bits

attribute bits

The following bit masks can be used to set options:

  • osThreadDetached : create thread in a detached mode (default).
  • osThreadJoinable : create thread in joinable mode.
void * cb_mem

memory for control block

Pointer to a memory for the thread control block object. Refer to Static Object Memory for more information.

Default: NULL to use Automatic Dynamic Allocation for the thread control block.

cb_size

size of provided memory for control block

The size (in bytes) of memory block passed with cb_mem. For RTX, the minimum value is defined with osRtxThreadCbSize (higher values are permitted).

Default: 0 as the default is no memory provided with cb_mem.

stack_mem

memory for stack

Pointer to a memory location for the thread stack (64-bit aligned).

Default: NULL to allocate stack from a fixed-size memory pool using Thread Stack Management.

stack_size

size of stack

The size (in bytes) of the stack specified by stack_mem.

Default: 0 as the default is no memory provided with stack_mem.

/**

osPriority_t priority

initial thread priority (default: osPriorityNormal)

Specifies the initial thread priority with a value from osPriority_t.

Default: osPriorityNormal.

TZ_ModuleId_t tz_module

TrustZone module identifier.

TrustZone Thread Context Management Identifier to allocate context memory for threads. The RTOS kernel that runs in non-secure state calls the interface functions defined by the header file TZ_context.h. Can safely be set to zero for threads not using secure calls at all. See TrustZone RTOS Context Management.

Default: 0 not thread context specified.

reserved

reserved (must be 0)

Reserved for future use.

线程创建实例 - osThreadNew
  exp1:创建一个简单线程,使用默认线程属性和全局内存池中的内存(动态分配)      
1 __NO_RETURN void thread1 (void *argument) {
 2   // ...
 3   for (;;) {}
 4 }
 5  
 6 int main (void) {
 7   osKernelInitialize();
 8   ;
 9   osThreadNew(thread1, NULL, NULL);     // Create thread with default settings
10   ;
11   osKernelStart(); 
12 }      

  exp2:创建一个自定义堆栈大小的线程,依然使用内存池中的内存

1 __NO_RETURN void thread1 (void *argument) {
 2   // ...
 3   for (;;) {}
 4 }
 5  
 6 const osThreadAttr_t thread1_attr = {
 7   .stack_size = 1024                            // Create the thread stack with a size of 1024 bytes
 8 };
 9  
10 int main (void) {
11   ;  
12   osThreadNew(thread1, NULL, &thread1_attr);    // Create thread with custom sized stack memory
13   ;
14 }      

  exp3:采用静态堆栈创建线程

1 __NO_RETURN void thread1 (void *argument) {
 2   // ...
 3   for (;;) {}
 4 }
 5  
 6 static uint64_t thread1_stk_1[64];
 7  
 8 const osThreadAttr_t thread1_attr = {
 9   .stack_mem  = &thread1_stk_1[0],
10   .stack_size = sizeof(thread1_stk_1)
11 };
12  
13 int main (void) {
14   ;  
15   osThreadNew(thread1, NULL, &thread1_attr);    // Create thread with statically allocated stack memory
16   ;
17 }      

  exp4:采用静态任务控制块创建线程

1 #include "cmsis_os2.h"
 2  
 3 //include rtx_os.h for types of RTX objects
 4 #include "rtx_os.h"
 5 __NO_RETURN void thread1 (void *argument) {
 6   // ...
 7   for (;;) {}
 8 }
 9  
10 static osRtxThread_t thread1_tcb;
11  
12 const osThreadAttr_t thread1_attr = {
13   .cb_mem  = &thread1_tcb,
14   .cb_size = sizeof(thread1_tcb),
15 };
16  
17 int main (void) {
18   ;
19   osThreadNew(thread1, NULL, &thread1_attr);    // Create thread with custom tcb memory
20   ;
21 }      

  exp5:创建一个自定义优先级的线程

1 __NO_RETURN void thread1 (void *argument) {
 2   // ...
 3   for (;;) {}
 4 }
 5  
 6 const osThreadAttr_t thread1_attr = {
 7   .priority = osPriorityHigh                    //Set initial thread priority to high   
 8 };
 9  
10 int main (void) {
11   ;
12   osThreadNew(thread1, NULL, &thread1_attr);
13   ;
14 }      

  exp6:可连接的线程。在这个例子中,一个主线程使用osThreadJoinable属性创建了四个线程。它们将执行一些工作,并在完成后使用osThreadExit调用返回。osThreadJoin用于同步线程终止。

1 __NO_RETURN void worker (void *argument) {
 2   ; // work a lot on data[] 
 3   osDelay(1000U);
 4   osThreadExit();
 5 }
 6  
 7 __NO_RETURN void thread1 (void *argument) {
 8   osThreadAttr_t worker_attr;
 9   osThreadId_t worker_ids[4];
10   uint8_t data[4][10];
11   memset(&worker_attr, 0, sizeof(worker_attr));
12   worker_attr.attr_bits = osThreadJoinable;
13  
14   worker_ids[0] = osThreadNew(worker, &data[0][0], &worker_attr);
15   worker_ids[1] = osThreadNew(worker, &data[1][0], &worker_attr);
16   worker_ids[2] = osThreadNew(worker, &data[2][0], &worker_attr);
17   worker_ids[3] = osThreadNew(worker, &data[3][0], &worker_attr);
18  
19   osThreadJoin(worker_ids[0]);
20   osThreadJoin(worker_ids[1]);
21   osThreadJoin(worker_ids[2]);
22   osThreadJoin(worker_ids[3]);
23  
24   osThreadExit(); 
25 }      

  线程退出 - osThreadExit