欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

rt-thread学习1 - 线程

程序员文章站 2022-07-11 18:52:37
...

1. 线程相关状态

rt-thread学习1 - 线程

2. 线程相关API

线程相关就这几个流程

rt-thread学习1 - 线程

2.1 动态线程创建
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);
参数 描述
name 线程的名称;线程名称的最大长度由 rtconfig.h 中的宏 RT_NAME_MAX 指定,多余部分会被自动截掉
entry 线程入口函数
parameter 线程入口函数参数
stack_size 线程栈大小,单位是字节
priority 线程的优先级。优先级范围根据系统配置情况(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定义),如果支持的是 256 级优先级,那么范围是从 0~255,数值越小优先级越高,0 代表最高优先级,STM32支持32级
tick 线程的时间片大小。时间片(tick)的单位是操作系统的时钟节拍。当系统中存在相同优先级线程时,这个参数指定线程一次调度能够运行的最大时间长度。这个时间片运行结束时,调度器自动选择下一个就绪态的同优先级线程进行运行
返回 ——
thread 线程创建成功,返回线程句柄
RT_NULL 线程创建失败
2.2 创建静态线程
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);

看到没?只返回对错,连句柄,栈地址都要你提供,动态不用啊,说好大小,我返回你句柄

参数 描述
thread 线程句柄。线程句柄由用户提供出来,并指向对应的线程控制块内存地址
name 线程的名称;线程名称的最大长度由 rtconfig.h 中定义的 RT_NAME_MAX 宏指定,多余部分会被自动截掉
entry 线程入口函数
parameter 线程入口函数参数
stack_start 线程栈起始地址
stack_size 线程栈大小,单位是字节。在大多数系统中需要做栈空间地址对齐(例如 ARM 体系结构中需要向 4 字节地址对齐)
priority 线程的优先级。优先级范围根据系统配置情况(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定义),如果支持的是 256 级优先级,那么范围是从 0 ~ 255,数值越小优先级越高,0 代表最高优先级
tick 线程的时间片大小。时间片(tick)的单位是操作系统的时钟节拍。当系统中存在相同优先级线程时,这个参数指定线程一次调度能够运行的最大时间长度。这个时间片运行结束时,调度器自动选择下一个就绪态的同优先级线程进行运行
返回 ——
RT_EOK 线程创建成功
-RT_ERROR 线程创建失败
2.3 删除线程

这里仅将动态线程改变位close态,释放占用的堆栈还是需要空闲线程来执行

rt_err_t rt_thread_delete(rt_thread_t thread);
参数 描述
thread 要删除的线程句柄
返回 ——
RT_EOK 删除线程成功
-RT_ERROR 删除线程失败

静态线程是用下面这个:

rt_err_t rt_thread_detach (rt_thread_t thread);
参数 描述
thread 线程句柄,它应该是由 rt_thread_init 进行初始化的线程句柄。
返回 ——
RT_EOK 线程脱离成功
-RT_ERROR 线程脱离失败
2.4 启动线程

将刚初始化,还是初始态的线程改变为就绪态

rt_err_t rt_thread_startup(rt_thread_t thread);
参数 描述
thread 线程句柄
返回 ——
RT_EOK 线程启动成功
-RT_ERROR 线程起动失败
2.5 其他操作
  1. 获取当前运行的线程

    rt_thread_t rt_thread_self(void);
    
    返回 描述
    thread 当前运行的线程句柄
    RT_NULL 失败,调度器还未启动
  2. 让出处理器,重新开始调度

    1. 将自己挂在线程队列尾部,即有相同优先级线程会切换相同优先级线程,没有才是自己

      rt_err_t rt_thread_yield(void);
      
    2. pass

  3. 线程挂起态固定时间后再就绪态

    rt_err_t rt_thread_sleep(rt_tick_t tick);
    rt_err_t rt_thread_delay(rt_tick_t tick);
    rt_err_t rt_thread_mdelay(rt_int32_t ms);
    
    参数 描述
    tick/ms 线程睡眠的时间: sleep/delay 的传入参数 tick 以 1 个 OS Tick 为单位 ; mdelay 的传入参数 ms 以 1ms 为单位;
    返回 ——
    RT_EOK 操作成功
  4. 线程挂起

    官方不建议使用,使用往后要手动切换线程(调用rt_schedule())

    rt_err_t rt_thread_suspend (rt_thread_t thread);
    
    参数 描述
    thread 线程句柄
    返回 ——
    RT_EOK 线程挂起成功
    -RT_ERROR 线程挂起失败,因为该线程的状态并不是就绪状态
  5. 线程控制

    可以对线程进行一些控制,比如:更改优先级

    rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg);
    
    函数参数 描述
    thread 线程句柄
    cmd 指示控制命令
    arg 控制参数
    返回 ——
    RT_EOK 控制执行正确
    -RT_ERROR 失败

    cmd命令:

    • RT_THREAD_CTRL_CHANGE_PRIORITY:动态更改线程的优先级RT_THREAD_CTRL_STARTUP:开始运行一个线程,等同于 rt_thread_startup() 函数调用;

      RT_THREAD_CTRL_CLOSE:关闭一个线程,等同于 rt_thread_delete() 函数调用。

  6. 设置和删除空闲钩子

    空闲线程时会去执行一些任务,注意:不要往里面放能挂起的东西,比如:获取信号量

    rt_err_t rt_thread_idle_sethook(void (*hook)(void));
    rt_err_t rt_thread_idle_delhook(void (*hook)(void));
    
    函数参数 描述
    hook 设置的钩子函数
    返回 ——
    RT_EOK 设置成功
    -RT_EFULL 设置失败
    函数参数 描述
    hook 删除的钩子函数
    返回 ——
    RT_EOK 删除成功
    -RT_ENOSYS 删除失败
  7. 设置调度器钩子

    任务切换时会执行

    void rt_scheduler_sethook(void (*hook)(struct rt_thread* from, struct rt_thread* to));
    

    void hook(struct rt_thread* from, struct rt_thread* to);

    函数参数 描述
    from 表示系统所要切换出的线程控制块指针
    to 表示系统所要切换到的线程控制块指针