⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipc.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
					mutex->owner = thread;					mutex->hold ++;					/* set thread error */					thread->error = RT_EOK;				}			}		}	}	/* enable interrupt */	rt_hw_interrupt_enable(temp);	return RT_EOK;}rt_err_t rt_mutex_release(rt_mutex_t mutex){	register rt_base_t temp;	struct rt_thread* thread;	/* disable interrupt */	temp = rt_hw_interrupt_disable();#ifdef IPC_DEBUG	rt_kprintf("mutex_release:mutex value: %d, hold: %d\n", mutex->value, mutex->hold);#endif	/* get current thread */	thread = rt_thread_self();	/* mutex is only released by owner */	if (thread != mutex->owner)	{		thread->error = -RT_ERROR;		/* enable interrupt */		rt_hw_interrupt_enable(temp);		return -RT_ERROR;	}	/* decrease hold */	mutex->hold --;	/* if no hold */	if (mutex->hold == 0)	{		/* change the owner thread to original priority */		if (mutex->owner->init_priority != mutex->owner->current_priority)		{			rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY,				&(mutex->owner->init_priority));		}		/* wakeup suspended thread */		if (mutex->value <= 0 && mutex->parent.suspend_thread_count > 0)		{#ifdef IPC_DEBUG		rt_kprintf("mutex release: resume thread: %s\n", thread->name);#endif			/* resume thread */			rt_ipc_object_resume(&(mutex->parent));		}		/* increase value */		mutex->value ++;	}	/* enable interrupt */	rt_hw_interrupt_enable(temp);	rt_schedule();	return RT_EOK;}rt_err_t rt_mutex_control(rt_mutex_t mutex, rt_uint8 cmd, void* arg){	return RT_EOK;}#endif /* end of RT_USING_MUTEX */#ifdef RT_USING_FASTEVENTrt_err_t rt_fast_event_init(rt_fast_event_t event, const char* name, rt_uint8 flag){	register rt_base_t offset;	RT_ASSERT(event != RT_NULL);	/* init object */	rt_object_init(&(event->parent), RT_Object_Class_FastEvent, name);	/* set parent */	event->parent.flag = flag;	/* clear event set */	event->set = 0x00;	/* init thread list */	for (offset = 0; offset < 32; offset ++)	{		rt_list_init(&(event->thread_list[offset]));	}	return RT_EOK;}rt_err_t rt_fast_event_detach(rt_fast_event_t event){	register rt_base_t bit;	struct rt_thread* thread;	register rt_ubase_t level;	RT_ASSERT(event != RT_NULL);	for (bit = 0; bit < RT_EVENT_LENGTH; bit ++)	{		/* resume all suspend thread */		if (!rt_list_isempty(&(event->thread_list[bit])))		{			/* wakeup all suspend threads */			while (!rt_list_isempty(&(event->thread_list[bit])))			{				/* disable interrupt */				level = rt_hw_interrupt_disable();				/* get next suspend thread */				thread = rt_list_entry(event->thread_list[bit].next, struct rt_thread, tlist);				/* set error code to RT_ERROR */				thread->error = -RT_ERROR;				/* resume thread */				rt_thread_resume(thread);				/* enable interrupt */				rt_hw_interrupt_enable(level);			}		}	}	/* detach event object */	rt_object_detach(&(event->parent));	return RT_EOK;}rt_fast_event_t rt_fast_event_create (const char* name, rt_uint8 flag){	rt_fast_event_t event;	register rt_base_t offset;	/* allocate object */	event = (rt_fast_event_t) rt_object_allocate(RT_Object_Class_FastEvent, name);	if (event == RT_NULL) return event;	/* set parent */	event->parent.flag = flag;	/* clear event set */	event->set = 0x00;	/* init thread list */	for (offset = 0; offset < 32; offset ++)	{		rt_list_init(&(event->thread_list[offset]));	}	return event;}rt_err_t rt_fast_event_delete (rt_fast_event_t event){	register rt_base_t bit;	struct rt_thread* thread;	register rt_ubase_t level;	RT_ASSERT(event != RT_NULL);	for (bit = 0; bit < RT_EVENT_LENGTH; bit ++)	{		/* resume all suspend thread */		if (!rt_list_isempty(&(event->thread_list[bit])))		{			/* wakeup all suspend threads */			while (!rt_list_isempty(&(event->thread_list[bit])))			{				/* disable interrupt */				level = rt_hw_interrupt_disable();				/* get next suspend thread */				thread = rt_list_entry(event->thread_list[bit].next, struct rt_thread, tlist);				/* set error code to RT_ERROR */				thread->error = -RT_ERROR;				/* resume thread */				rt_thread_resume(thread);				/* enable interrupt */				rt_hw_interrupt_enable(level);			}		}	}	/* detach semaphore object */	rt_object_delete(&(event->parent));	return RT_EOK;}rt_err_t rt_fast_event_send(rt_fast_event_t event, rt_uint8 bit){	rt_uint32 offset;	register rt_ubase_t level;	struct rt_thread *thread;	struct rt_list_node *n;	/* parameter check */	RT_ASSERT(event != RT_NULL);	RT_ASSERT(bit < RT_EVENT_LENGTH);	offset = 1 << bit;	/* disable interrupt */	level = rt_hw_interrupt_disable();	event->set |= offset;	/* if thread list at offset is not empty */	n = event->thread_list[bit].next;	while (n != &(event->thread_list[bit]))	{		/* get thread */		thread = rt_list_entry(n, struct rt_thread, tlist);		/* move to next node */		n = n->next;		/* clear bit or not */		if (thread->event_info & RT_EVENT_FLAG_CLEAR)			event->set &= ~offset;		/* resume thread */		rt_thread_resume(thread);	}	/* enable interrupt */	rt_hw_interrupt_enable(level);	/* do a schedule */	rt_schedule();	return RT_EOK;}rt_err_t rt_fast_event_recv(rt_fast_event_t event, rt_uint8 bit, rt_uint8 option, rt_int32 timeout){ 	rt_base_t offset;	struct rt_thread* thread;	register rt_ubase_t level;	/* parameter check */	RT_ASSERT(event != RT_NULL);	RT_ASSERT(bit < RT_EVENT_LENGTH);	offset = 1 << bit;	/* disable interrupt */	level = rt_hw_interrupt_disable();	/* get current thread */	thread = rt_thread_self();	thread->error = RT_EOK;	/* get event successfully */	if (event->set & offset)	{		if (option & RT_EVENT_FLAG_CLEAR)			event->set &= ~ offset;		/* enable interrupt */		rt_hw_interrupt_enable(level);		return RT_EOK;	}	/* no event happen */	/* check waiting time */	if (timeout == 0)	{		/* no waiting */		thread->error = -RT_ETIMEOUT;	}	else	{		/* there are no event, suspend thread */		rt_thread_suspend(thread);		/* set event info in thread */		thread->event_info = option;		switch (event->parent.flag)		{		case RT_IPC_FLAG_FIFO:			rt_list_insert_after(&(event->thread_list[bit]), &(thread->tlist));			break;		case RT_IPC_FLAG_PRIO:			{				struct rt_list_node* n;				struct rt_thread* sthread;				/* find a suitable position */				for (n = event->thread_list[bit].next; n != &(event->thread_list[bit]); n = n->next)				{					sthread = rt_list_entry(n, struct rt_thread, tlist);					/* find out */					if (thread->current_priority < sthread->current_priority) break;				}				/* insert thread */				rt_list_insert_before(&(event->thread_list[bit]), &(thread->tlist));			}			break;		}		/* if there is timeout, active thread 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 a schedule */	rt_schedule();	return thread->error;}rt_err_t rt_fast_event_control (rt_fast_event_t event, rt_uint8 cmd, void* arg){	return RT_EOK;}#endif#ifdef RT_USING_EVENTrt_err_t rt_event_init(rt_event_t event, const char* name, rt_uint8 flag){	RT_ASSERT(event != RT_NULL);	/* init object */	rt_object_init(&(event->parent.parent), RT_Object_Class_Event, name);	/* set parent flag */	event->parent.parent.flag = flag;	/* init ipc object */	rt_ipc_object_init(&(event->parent));	/* init event */	event->set = 0;	return RT_EOK;}rt_err_t rt_event_detach(rt_event_t event){	/* parameter check */	RT_ASSERT(event != RT_NULL);	/* resume all suspended thread */	rt_ipc_object_resume_all(&(event->parent));	/* detach mailbox object */	rt_object_detach(&(event->parent.parent));	return RT_EOK;}rt_event_t rt_event_create (const char* name, rt_uint8 flag){	rt_event_t event;	/* allocate object */	event = (rt_event_t) rt_object_allocate(RT_Object_Class_Event, name);	if (event == RT_NULL) return event;	/* set parent */	event->parent.parent.flag = flag;	/* init ipc object */	rt_ipc_object_init(&(event->parent));	/* init event */	event->set = 0;	return event;}rt_err_t rt_event_delete (rt_event_t event){	/* parameter check */	RT_ASSERT(event != RT_NULL);	/* resume all suspended thread */	rt_ipc_object_resume_all(&(event->parent));	/* delete event object */	rt_object_delete(&(event->parent.parent));	return RT_EOK;}rt_err_t rt_event_send(rt_event_t event, rt_uint32 set){	struct rt_list_node *n;	struct rt_thread *thread;	register rt_ubase_t level;	register rt_base_t status;	/* parameter check */	RT_ASSERT(event != RT_NULL);	if (set == 0) return -RT_ERROR;	/* disable interrupt */	level = rt_hw_interrupt_disable();	/* set event */	event->set |= set;	if (event->parent.suspend_thread_count > 0)	{		/* search thread list to resume thread */		n = event->parent.suspend_thread.next;		while (n != &(event->parent.suspend_thread))		{			/* get thread */			thread = rt_list_entry(n, struct rt_thread, tlist);			status = -RT_ERROR;			if (thread->event_info & RT_EVENT_FLAG_AND)			{				if ((thread->event_set & event->set) == thread->event_set)				{					status = RT_EOK;				}			}			else if (thread->event_info & RT_EVENT_FLAG_OR)			{				if (thread->event_set & event->set)				{					status = RT_EOK;				}			}			/* move node to the nexe */			n = n->next;			/* condition is satisfied, resume thread */			if (status == RT_EOK)			{				/* resume thread, and thread list breaks out */				rt_thread_resume(thread);				/* decrease suspended thread count */				event->parent.suspend_thread_count--;				if (thread->event_info & RT_EVENT_FLAG_CLEAR)					event->set &= ~thread->event_set;			}		}	}	/* enable interrupt */	rt_hw_interrupt_enable(level);	/* do a schedule */	rt_schedule();	return RT_EOK;}rt_err_t rt_event_recv(rt_event_t event, rt_uint32 set, rt_uint8 option, rt_int32 timeout, rt_uint32* recved){	struct rt_thread *thread;	register rt_ubase_t level;	register rt_base_t status;	/* parameter check */	RT_ASSERT(event != RT_NULL);	if (set == 0) return -RT_ERROR;	/* init status */	status = -RT_ERROR;	/* disable interrupt */	level = rt_hw_interrupt_disable();	/* check event set */	if (option & RT_EVENT_FLAG_AND)	{		if ((event->set & set) == set) status = RT_EOK;	}	else if (option & RT_EVENT_FLAG_OR)	{		if (event->set & set) status = RT_EOK;	}	/* get current thread */	thread = rt_thread_self();	/* reset thread error */	thread->error = RT_EOK;	if (status == RT_EOK)	{		/* set received event */		*recved = event->set;		/* received event */		if (option & RT_EVENT_FLAG_CLEAR) event->set &= ~set;	}	else if (timeout == 0)	{		/* no waiting */		thread->error = -RT_ETIMEOUT;	}	else	{		/* fill thread event info */		thread->event_set  = set;		thread->event_info = option;		/* put thread to suspended thread list */		rt_ipc_object_suspend(&(event->parent), thread);		/* if there is a waiting timeout, active thread 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 a schedule */		rt_schedule();		if (thread->error != RT_EOK) return thread->error;		/* disable interrupt */		level = rt_hw_interrupt_disable();		/* get received event */		*recved = event->set;	}	/* enable interrupt */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -