completion
直接翻译过来是完成,所以我更愿意称 rt_completion
为 完成量。在 RT-Thread 的文档中心 中讲线程间通讯(IPC)时,只介绍了,信号量, 互斥量, 事件集,其实 rt_completion
可以认为是轻量级的二值信号量。
completion 的使用非常简单
定义一个完成量
struct rt_completion completion;
初始化完成量
rt_completion_init(&completion);
等待完成量
rt_completion_wait(&completion);
释放完成量
rt_completion_done(&completion);
completion 的 API 非常少,可以通过简单的代码去分析
初始化完成量
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);
}
干了两件事:
RT_UNCOMPLETED
等待完成量(以下代码有删减)
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;
}
主要做了以下工作:
这样就完成了线程的挂起。
完成完成量(以下代码有删减)
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_COMPLETED
"\rt-thread\components\drivers\src\completion.c"
在你要使用的文件中#include completion.h
直接就可以使用。completion.c
和 completion.h
添加到工程就可以使用。
感谢分享
附上另一个宝藏ringbuffer:https://club.rt-thread.org/ask/article/27.html
啥时候讲讲
前排围观
@mysterywolf 我计划年前至少写
3
篇, 今年过年期间不能串门,应该可以更新完毕。能不能写完,先立个 FLAG感谢分享
感觉如上图截图位置,是不是理解上有一些不对?
我理解的是 : completion只能释放获取,不支持在某个线程中获取,并处于等待状态后,在另一个线程中再次获取
还请大佬指教
@chenyingchun 我在使用这个 API 的场景是,线程与中断。线程中获取,中断中释放。 是否支持多线程,我稍后看一下源码。
好像还需要手动添加路径