[分享]在 rt-thread 中实现相对延时

发布于 2019-08-27 20:55:55
    本帖最后由 还没想好 于 2019-8-28 09:00 编辑


rt-thread 中支持的 rt-thread_mdelay 函数,是一个绝对延时函数。如果周期执行某一个动作,这个函数就不太适合。并且之前有帖子提到相对延时的问题。想必这个功能还是比较常用的。下面就贴一段代码供大家参考。
基本实现原理就是定时器进行周期定时,时间到了发送信号量。线程里面等待信号量,等到信号量了,代表定时时间到了。就去执行相应的动作。并且执行动作区间,定时器仍在运行,所以周期是准确的。

延时.png

下面是相对延时的实现代码:

#include 

struct d_until
{
struct rt_timer time;
struct rt_semaphore sem;
rt_tick_t tick;
};
typedef struct d_until * d_until_t;

static void thread_delay_until_handle(void *param)
{
d_until_t _obj = param;

rt_sem_release(&_obj->sem);
}

d_until_t delay_until_create(const char *name)
{
d_until_t _obj;

_obj = rt_calloc(1, sizeof(struct d_until));
if (_obj == RT_NULL)
{
return RT_NULL;
}
rt_timer_init(&_obj->time, name, thread_delay_until_handle,
_obj, 0, RT_TIMER_FLAG_PERIODIC);
rt_sem_init(&_obj->sem, name, 0, RT_IPC_FLAG_FIFO);
return _obj;
}

rt_err_t delay_until_run(d_until_t obj, rt_tick_t tick)
{
if (obj->tick != tick)
{
rt_timer_control(&obj->time, RT_TIMER_CTRL_SET_TIME, &tick);
obj->tick = tick;
rt_timer_start(&obj->time);
}
return rt_sem_take(&obj->sem, RT_WAITING_FOREVER);
}

void delay_until_stop(d_until_t obj)
{
rt_timer_stop(&obj->time);
while (rt_sem_take(&obj->sem, 0) == RT_EOK);
obj->tick = 0;
}

void delay_until_delete(d_until_t obj)
{
delay_until_stop(obj);
rt_timer_detach(&obj->time);
rt_sem_detach(&obj->sem);
}


上面代码中提供了 4 个 API

d_until_t delay_until_create(const char *name) 创建相对延时

rt_err_t delay_until_run(d_until_t obj, rt_tick_t tick)  相对延时
void delay_until_stop(d_until_t obj) 停止延时
void delay_until_delete(d_until_t obj)  删除相对延时


使用示例 :
int main(void)
{
void *delay;
rt_bool_t isrun = RT_TRUE;

delay = delay_until_create("delay"); // 创建相对延时
while (isrun)
{
printf("delay...\n");
delay_until_run(delay, 500); // 延时 500 个 tick
}
delay_until_delete(delay); // 删除相对延时

return 0;
}




查看更多

关注者
0
被浏览
911
6 个回答
armink
armink 2019-08-27
这么实用的功能应该放在 RT-Thread 源码功能呢

记得 freertos 也有类似功能
tyustli
tyustli 2019-08-27
    本帖最后由 tyustli 于 2019-8-27 22:38 编辑


mark delete 少了

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友