zephyr笔记 2.1.1 线程的生命周期

xiaoxiao2021-02-28  26

我正在学习 Zephyr,一个很可能会用到很多物联网设备上的操作系统,如果你也感兴趣,可点此查看帖子zephyr学习笔记汇总。

1 前言

这节将会描述线程的创建,调度以及删除操作。

http://docs.zephyrproject.org/kernel/threads/lifecycle.html

2 概念

概念不复制了。

3 操作

3.1 Spawning a Thread

线程的创建,是通过定义它的栈区域,以及它的线程控制块,之后调用 k_thread_create()。其中的栈区域是通过 K_THREAD_STACK_DEFINE 来定义,保证在内存中建立起区域。

线程创建函数将会返回它的线程id,以此来对应线程。

如下是示例代码:

#define MY_STACK_SIZE 500 #define MY_PRIORITY 5 extern void my_entry_point(void *, void *, void *); K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE); struct k_thread my_thread_data; k_tid_t my_tid = k_thread_create(&my_thread_data, my_stack_area, K_THREAD_STACK_SIZEOF(my_stack_area), my_entry_point, NULL, NULL, NULL, MY_PRIORITY, 0, K_NO_WAIT);

Alternatively, a thread can be spawned at compile time by calling K_THREAD_DEFINE. Observe that the macro defines the stack area, control block, and thread id variables automatically. 或者,线程可以在编译时间通过调用 K_THREAD_DEFINE 来创建,栈区域、控制块、线程id都自动创建。

如下代码和上面的代码是一样的:

#define MY_STACK_SIZE 500 #define MY_PRIORITY 5 extern void my_entry_point(void *, void *, void *); K_THREAD_DEFINE(my_tid, MY_STACK_SIZE, my_entry_point, NULL, NULL, NULL, MY_PRIORITY, 0, K_NO_WAIT);

用户模式限制

这节仅适用于 CONFIG_USERSPACE 使能,用户线程想要创建新线程的情况。仍可以使用 k_thread_create() API,但有一些额外的限制需要注意下,否则调用会被停止:

The calling thread must have permissions granted on both the child thread and stack parameters; both are tracked by the kernel as kernel objects.The child thread and stack objects must be in an uninitialized state, i.e. it is not currently running and the stack memory is unused.The stack size parameter passed in must be equal to or less than the bounds of the stack object when it was declared.The K_USER option must be used, as user threads can only create other user threads.The K_ESSENTIAL option must not be used, user threads may not be considered essential threads.The priority of the child thread must be a valid priority value, and equal to or lower than the parent thread.

3.2 Dropping Permissions

If CONFIG_USERSPACE is enabled, a thread running in supervisor mode may perform a one-way transition to user mode using the k_thread_user_mode_enter() API. This is a one-way operation which will reset and zero the thread’s stack memory. The thread will be marked as non-essential.

3.3 终止线程

线程可以从自己的 entry point 函数中返回,即可终止线程。

如下代码展示如何终止线程。

void my_entry_point(int unused1, int unused2, int unused3) { while (1) { ... if (<some condition>) { return; /* thread terminates from mid-entry point function */ } ... } /* thread terminates at end of entry point function */ }

如果 CONFIG_USERSPACE 使能,终止一个线程将会标记线程和栈为未初始化,以方便他们再次使用。

4 建议用法

使用线程来处理那些不能在ISR的事务。

使用分开的线程来处理逻辑上分开又可以并行的操作。

5 配置选项

CONFIG_USERSPACE

6 API

下列线程API,都在 kernel.h 中提供了:

K_THREAD_DEFINE k_thread_create() k_thread_cancel() k_thread_abort() k_thread_suspend() k_thread_resume() K_THREAD_STACK_DEFINE K_THREAD_STACK_ARRAY_DEFINE K_THREAD_STACK_MEMBER K_THREAD_STACK_SIZEOF K_THREAD_STACK_BUFFER

End


转载请注明原文地址: https://www.6miu.com/read-1450164.html

最新回复(0)