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

📄 ipc.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
	rt_hw_interrupt_enable(level);	return thread->error;}rt_err_t rt_event_control (rt_event_t event, rt_uint8 cmd, void* arg){	return RT_EOK;}#endif /* end of RT_USING_EVENT */#ifdef RT_USING_MAILBOXrt_err_t rt_mb_init(rt_mailbox_t mb, const char* name, void* msgpool, rt_size_t size, rt_uint8 flag){	RT_ASSERT(mb != RT_NULL);	/* init object */	rt_object_init(&(mb->parent.parent), RT_Object_Class_MailBox, name);	/* set parent flag */	mb->parent.parent.flag = flag;	/* init ipc object */	rt_ipc_object_init(&(mb->parent));	/* init mailbox */	mb->msg_pool = msgpool;	mb->size 	 = size;	mb->in_offset 	= 0;	mb->out_offset 	= 0;	return RT_EOK;}rt_err_t rt_mb_detach(rt_mailbox_t mb){	/* parameter check */	RT_ASSERT(mb != RT_NULL);	/* resume all suspended thread */	rt_ipc_object_resume_all(&(mb->parent));	/* detach mailbox object */	rt_object_detach(&(mb->parent.parent));	return RT_EOK;}rt_mailbox_t rt_mb_create (const char* name, rt_size_t size, rt_uint8 flag){	rt_mailbox_t mb;	/* allocate object */	mb = (rt_mailbox_t) rt_object_allocate(RT_Object_Class_MailBox, name);	if (mb == RT_NULL) return mb;	/* set parent */	mb->parent.parent.flag = flag;	/* init ipc object */	rt_ipc_object_init(&(mb->parent));	/* init mailbox */	mb->size 	 	= size;	mb->msg_pool 	= rt_malloc(mb->size);	if (mb->msg_pool == RT_NULL)	{		/* delete mailbox object */		rt_object_delete(&(mb->parent.parent));		return RT_NULL;	}	mb->in_offset 	= 0;	mb->out_offset 	= 0;	return mb;}rt_err_t rt_mb_delete (rt_mailbox_t mb){	/* parameter check */	RT_ASSERT(mb != RT_NULL);	/* resume all suspended thread */	rt_ipc_object_resume_all(&(mb->parent));	/* free mailbox pool */	rt_free(mb->msg_pool);	/* delete mailbox object */	rt_object_delete(&(mb->parent.parent));	return RT_EOK;}rt_err_t rt_mb_send (rt_mailbox_t mb, rt_uint32 value){	register rt_ubase_t temp;	/* parameter check */	RT_ASSERT(mb != RT_NULL);	/* disable interrupt */	temp = rt_hw_interrupt_disable();	/* mailbox is full */	if (mb->entry == mb->size)	{		/* enable interrupt */		rt_hw_interrupt_enable(temp);		return -RT_EFULL;	}	/* set ptr */	mb->msg_pool[mb->in_offset] = value;	/* increase input offset */	mb->in_offset = (++ mb->in_offset) % mb->size;	/* increase message entry */	mb->entry ++;	/* resume suspended thread */	if (mb->parent.suspend_thread_count > 0)	{		rt_ipc_object_resume(&(mb->parent));	}	/* enable interrupt */	rt_hw_interrupt_enable(temp);	rt_schedule();	return RT_EOK;}rt_err_t rt_mb_recv (rt_mailbox_t mb, rt_uint32* value, rt_int32 timeout){	struct rt_thread *thread;	register rt_ubase_t temp;	/* parameter check */	RT_ASSERT(mb != RT_NULL);	/* disable interrupt */	temp = rt_hw_interrupt_disable();	/* mailbox is empty */	if (mb->entry == 0)	{		/* get current thread */		thread = rt_thread_self();		/* reset error number in thread */		thread->error = RT_EOK;		/* no waiting, return timeout */		if (timeout == 0)		{			/* enable interrupt */			rt_hw_interrupt_enable(temp);			thread->error = -RT_ETIMEOUT;			return -RT_ETIMEOUT;		}		/* suspend current thread */		rt_ipc_object_suspend(&(mb->parent), thread);		/* has waiting time, start thread timer */		if (timeout > 0)		{#ifdef 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, &timeout);			rt_timer_start(&(thread->thread_timer));		}		/* enable interrupt */		rt_hw_interrupt_enable(temp);		/* re-schedule */		rt_schedule();		/* recv message */		if (thread->error != RT_EOK) /* maybe return RT_ETIMEOUT */			return thread->error;		/* disable interrupt */		temp = rt_hw_interrupt_disable();	}	/* fill ptr */	*value = mb->msg_pool[mb->out_offset];	/* increase output offset */	mb->out_offset = (++ mb->out_offset) % mb->size;	/* decrease message entry */	mb->entry --;	/* enable interrupt */	rt_hw_interrupt_enable(temp);	return RT_EOK;}rt_err_t rt_mb_control(rt_mailbox_t mb, rt_uint8 cmd, void* arg){	return RT_EOK;}#endif /* end of RT_USING_MAILBOX */#ifdef RT_USING_MESSAGEQUEUEstruct rt_mq_message{	struct rt_mq_message* next;};rt_err_t rt_mq_init(rt_mq_t mq, const char* name, void *msgpool, rt_size_t msg_size, rt_size_t pool_size, rt_uint8 flag){	struct rt_mq_message* head;	register rt_base_t temp;	/* parameter check */	RT_ASSERT(mq != RT_NULL);	/* init object */	rt_object_init(&(mq->parent.parent), RT_Object_Class_MessageQueue, name);	/* set parent flag */	mq->parent.parent.flag = flag;	/* init ipc object */	rt_ipc_object_init(&(mq->parent));	/* set messasge pool */	mq->msg_pool 	= msgpool;	/* get correct message size */	mq->msg_size	= RT_ALIGN(msg_size,  RT_ALIGN_SIZE);	mq->max_msgs	= pool_size / (mq->msg_size + sizeof(struct rt_mq_message));	/* init message list */	mq->msg_queue_head = RT_NULL;	mq->msg_queue_tail = RT_NULL;	/* init message empty list */	mq->msg_queue_free = RT_NULL;	for (temp = 0; temp < mq->max_msgs; temp ++)	{		head = (struct rt_mq_message*)((rt_uint8*)mq->msg_pool +			temp * (mq->msg_size + sizeof(struct rt_mq_message)));		head->next = mq->msg_queue_free;		mq->msg_queue_free = head;	}	/* the initial entry is zero */	mq->entry		= 0;	return RT_EOK;}rt_err_t rt_mq_detach(rt_mq_t mq){	/* parameter check */	RT_ASSERT(mq != RT_NULL);	/* resume all suspended thread */	rt_ipc_object_resume_all((struct rt_ipc_object*)mq);	/* detach message queue object */	rt_object_detach(&(mq->parent.parent));	return RT_EOK;}rt_mq_t rt_mq_create (const char* name, rt_size_t msg_size, rt_size_t max_msgs, rt_uint8 flag){	struct rt_messagequeue* mq;	struct rt_mq_message* head;	register rt_base_t temp;	/* allocate object */	mq = (rt_mq_t) rt_object_allocate(RT_Object_Class_MessageQueue, name);	if (mq == RT_NULL) return mq;	/* set parent */	mq->parent.parent.flag = flag;	/* init ipc object */	rt_ipc_object_init(&(mq->parent));	/* init message queue */	/* get correct message size */	mq->msg_size	= RT_ALIGN(msg_size, RT_ALIGN_SIZE);	mq->max_msgs	= max_msgs;	/* allocate message pool */	mq->msg_pool 	= rt_malloc(mq->msg_size * mq->max_msgs);	if (mq->msg_pool == RT_NULL)	{		rt_mq_delete(mq);		return RT_NULL;	}	/* init message list */	mq->msg_queue_head = RT_NULL;	mq->msg_queue_tail = RT_NULL;	/* init message empty list */	mq->msg_queue_free = RT_NULL;	for (temp = 0; temp < mq->max_msgs; temp ++)	{		head = (struct rt_mq_message*)((rt_uint8*)mq->msg_pool +			temp * (mq->msg_size + sizeof(struct rt_mq_message)));		head->next = mq->msg_queue_free;		mq->msg_queue_free = head;	}	/* the initial entry is zero */	mq->entry		= 0;	return mq;}rt_err_t rt_mq_delete (rt_mq_t mq){	/* parameter check */	RT_ASSERT(mq != RT_NULL);	/* resume all suspended thread */	rt_ipc_object_resume_all(&(mq->parent));	/* free mailbox pool */	rt_free(mq->msg_pool);	/* delete mailbox object */	rt_object_delete(&(mq->parent.parent));	return RT_EOK;}rt_err_t rt_mq_send (rt_mq_t mq, void* buffer, rt_size_t size){	register rt_ubase_t temp;	struct rt_mq_message *msg;	/* greater than one message size */	if (size > mq->msg_size) return -RT_ERROR;	/* disable interrupt */	temp = rt_hw_interrupt_disable();	/* get a free list, there must be an empty item */	msg = (struct rt_mq_message*)mq->msg_queue_free;	/* message queue is full */	if (msg == RT_NULL)	{		/* enable interrupt */		rt_hw_interrupt_enable(temp);		return -RT_EFULL;	}	/* move free list pointer */	mq->msg_queue_free = msg->next;	/* copy buffer */	rt_memcpy(msg + 1, buffer, size);	/* link msg to message queue */	if (mq->msg_queue_tail != RT_NULL)	{		/* if the tail exists, */		((struct rt_mq_message*)mq->msg_queue_tail)->next = msg;	}	/* the msg is the new tail of list, the next shall be NULL */	msg->next = RT_NULL;	/* set new tail */	mq->msg_queue_tail = msg;	/* if the head is empty, set head */	if (mq->msg_queue_head == RT_NULL)mq->msg_queue_head = msg;	/* increase message entry */	mq->entry ++;	/* resume suspended thread */	if (mq->parent.suspend_thread_count > 0)	{		rt_ipc_object_resume(&(mq->parent));	}	/* enable interrupt */	rt_hw_interrupt_enable(temp);	rt_schedule();	return RT_EOK;}rt_err_t rt_mq_urgent(rt_mq_t mq, void* buffer, rt_size_t size){	register rt_ubase_t temp;	struct rt_mq_message *msg;	/* greater than one message size */	if (size > mq->msg_size) return -RT_ERROR;	/* disable interrupt */	temp = rt_hw_interrupt_disable();	/* get a free list, there must be an empty item */	msg = (struct rt_mq_message*)mq->msg_queue_free;	/* message queue is full */	if (msg == RT_NULL)	{		/* enable interrupt */		rt_hw_interrupt_enable(temp);		return -RT_EFULL;	}	/* move free list pointer */	mq->msg_queue_free = msg->next;	/* copy buffer */	rt_memcpy(msg + 1, buffer, size);	/* link msg to the beginning of message queue */	msg->next = mq->msg_queue_head;	mq->msg_queue_head = msg;	/* if there is no tail */	if (mq->msg_queue_tail == RT_NULL) mq->msg_queue_tail = msg;	/* increase message entry */	mq->entry ++;	/* resume suspended thread */	if (mq->parent.suspend_thread_count > 0)	{		rt_ipc_object_resume(&(mq->parent));	}	/* enable interrupt */	rt_hw_interrupt_enable(temp);	rt_schedule();	return RT_EOK;}rt_err_t rt_mq_recv (rt_mq_t mq, void* buffer, rt_size_t size, rt_int32 timeout){	struct rt_thread *thread;	register rt_ubase_t temp;	struct rt_mq_message *msg;	/* disable interrupt */	temp = rt_hw_interrupt_disable();	/* mailbox is empty */	if (mq->entry == 0)	{		/* get current thread */		thread = rt_thread_self();		/* reset error number in thread */		thread->error = RT_EOK;		/* no waiting, return timeout */		if (timeout == 0)		{			/* enable interrupt */			rt_hw_interrupt_enable(temp);			thread->error = -RT_ETIMEOUT;			return -RT_ETIMEOUT;		}		/* suspend current thread */		rt_ipc_object_suspend(&(mq->parent), thread);		/* has waiting time, start thread timer */		if (timeout > 0)		{#ifdef 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, &timeout);			rt_timer_start(&(thread->thread_timer));		}		/* enable interrupt */		rt_hw_interrupt_enable(temp);		/* re-schedule */		rt_schedule();		/* recv message */		if (thread->error != RT_EOK) /* maybe return a RT_ETIMEOUT */			return thread->error;		/* disable interrupt */		temp = rt_hw_interrupt_disable();	}	/* get message from queue */	msg = (struct rt_mq_message*) mq->msg_queue_head;	/* move message queue head */	mq->msg_queue_head = msg->next;	/* reach queue tail, set to NULL */	if (mq->msg_queue_tail == msg) mq->msg_queue_tail = RT_NULL;	/* copy message */	rt_memcpy(buffer, msg + 1,		size > mq->msg_size? mq->msg_size : size);	/* put message to free list */	msg->next = (struct rt_mq_message*)mq->msg_queue_free;	mq->msg_queue_free = msg;	/* decrease message entry */	mq->entry --;	/* enable interrupt */	rt_hw_interrupt_enable(temp);	return RT_EOK;}rt_err_t rt_mq_control(rt_mq_t mq, rt_uint8 cmd, void* arg){	return RT_EOK;}#endif /* end of RT_USING_MESSAGEQUEUE *//** * @brief init operating system IPC module * * This function will init IPC module. * * @note This function shall be invoked in system init */void rt_system_ipc_init(){}/*@}*/

⌨️ 快捷键说明

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