RT-Thread线程内部机制(1)

1、RTOS

RTOS代表实时操作系统(Real-Time Operating System)。

一种专为实时应用程序设计的操作系统,用于控制嵌入式系统中的实时任务和事件。

RTOS的主要特点是能够满足严格的时间约束和响应要求。

2、线程

在RTOS中,线程(Thread)是一种表示任务执行的基本单位。

RTOS中的线程类似于通用操作系统中的线程概念,

在RTOS中,线程通常具有更严格的时间约束和实时性要求。

系统中有两种线程:

  • 系统线程:RT内核创建
  • 用户线程:用户应用程序创建

3、线程间切换的时候需要做什么工作

1、保存当前线程上下文

2、选择下一个线程

3、恢复下一个线程的上下文

4、切换堆栈和地址空间

5、更新调度器状态

6、执行下一个线程

4、什么叫保存线程

把暂停瞬间CPU内的值保存进栈里

5、保存线程需要保存哪些寄存器的哪些值?

4、如何创建线程

RT-Thread中创建线程的两种方式

                静态创建线程:rt_thread_init();

                动态创建线程:rt_thread_startup();

//静态创建线程
rt_err_t rt_thread_init(struct rt_thread* thread, //线程句柄
 const char* name, //线程名字
 void (*entry)(void* parameter), //入口函数
 void* parameter, //入口函数参数
 void* stack_start, //线程栈起始地址
 rt_uint32_t stack_size, //栈大小
 rt_uint8_t priority, //线程优先级
 rt_uint32_t tick); //线程时间片大小
//动态创建线程
rt_thread_t rt_thread_create(const char* name, //线程名字
 void (*entry)(void* parameter), //入口函数
 void* parameter, //入口函数参数
 rt_uint32_t stack_size, //栈大小
 rt_uint8_t priority, //线程优先级
 rt_uint32_t tick); //线程时间片大小

静态创建和动态创建的区别:

1、栈空间区别:
        动态线程:是系统自动从动态内存堆上分配栈空间与线程句柄
        静态线程:是由用户分配栈空间与线程句柄
2、参数区别:
静态创建线程:输入需要线程的句柄(线程控制块),返回值是RT_EOK / RT_ERROR
动态创建线程:返回值是线程的句柄(线程控制块),需要用启动线程函数启动
启动线程函数:
rt_err_t rt_thread_startup ( rt_thread_t thread );
输入创建的线程句柄
返回值: RT_EOK RT_ERROR

创建线程中重点需要两个东西

                1、线程函数:也就是入口函数

                2、线程的栈:也就是线程栈

线程的组成:

1、线程控制块:

        由结构体 struct rt_thread 表示,线程控制块是操作系统用于管理线程的一个数据结构。

        它存放线程的一些信息:
  • RT对象:线程名字、对象类型、标注位、对象列表、线程列表
  • 栈指针和入口指针:栈指针、入口函数指针参数栈指针地址栈大小
  • 错误代码:线程错误代码、线程状态
  • 优先级:当前优先级初始优先级
  • 其他:线程初始化数值、线程剩余计数值、内置线程定时器、线程退出清理函数、用户私有数据
  •  
    /**
    * Thread structure
    */
    struct rt_thread
    {
     /* rt 对象 */
     char name[RT_NAME_MAX]; /* 线程名字 */
     rt_uint8_t type; /* 对象类型 */
     rt_uint8_t flags; /* 标注位 */
     rt_list_t list; /* 对象列表 */
     rt_list_t tlist; /* 线程列表 */
     /* 栈指针和入口指针 */
     void *sp; /* 栈指针 */
     void *entry; /* 入口函数指针*/
     void *parameter; /* 参数 */
     void *stack_addr; /* 栈地址指针 */
     rt_uint32_t stack_size; /* 栈大小*/
     /* 错误代码 */
     rt_err_t error; /* 线程错误代码 */
     rt_uint8_t stat; /* 线程状态 */
     /* 优先级 */
     rt_uint8_t current_priority; /* 当前优先级 */
     rt_uint8_t init_priority; /* 初始优先级 */
    …………
     rt_ubase_t init_tick; /* 线程初始化计数值 */
     rt_ubase_t remaining_tick; /* 线程剩余计数值 */
     struct rt_timer thread_timer; /* 内置线程定时器 */
     void (*cleanup)(struct rt_thread *tid); /* 线程退出清理函数 */
     rt_uint32_t user_data; /* 用户私有数据*/
    };
    typedef struct rt_thread *rt_thread_t;

2、线程栈:

可以使用两种方法提供线程栈:静态分配、动态分配
栈的大小通常由用户定义
rt_uint32_t test_stack[512];
也可以在初始化时设置为较大的栈,比如 1K 2K
在进入系统后,通过终端的 list_thread 命令查看当前线程栈的最大使用率。
如果使用率超过 70% ,将线程栈再设置大 一点;
如果远低于 70% ,将线程栈设置小一点。

3、入口函数:

入口函数是线程要运行函数,由用户自行设计。
可分为无限循环模式顺序执行模式
无限循环:
void thread_entry(void* paramenter)
{
 while (1)
 {
 /* 等待事件的发生 */
 /* 对事件进行服务、进行处理 */
 }
}
在这种模式中,需要调用延时函数或者主动挂起。
顺序执行:
static void thread_entry(void* parameter)
{
 /* 处理事务 #1 */
 …
 /* 处理事务 #2 */
 …
 /* 处理事务 #3 */
}
执行完毕后,线程将被系统自动删除。

5、删除线程:

两种创建线程的方式对应不同的删除方式

// 删除使用 rt_thread_init()创建的线程
rt_err_t rt_thread_detach (rt_thread_t thread);

// 删除使用 rt_thread_create()创建的线程
rt_err_t rt_thread_delete (rt_thread_t thread); 
  • rt_thread_delete 并不是真正的删除线程,只是把线程状态状态改为 RT_THREAD_CLOSE
  • 真正的删除(释放线程控制块和线程栈),在下一次执行空闲线程时,由空闲线程删除
  • 线程本身不应调用 rt_thread_detach 脱离线程
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值