Esempio n. 1
0
/**
 * This function will start the timer
 *
 * @param timer the timer to be started
 *
 * @return the operation status, RT_EOK on OK, -RT_ERROR on error
 *
 */
rt_err_t rt_timer_start(rt_timer_t timer)
{
	struct rt_timer* t;
	register rt_base_t level;
	rt_list_t *n, *timer_list;

	/* timer check */
	RT_ASSERT(timer != RT_NULL);
	if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) return -RT_ERROR;

#ifdef RT_USING_HOOK
	if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(timer->parent));
#endif

	/* disable interrupt */
	level = rt_hw_interrupt_disable();

	/* get timeout tick, the max timeout tick shall not great than RT_TICK_MAX/2 */
	RT_ASSERT(timer->init_tick < RT_TICK_MAX/2);
	timer->timeout_tick = rt_tick_get() + timer->init_tick;

#ifdef RT_USING_TIMER_SOFT
	if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
	{
		/* insert timer to soft timer list */
		timer_list = &rt_soft_timer_list;
	}
	else
#endif
	{
		/* insert timer to system timer list */
		timer_list = &rt_timer_list;
	}

	for (n = timer_list->next; n != timer_list; n = n->next)
	{
		t = rt_list_entry(n, struct rt_timer, list);
		
		/*
		 * It supposes that the new tick shall less than the half duration of tick max.
		 */
		if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX/2)
		{
			rt_list_insert_before(n, &(timer->list));
			break;
		}
	}
	/* no found suitable position in timer list */
	if (n == timer_list)
	{
		rt_list_insert_before(n, &(timer->list));
	}
		
	timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;

	/* enable interrupt */
	rt_hw_interrupt_enable(level);

	return -RT_EOK;
}
Esempio n. 2
0
/**
 * This function will start the timer
 *
 * @param timer the timer to be started
 *
 * @return the operation status, RT_EOK on OK; RT_ERROR on error
 *
 */
rt_err_t rt_timer_start(rt_timer_t timer)
{
	rt_list_t *n;
	struct rt_timer* t;
	register rt_base_t level;

	/* timer check */
	RT_ASSERT(timer != RT_NULL);
	if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) return -RT_ERROR;

#ifdef RT_USING_HOOK
	if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(timer->parent));
#endif

	timer->timeout_tick = rt_tick_get() + timer->init_tick;

	/* disable interrupt */
	level = rt_hw_interrupt_disable();
	if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
	{/* insert timer to soft timer list */	
		for (n = rt_soft_timer_list.next; n != &rt_soft_timer_list; n = n->next)
		{
			t = rt_list_entry(n, struct rt_timer, list);
			if (t->timeout_tick > timer->timeout_tick)
			{
				rt_list_insert_before(n, &(timer->list));
				break;
			}
		}
		/* no found suitable position in timer list */
		if (n == &rt_soft_timer_list)
		{
			rt_list_insert_before(n, &(timer->list));
		}
	}
	else
	{/* insert timer to system timer list */	
		/* insert timer to system timer list */	
		for (n = rt_timer_list.next; n != &rt_timer_list; n = n->next)
Esempio n. 3
0
/**
 * This function will take a mutex, if the mutex is unavailable, the
 * thread shall wait for a specified time.
 *
 * @param mutex the mutex object
 * @param time the waiting time
 *
 * @return the error code
 */
rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time)
{
	register rt_base_t temp;
	struct rt_thread* thread;

	RT_ASSERT(mutex != RT_NULL);

	/* disable interrupt */
	temp = rt_hw_interrupt_disable();

	/* get current thread */
	thread = rt_thread_self();

#ifdef RT_USING_HOOK
	if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mutex->parent.parent));
#endif

#ifdef RT_IPC_DEBUG
	rt_kprintf("mutex_take: current thread %s, mutex value: %d, hold: %d\n", 
		thread->name, mutex->value, mutex->hold);
