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

📄 ipc.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
	/* parameter check */	RT_ASSERT(mb != RT_NULL);#ifdef RT_USING_HOOK	if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mb->parent.parent));#endif	/* 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);#ifdef RT_USING_HOOK	if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(mb->parent.parent));#endif	return RT_EOK;}/** * This function can get or set some extra attributions of a mailbox object. * * @param mb the mailbox object * @param cmd the execution command * @param arg the execution argument * * @return the error code */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;};/** * This function will initialize a message queue and put it under control of resource * management. * * @param mq the message object * @param name the name of message queue * @param msgpool the beginning address of buffer to save messages * @param msg_size the maximum size of message * @param pool_size the size of buffer to save messages * @param flag the flag of message queue * * @return the operation status, RT_EOK on successful */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;}/** * This function will detach a message queue object from resource management * * @param mq the message queue object * * @return the operation status, RT_EOK on successful */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;}#ifdef RT_USING_HEAP/** * This function will create a message queue object from system resource * * @param name the name of message queue * @param msg_size the size of message * @param max_msgs the maximum number of message in queue * @param flag the flag of message queue * * @return the created message queue, RT_NULL on error happen */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;}/** * This function will delete a message queue object and release the memory * * @param mq the message queue object * * @return the error code */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;}#endif/** * This function will send a message to message queue object, if there are threads  * suspended on message queue object, it will be waked up. * * @param mq the message queue object * @param buffer the message * @param size the size of buffer * * @return the error code */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;#ifdef RT_USING_HOOK	if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(mq->parent.parent));#endif	/* 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;}/** * This function will send urgently a message to message queue object, which means * the message will be inserted to the head of message queue. If there are threads  * suspended on message queue object, it will be waked up. * * @param mq the message queue object * @param buffer the message * @param size the size of buffer * * @return the error code */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;#ifdef RT_USING_HOOK	if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(mq->parent.parent));#endif	/* 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;}/** * This function will receive a message from message queue object, if there is no  * message in message queue object, the thread shall wait for a specified time. * * @param mq the message queue object * @param buffer the received message will be saved in * @param size the size of buffer * @param timeout the waiting time * * @return the error code */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;#ifdef RT_USING_HOOK	if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mq->parent.parent));#endif	/* 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);#ifdef RT_USING_HOOK	if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(mq->parent.parent));#endif	return RT_EOK;}/** * This function can get or set some extra attributions of a message queue object. * * @param mq the message queue object * @param cmd the execution command * @param arg the execution argument * * @return the error code */rt_err_t rt_mq_control(rt_mq_t mq, rt_uint8 cmd, void* arg){	return RT_EOK;}#endif /* end of RT_USING_MESSAGEQUEUE *//** * @ingroup SystemInit * This function will init IPC module. */void rt_system_ipc_init(){	/* nothing to be done */}/*@}*/

⌨️ 快捷键说明

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