rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

定时器组件的问题(timer.c)

Open slyant opened this issue 3 years ago • 3 comments

相关代码:

 void rt_timer_init(rt_timer_t  timer,
                   const char *name,
                   void (*timeout)(void *parameter),
                   void       *parameter,
                   rt_tick_t   time,
                   rt_uint8_t  flag)
{
    RT_ASSERT(timer != RT_NULL);
    RT_ASSERT(timeout != RT_NULL);
    RT_ASSERT(time < RT_TICK_MAX / 2);


    rt_object_init(&(timer->parent), RT_Object_Class_Timer, name);

    _timer_init(timer, timeout, parameter, time, flag);
}

rt_timer_t rt_timer_create(const char *name,
                           void (*timeout)(void *parameter),
                           void       *parameter,
                           rt_tick_t   time,
                           rt_uint8_t  flag)
{
    struct rt_timer *timer;

    RT_ASSERT(timeout != RT_NULL);
    RT_ASSERT(time < RT_TICK_MAX / 2);

    timer = (struct rt_timer *)rt_object_allocate(RT_Object_Class_Timer, name);
    if (timer == RT_NULL)
    {
        return RT_NULL;
    }

    _timer_init(timer, timeout, parameter, time, flag);

    return timer;
}

rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
{
    register rt_base_t level;

    /* parameter check */
    RT_ASSERT(timer != RT_NULL);
    RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);

    level = rt_hw_interrupt_disable();
    switch (cmd)
    {
    case RT_TIMER_CTRL_GET_TIME:
        *(rt_tick_t *)arg = timer->init_tick;
        break;

    case RT_TIMER_CTRL_SET_TIME:
        RT_ASSERT((*(rt_tick_t *)arg) < RT_TICK_MAX / 2);
        timer->init_tick = *(rt_tick_t *)arg;
        break;

    case RT_TIMER_CTRL_SET_ONESHOT:
        timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;
        break;

    case RT_TIMER_CTRL_SET_PERIODIC:
        timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;
        break;

    case RT_TIMER_CTRL_GET_STATE:
        if(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
        {
            /*timer is start and run*/
            *(rt_uint32_t *)arg = RT_TIMER_FLAG_ACTIVATED;
        }
        else
        {
            /*timer is stop*/
            *(rt_uint32_t *)arg = RT_TIMER_FLAG_DEACTIVATED;
        }
    case RT_TIMER_CTRL_GET_REMAIN_TIME:
        *(rt_tick_t *)arg =  timer->timeout_tick;
        break;

    default:
        break;
    }
    rt_hw_interrupt_enable(level);

    return RT_EOK;
}

RT_ASSERT(time < RT_TICK_MAX / 2);这个参数的处理建议不要这么“狠”,断言无异于“杀头”。很多时候物联设备需要远程配置定时参数,并保存到设备,如果不小心保存了错误的值(time > RT_TICK_MAX / 2),造成设备一启动就断言失败死机,连远程升级固件的机会都没有了,这是灾难!!!建议只做警告,然后修剪值为<RT_TICK_MAX / 2,或者返回创建失败。

slyant avatar May 13 '22 03:05 slyant

感谢反馈,我们看看这个问题

Guozhanxin avatar May 13 '22 06:05 Guozhanxin

同意这个观点,应该返回创建失败,生产环境尽量避免断言

wineee avatar May 20 '22 15:05 wineee

这块建议应该重新处理一下assert的使用时机, 如果开启rt_assert,说明目前是处于调试模式,而不是大规模产品部署,可以直接卡死来提醒工程师这块在编程上是有问题的。 如果关闭rt_assert,说明这个程序可能已经真正投入使用了,应该在检查值出现问题之后直接返回RT_ERROR或者其他错误码,让用户的应用层程序动态的处理这种错误。

mysterywolf avatar May 20 '22 21:05 mysterywolf