#endif

	/* reset thread error */
	thread->error = RT_EOK;

	if (mutex->owner == thread)
	{
		/* it's the same thread */
		mutex->hold ++;
	}
	else
	{
		/* in initialization status, the value is 1. Therefore, if the 
		 * value is great than 1, which indicates the mutex is avaible.
		 */
		if (mutex->value > 0)
		{
			/* mutex is available */
			mutex->value --;

			/* set mutex owner and original priority */
			mutex->owner = thread;
			mutex->original_priority = thread->current_priority;
			mutex->hold ++;
		}
		else
		{
			/* no waiting, return with timeout */
			if (time == 0 )
			{
				/* set error as timeout */
				thread->error = -RT_ETIMEOUT;

				/* enable interrupt */
				rt_hw_interrupt_enable(temp);

				return -RT_ETIMEOUT;
			}
			else
			{
				/* mutex is unavailable, push to suspend list */
#ifdef RT_IPC_DEBUG
				rt_kprintf("mutex_take: suspend thread: %s\n", thread->name);
#endif
				/* change the owner thread priority of mutex */
				if (thread->current_priority < mutex->owner->current_priority)
				{
					/* change the owner thread priority */
					rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY,
						&thread->current_priority);
				}

				/* suspend current thread */
				rt_ipc_object_suspend(&(mutex->parent), thread);

				/* has waiting time, start thread timer */
				if (time > 0)
				{
#ifdef RT_IPC_DEBUG
					rt_kprintf("mutex_take: start the timer of thread:%s\n", thread->name);
#endif
					/* reset the timeout of thread timer and start it */
					rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);
					rt_timer_start(&(thread->thread_timer));
				}

				/* enable interrupt */
				rt_hw_interrupt_enable(temp);

				/* do schedule */
				rt_schedule();

				if (thread->error != RT_EOK)
				{
					/* decrease suspended thread count */
					rt_ipc_object_decrease(&(mutex->parent));

					/* return error */
					return thread->error;
				}
				else
				{
					/* the mutex is taken successfully. */
					/* disable interrupt */
					temp = rt_hw_interrupt_disable();
				}
			}
		}
	}

	/* enable interrupt */
	rt_hw_interrupt_enable(temp);

#ifdef RT_USING_HOOK
	if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(mutex->parent.parent));
#endif

	return RT_EOK;
}
Esempio n. 4
0
/**
 * This function will take a semaphore, if the semaphore is unavailable, the
 * thread shall wait for a specified time.
 *
 * @param sem the semaphore object
 * @param time the waiting time
 *
 * @return the error code
 */
rt_err_t rt_sem_take (rt_sem_t sem, rt_int32_t time)
{
	register rt_base_t temp;
	struct rt_thread* thread;

	RT_ASSERT(sem != RT_NULL);

#ifdef RT_USING_HOOK
	if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(sem->parent.parent));
#endif

	/* disable interrupt */
	temp = rt_hw_interrupt_disable();

#ifdef RT_IPC_DEBUG
	rt_kprintf("thread %s take sem:%s, which value is: %d\n", rt_thread_self()->name, 
		((struct rt_object*)sem)->name, sem->value);
#endif
	if (sem->value > 0)
	{
		/* semaphore is available */
		sem->value --;

		/* enable interrupt */
		rt_hw_interrupt_enable(temp);
	}
	else
	{
		/* no waiting, return with timeout */
		if (time == 0 )
		{
			rt_hw_interrupt_enable(temp);
			return -RT_ETIMEOUT;
		}
		else
		{
			/* semaphore is unavailable, push to suspend list */
			/* get current thread */
			thread = rt_thread_self();

			/* reset thread error number */
			thread->error = RT_EOK;

#ifdef RT_IPC_DEBUG
			rt_kprintf("sem take: suspend thread - %s\n", thread->name);
#endif

			/* suspend thread */
			rt_ipc_object_suspend(&(sem->parent), thread);

			/* has waiting time, start thread timer */
			if (time > 0)
			{
#ifdef RT_IPC_DEBUG
				rt_kprintf("set thread:%s to timer list\n", thread->name);
#endif
				/* reset the timeout of thread timer and start it */
				rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);
				rt_timer_start(&(thread->thread_timer));
			}

			/* enable interrupt */
			rt_hw_interrupt_enable(temp);

			/* do schedule */
			rt_schedule();

			if (thread->error != RT_EOK)
			{
				/* decrease suspended thread count */
				rt_ipc_object_decrease(&(sem->parent));
				return thread->error;
			}
		}
	}

#ifdef RT_USING_HOOK
	if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(sem->parent.parent));
#endif

	return RT_EOK;
}