IoT小能手

twowinter的学习小站 | 物联网技术及心得分享

zephyr笔记 2.1.1 线程的生命周期

我正在学习 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


阅读更多

扫码向博主提问

去开通我的Chat快问

iotisan

博客专家

物联网技术交流
  • 擅长领域:
  • 物联网
  • 嵌入式
  • LoRa
  • NB-IoT
  • ZigBee
版权声明:本文为twowinter原创文章,请联系微信公众号twowinter,未经博主允许不得转载。 https://blog.csdn.net/iotisan/article/details/79968620
文章标签: Zephyr
个人分类: 物 - 操作系统
上一篇zephyr笔记 1.5 hello world
下一篇zephyr笔记 2.1.2 线程的调度
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