Thread states
RUNNING:thread正在运行
READY:线程准备就绪,等待执行
BLOCKED:线程处于阻塞状态,可能在延时、等待时间的发生或者挂起
TERMINATED:终止状态,资源还未释放
INACTIVE:线程还未创建或者已经终止,并且资源已经释放
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
osThreadId_t osThreadNew ( osThreadFunc_t func, void * argument, const osThreadAttr_t * attr )
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:
|
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. |
uint32_t | 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. |
void * | 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. |
uint32_t | 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. /** |
uint32_t | reserved | reserved (must be 0)
Reserved for future use. |
func:线程函数
argument:传递给线程函数的参数指针
attr:线程属性;NULL:使用默认线程属性
返回值:thread ID,可以被其他函数引用,NULL:创建失败
线程创建实例 - 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
函数osThreadExit终止调用线程。这允许线程采用 osThreadJoin 进行同步。
线程连接 - osThreadJoin
函数osThreadJoin等待由thread_id指定的线程终止。如果线程已经终止,那么osThreadJoin会立即返回。线程必须是可连接的。默认情况下,线程是用属性osThreadDetached创建的