推荐星级:
  • 1
  • 2
  • 3
  • 4
  • 5

RT-Thread快速入门-线程管理(上)

更新时间:2023-10-03 07:03:46 大小:223K 上传用户:sun2152查看TA发布的资源 标签:RT-Thread 下载积分:1分 评价赚积分 (如何评价?) 打赏 收藏 评论(0) 举报

资料介绍

在 RT-Thread 中 , 最 基 本 的 调 度 单 位 是 线 程 , 其 他 RTOS 也 叫 任 务 。如 果 学 习 过 或 者 了 解 过 RTOS,任 务 这 种 叫 法 是 最 为 熟 知 的 。 本 篇 文 章 来 学 习 一 下 RT-Thread 线 程 方 面 的 内 容 。对 于 初 学 者 来 说 , 转 换 一 下 思 维 , 建 立 多 任 务 ( 线 程 ) 的 编 程 思 想 。 引 言 对 于 裸 机 编 程 ,整 个 软 件 系 统 只 有 一 个 线 程( 任 务 )在 执 行 ,实 现 方 式 是 通 过 一 个 大 循 环 完 成 的 。应 用 程 序 是 一 个 无 限 循 环 ,循 环 中 调 用 各 个 功 能 模 块 的 函 数 , 完 成 相 应 的 操 作 。 RTOS 是 一 个 多 任 务 系 统 ,可 以 把 总 体 功 能 划 分 为 多 个 小 模 块 ,每 个 小 模 块 独 立 运 行 完 成 某 项 功 能 ,即 将 任 务 分 解 。这 样 使 得 复 杂 项 目 的 实 现 变 得 简 单 了 。 关 于 为 什 么 要 用 RTOS, 或 者 说 RTOS 的 优 点 , 网 上 资 料 很 多 , 在 此 不 再 赘 述 。 线 程 基 础 1. 线 程 调 度 对 于 一 款 RTOS 来 说 , 最 核 心 的 部 分 就 是 线 程 ( 任 务 ) 调 度 器 。 调 度 器 的 作 用 是 根 据 调 度 算 法 来 决 定 当 前 需 要 执 行 的 线 程 。 RT-Thread 的 线 程 调 度 器 是 抢 占 式 的 , 基 于 优 先 级 对 线 程 进 行 调 度 。每 个 线 程 均 具 有 一 个 优 先 级 ,调 度 器 的 主 要 工 作 是 ,从 就 绪 线 程 列 表 中 查 找 最 高 优 先 级 线 程 , 然 后 将 CPU 的 使 用 权 分 配 给 它 。 " 可 抢 占 " 意 味 着 , 如 果 高 优 先 级 线 程 就 绪 或 者 满 足 运 行 条 件 , RT-Thread 马 上 将 CPU 的 控 制 权 交 给 高 优 先 级 线 程 。 2. 线 程 优 先 级 RT-Thread 线 程 的 优 先 级 表 示 线 程 被 调 度 的 优 先 程 度 。 每 个 线 程 都 具 有 优 先 级 ,对 于 重 要 的 线 程 ,应 该 赋 予 其 高 优 先 级 ,这 样 才 能 保 证 线 程 被 优 先 调 度 。 RT-Thread 最 大 支 持 256 个 优 先 级 ( 0~255) , 数 值 越 小 的 线 程 优 先 级 越 高 。 0 为 最 高 优 先 级 。 最 低 优 先 级 默 认 分 配 给 空 闲 线 程 , 用 户 一 般 不 用 。 可 以 根 据 实 际 情 况 配 置 优 先 级 个 数 , 对 于 ARM Cortex-M 系 列 , 普 遍 采 用 32 个 优 先 级 ( 0~31) 。 3. 时 间 片 RT-Thread 允 许 多 个 线 程 具 有 相 同 的 优 先 级 , 相 同 优 先 级 的 线 程 之 间 采 用 时 间 片 轮 转 的 方 式 进 行 调 度 。创 建 线 程 的 时 候 ,可 以 配 置 线 程 的 时 间 片 参 数 。 时 间 片 仅 对 优 先 级 相 同 的 就 绪 线 程 有 效 。 时 间 片 的 作 用 是 约 束 线 程 单 次 运 行 的 时 长 ,其 单 位 是 系 统 时 钟 节 拍 ( OS Tick) 。 4. 线 程 栈 RT-Thread 线 程 具 有 独 立 的 栈 , 当 进 行 线 程 切 换 时 , 会 将 当 前 线 程 的 上 下 文 存 在 栈 中 ,当 线 程 要 恢 复 运 行 时 ,再 从 栈 中 读 取 上 下 文 信 息 , 进 行 恢 复 。 线 程 栈 还 用 来 存 放 函 数 中 的 局 部 变 量 。当 一 个 函 数 调 用 另 外 一 个 函 数 时 , 函 数 中 的 局 部 变 量 会 暂 时 存 放 在 栈 中 。 线 程 栈 的 增 长 方 向 由 芯 片 架 构 决 定 的 :由 高 地 址 向 低 地 址 增 长 、由 低 地 址 向 高 地 址 增 长 。这 两 种 增 长 方 式 RT-Thread 均 支 持 。对 于 ARM Cortex-M 架 构 , 线 程 栈 构 造 如 下 图 所 示 : 5. 线 程 的 入 口 函 数 入 口 函 数 是 线 程 实 现 预 期 功 能 的 函 数 。线 程 的 入 口 函 数 由 用 户 设 计 , 一 般 有 以 下 两 种 形 式 :  无 线 循 环 模 式  这 种 线 程 会 一 直 被 系 统 循 环 调 度 , 执 行 任 务 , 不 会 删 除 。 void thread_entry(void *parameter) { while(1) { /* 线程处理 */ } }  顺 序 执 行 或 有 限 次 循 环 模 式  这 类 线 程 不 会 循 环 或 者 不 会 永 久 循 环 ,执 行 完 毕 之 后 ,线 程 将 被 系 统 自 动 删 除 。 void thread_entry(void *parameter) { /* 处理任务 */ ... } 线 程 状 态 对 于 单 CPU 来 说 ,系 统 运 行 过 程 中 ,同 一 时 刻 只 有 一 个 线 程 在 处 理 器 运 行 。 在 运 行 过 程 中 , 线 程 有 多 种 不 同 的 运 行 状 态 :  初 始 状 态 ,线 程 刚 创 建 还 未 开 始 运 行 时 处 于 的 状 态 ,此 状 态 下 ,线 程 不 参 与 调 度 。   就 绪 状 态 , 线 程 具 备 运 行 条 件 的 状 态 , 等 待 被 调 度 器 调 度 执 行 。   运 行 状 态 , 线 程 正 在 运 行 。   挂 起 状 态 ,也 称 为 阻 塞 状 态 。由 于 资 源 不 可 用 或 线 程 主 动 延 时 一 段 时 间 , 而 进 入 的 状 态 。 线 程 不 能 执 行 。   关 闭 状 态 。 线 程 运 行 结 束 处 于 的 状 态 。 此 时 线 程 不 参 与 调 度 。  下 图 是 各 个 状 态 之 间 的 转 换 图 ,通 过 此 图 可 以 对 RT-Thread 线 程 的 运 行 状 态 有 一 个 整 体 的 认 识 。 图 中 涉 及 到 的 系 统 调 用 函 数 ,在 后 面 的 学 习 会 进 行 详 细 讲 解 。此 处 进 行 简 单 的 说 明 :  rt_thread_create/init() 创 建 或 初 始 化 一 个 线 程 , 此 线 程 处 于 初 始 状 态 。   rt_thread_startup() 函 数 使 得 初 始 化 状 态 的 线 程 进 入 到 就 绪 状 态 。   rt_thread_delay(),rt_sem_take(), rt_mutex_take() 等 函 数 使 得 运 行 状 态 的 线 程 进 入 到 挂 起 状 态 。   rt_thread_resume(), rt_sem_release() 等 函 数 使 得 挂 起 状 态 的 线 程 返 回 到 就 绪 状 态 。   rt_thread_delete/detach() 函 数 将 挂 起 状 态 的 线 程 更 改 为 关 闭 状 态 。   rt_thread_exit(),处 于 运 行 状 态 的 线 程 ,运 行 结 束 ,在 线 程 的 最 后 部 分 调 用 此 函 数 , 将 状 态 更 改 为 关 闭 状 态 。  线 程 控 制 块 在 RT-Thread 中 , 线 程 控 制 块 由 结 构 体 struct rt_thread 表 示 。 线 程 控 制 块 是 操 作 系 统 用 于 管 理 线 程 的 一 个 数 据 结 构 ,它 会 存 放 线 程 的 一 些 信 息 , 例 如 优 先 级 、 线 程 名 称 、 线 程 状 态 等 。 线 程 控 制 块 也 包 含 线 程 与 线 程 之 间 连 接 用 的 链 表 结 构 ,线 程 等 待 事 件 集 合 等 。 详 细 定 义 如 下 , 列 出 了 关 键 结 构 成 员 , 并 加 入 了 注 释 , 了 解 即 可 : 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_uint32_t number_mask; ...... 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; 创 建 线 程 RT-Thread 提 供 了 先 管 理 相 关 的 系 统 函 数 : 包 含 : 创 建 / 初 始 化 线 程 、 启 动 线 程 、 运 行 线 程 、 删 除 / 脱 离 线 程 等 。 此 处 只 讲 解 如 何 创 建 一 个 线 程 。 在 RT-Thread 中 ,要 创 建 一 个 线 程 ,并 使 得 它 能 够 被 执 行 ,需 要 两 步 :  创 建 线 程 , 此 时 一 个 新 线 程 被 创 建 , 并 处 于 初 始 状 态 。   启 动 线 程 ,此 时 线 程 由 初 始 状 态 进 入 就 绪 状 态 ,可 以 被 调 度 器 执 行 。  1. 创 建 线 程 创 建 一 个 线 程 的 函 数 rt_thread_create() 定 义 如 下 : 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) 调 用 这 个 函 数 时 ,系 统 会 从 动 态 内 存 堆 中 分 配 一 个 线 程 句 柄( 线 程 控 制 块 ),并 按 照 参 数 中 指 定 的 栈 大 小 从 动 态 内 存 堆 中 分 配 相 应 的 空 间 。 函 数 的 各 个 参 数 解 释 如 下 :

部分文件列表

文件名 大小
RT-Thread快速入门-线程管理(上).pdf 223K

【关注B站账户领20积分】

全部评论(0)

暂无评论

上传资源 上传优质资源有赏金

  • 打赏
  • 30日榜单

推荐下载