Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread
内核
RT-Thread-API
RT-Thread隐藏的宝藏之completion
发布于 2021-01-19 17:51:22 浏览:6018
订阅该版
[tocm] ### 1. completion 是什么 `completion` 直接翻译过来是**完成**,所以我更愿意称 `rt_completion` 为 **完成量**。在 RT-Thread 的[文档中心](https://www.rt-thread.org/document/site/programming-manual/ipc1/ipc1/) 中讲线程间通讯(IPC)时,只介绍了,**信号量**, **互斥量**, **事件集**,其实 `rt_completion` 可以认为是**轻量级的二值信号量**。 ### 2. completion 怎么使用 completion 的使用非常简单 1. 定义一个完成量 ``` struct rt_completion completion; ``` 2. 初始化完成量 ``` rt_completion_init(&completion); ``` 3. 等待完成量 ``` rt_completion_wait(&completion); ``` 4. 释放完成量 ``` rt_completion_done(&completion); ``` ### 3. completion 的实现 completion 的 API 非常少,可以通过简单的代码去分析 1. **初始化完成量** ``` void rt_completion_init(struct rt_completion *completion) { rt_base_t level; RT_ASSERT(completion != RT_NULL); level = rt_hw_interrupt_disable(); completion->flag = RT_UNCOMPLETED; rt_list_init(&completion->suspended_list); rt_hw_interrupt_enable(level); } ``` 干了两件事: - 设置 **flag** 为 `RT_UNCOMPLETED` - 初始化完成量的链表 2. **等待完成量**(以下代码有删减) ``` rt_err_t rt_completion_wait(struct rt_completion *completion, rt_int32_t timeout) { result = RT_EOK; thread = rt_thread_self(); level = rt_hw_interrupt_disable(); if (completion->flag != RT_COMPLETED) { if (timeout == 0) { } else { /* reset thread error number */ thread->error = RT_EOK; /* suspend thread */ rt_thread_suspend(thread); /* add to suspended list */ rt_list_insert_before(&(completion->suspended_list), &(thread->tlist)); /* current context checking */ RT_DEBUG_NOT_IN_INTERRUPT; /* start timer */ if (timeout > 0) { /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(level); /* do schedule */ rt_schedule(); /* thread is waked up */ result = thread->error; level = rt_hw_interrupt_disable(); } } /* clean completed flag */ completion->flag = RT_UNCOMPLETED; return result; } ``` 主要做了以下工作: - 关中断:rt_hw_interrupt_disable(); - 挂起当前线程:rt_thread_suspend(thread); - 把挂起状态插入到线程的链表中:rt_list_insert_before - 确保当前函数执行不是在中断中:RT_DEBUG_NOT_IN_INTERRUPT; - 设置并启动定时器:rt_timer_start(&(thread->thread_timer)); - 开中断:rt_hw_interrupt_enable(level); - 开调度器:rt_schedule(); - 获取当前线程状态:result = thread->error; - 设置完成量的标志位:completion->flag = RT_UNCOMPLETED; - 返回线程状态 这样就完成了线程的挂起。 3. **完成完成量**(以下代码有删减) ``` void rt_completion_done(struct rt_completion *completion) { level = rt_hw_interrupt_disable(); completion->flag = RT_COMPLETED; if (!rt_list_isempty(&(completion->suspended_list))) { /* there is one thread in suspended list */ struct rt_thread *thread; /* get thread entry */ thread = rt_list_entry(completion->suspended_list.next, struct rt_thread, tlist); /* resume it */ rt_thread_resume(thread); rt_hw_interrupt_enable(level); /* perform a schedule */ rt_schedule(); } } ``` 主要做了以下工作: - 关中断:rt_hw_interrupt_disable(); - 设置 **flag** 为 `RT_COMPLETED` - 检查链表不为空:rt_list_isempty - 获取到当前等待完成量的句柄:rt_list_entry - 启动被挂起的线程:rt_thread_resume(thread); - 开中断:rt_hw_interrupt_enable(level); - 开调度:rt_schedule(); ### 4. completion 与信号量的对比 1. **completion** API 个数少,资源占用少,只能释放获取,不支持多次释放 2. **semaphore** API 个数多,资源占用较多,使用灵活,可以尝试获取,可以多次释放, ### 5. completion 如何加入工程 1. 标准版 **RT-Thread** 中的 **completion** 源码在 `"\rt-thread\components\drivers\src\completion.c"`在你要使用的文件中`#include completion.h`直接就可以使用。 2. Nano 版 **RT-Thread** 直接拷贝`completion.c` 和 `completion.h` 添加到工程就可以使用。
8
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
whj467467222
开源,分享,交流,共同进步
文章
32
回答
1210
被采纳
141
关注TA
发私信
相关文章
1
RT-THREAD在STM32H747平台上移植lwip
2
正点原子miniSTM32开发板读写sdcard
3
反馈rtt串口驱动对低功耗串口lpuart1不兼容的问题
4
Keil MDK 移植 RT-Thread Nano
5
RT1061/1052 带 RTT + LWIP和LPSPI,有什么坑要注意吗?
6
RT thread HID 如何收发数据
7
求一份基于RTT系统封装好的STM32F1系列的FLASH操作程序
8
RT-Thread修改项目名称之后不能下载
9
rt-studio编译c++
10
有木有移植rt-thread(nano)到riscv 32位MCU上
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
五分钟玩转RT-Thread新社区
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
6
国产MCU移植系列教程汇总,欢迎查看!
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
LWIP
SPI
Env
AT
FinSH
ART-Pi
Bootloader
CAN总线
Hardfault
文件系统
USB
DMA
RT-Thread
线程
stm32
RT-Thread Nano
SCons
MQTT
ESP8266
ota
packages_软件包
UART
rtthread
RTC
freemodbus
I2C
flash
cubemx
W5500
rt-smart
定时器
FAL
PWM
ADC
BSP
SDIO
msh
AB32VG1
Debug
C++_cpp
socket
SFUD
中断
编译报错
MicroPython
keil
LVGL
dfs
本月问答贡献
出出啊
1424
个答案
315
次被采纳
小小李sunny
1327
个答案
262
次被采纳
crystal266
490
个答案
144
次被采纳
whj467467222
1210
个答案
141
次被采纳
张世争
581
个答案
131
次被采纳
本月文章贡献
出出啊
4
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
crystal266
1
篇文章
1
次点赞
whj467467222
2
篇文章
2
次点赞
张世争
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部