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

📄 msg.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 5 页
字号:
/**  * @file * Message handling functions. * @author Paolo Mantegazza * * @note Copyright (C) 1999-2003 Paolo Mantegazza * <mantegazza@aero.polimi.it> [ Specific COPYRIGHTS follow along the *  code ]  * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * @ingroup msg * @ingroup rpc *//** * @ingroup sched * @defgroup msg Message handling functions *//** * @ingroup sched * @defgroup rpc Remote procedure call functions */#include <rtai_schedcore.h>MODULE_LICENSE("GPL");/* +++++++++++++++++++++++ SHORT INTERTASK MESSAGES +++++++++++++++++++++++++ *//* +++++++++++++++++++++++++++++ ASYNC SENDS ++++++++++++++++++++++++++++++++ *//** * @ingroup msg * @anchor rt_send * @brief Send a message. * * rt_send sends the message @e msg to the task @e task. If the * receiver task is ready to get the message rt_send does not block * the sending task, but its execution can be preempted if the * receiving task has a higher priority. Otherwise the caller task is * blocked and queued up in priority order on the receive list of the sent * task. * * @param task is a pointer to a task structure. * * @param msg corresponds to the message that has to be sent. * * @return On success, the pointer to the task that received the message is * returned.<br> * 0 is returned if the caller is unblocked but the message has not * been sent, e.g. the task @e task was killed before receiving the * message.<br> * A special value is returned as described below in case of * a failure: * - @b 0xFFFF: @e task does not refer to a valid task. *  * @note Since all the messaging functions return a task address * 0xFFFF could seem an inappropriate return value. However on all the * CPUs RTAI runs on 0xFFFF is not an address that can be used by any * RTAI task, so it is should be safe always. */RT_TASK *rt_send(RT_TASK *task, unsigned int msg){	DECLARE_RT_CURRENT;	unsigned long flags;	if (task->magic != RT_TASK_MAGIC) {		return MSG_ERR;	}	flags = rt_global_save_flags_and_cli();	ASSIGN_RT_CURRENT;	if ((task->state & RT_SCHED_RECEIVE) &&	      (!task->msg_queue.task || task->msg_queue.task == rt_current)) {		task->msg = msg;		task->msg_queue.task = rt_current;		task->ret_queue.task = NOTHING;		rem_timed_task(task);		if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_RECEIVE | RT_SCHED_DELAYED)) == RT_SCHED_READY) {			enq_ready_task(task);			RT_SCHEDULE(task, cpuid);		}	} else {		rt_current->msg = msg;		rt_current->msg_queue.task = task;		enqueue_blocked(rt_current, &task->msg_queue, 0);		rt_current->state |= RT_SCHED_SEND;		rem_ready_current(rt_current);		rt_schedule();	}	if (rt_current->msg_queue.task != rt_current) {		rt_current->msg_queue.task = rt_current;		task = (RT_TASK *)0;	}	rt_global_restore_flags(flags);	return task;}/** * @ingroup msg * @anchor rt_send_if * @brief Send a message, only if the calling task will not be blocked. * * rt_send_if sends the message @e msg to the task @e task if the * latter is ready to receive, so that the caller task is never * blocked, but its execution can be preempted if the receiving task is * ready to receive and has a higher priority. * * @param task is a pointer to a task structure. * * @param msg corresponds to the message that has to be sent. * * @return the pointer to the task @e task that received the message  * is returned upon success.<br> * @e 0 is returned if the message has not been sent.<br> * A special value @e 0xFFFF is returned upon failure.<br><br> * The errors are described below:  * - @b 0: the task @e task was not ready to receive the message. * - @b 0xFFFF: @e task does not refer to a valid task. * * @note Since all the messaging functions return a task address, * 0xFFFF could seem an inappropriate return value. However on all the * CPUs RTAI runs on 0xFFFF is not an address that can be used by any * RTAI task, so it is should be safe always. (FIXME) */RT_TASK *rt_send_if(RT_TASK *task, unsigned int msg){	DECLARE_RT_CURRENT;	unsigned long flags;	if (task->magic != RT_TASK_MAGIC) {		return MSG_ERR;	}	flags = rt_global_save_flags_and_cli();	ASSIGN_RT_CURRENT;	if ((task->state & RT_SCHED_RECEIVE) &&	      (!task->msg_queue.task || task->msg_queue.task == rt_current)) {		task->msg = msg;		task->msg_queue.task = rt_current;		task->ret_queue.task = NOTHING;		rem_timed_task(task);		if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_RECEIVE | RT_SCHED_DELAYED)) == RT_SCHED_READY) {			enq_ready_task(task);			RT_SCHEDULE(task, cpuid);		}		if (rt_current->msg_queue.task != rt_current) {			rt_current->msg_queue.task = rt_current;			task = (RT_TASK *)0;		}	} else {		task = (RT_TASK *)0;	}	rt_global_restore_flags(flags);	return task;}/** * @ingroup msg * @anchor rt_send_until * brief Send a message with an absolute timeout. * * rt_send_until sends the message @e msg to the task @e task. If the * receiver task is ready to get the message, this function does not * block the sending task, but its execution can be preempted if the * receiving task has a higher priority. Otherwise the caller task is * blocked and queued up in priority order on the receive list of the sent * task. * In this case the function returns if: * - the caller task is in the first place of the waiting queue and *   the receiver gets the message and has a lower priority; * - a timeout occurs; * - an error occurs (e.g. the receiver task is killed). * * @param task is a pointer to a task structure. * * @param msg corresponds to the message that has to be sent. * * @param time is the absolute timeout value. * * @return the pointer to the task that received the message is * returned on success i.e. the message received before timeout * expiration.<br> * 0 is returned if the message has not been sent. * A special value is returned on other failure. The errors * are described below:   * - @b 0: operation timed out, message was not delivered;  * - @b 0xFFFF: @e task does not refer to a valid task. * * See also: @ref rt_send_timed(). * * @note Since all the messaging functions return a task address * 0xFFFF could seem an inappropriate return value.  However on all * the CPUs RTAI runs on 0xFFFF is not an address that can be used by * any RTAI task, so it is should be safe always. */RT_TASK *rt_send_until(RT_TASK *task, unsigned int msg, RTIME time){	DECLARE_RT_CURRENT;	unsigned long flags;	if (task->magic != RT_TASK_MAGIC) {		return MSG_ERR;	}	flags = rt_global_save_flags_and_cli();	ASSIGN_RT_CURRENT;	if ((task->state & RT_SCHED_RECEIVE) &&	      (!task->msg_queue.task || task->msg_queue.task == rt_current)) {		task->msg = msg;		task->msg_queue.task = rt_current;		task->ret_queue.task = NOTHING;		rem_timed_task(task);		if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_RECEIVE | RT_SCHED_DELAYED)) == RT_SCHED_READY) {			enq_ready_task(task);			RT_SCHEDULE(task, cpuid);		}	} else {		rt_current->msg_queue.task = task;		if ((rt_current->resume_time = time) > rt_time_h) {			rt_current->msg = msg;			enqueue_blocked(rt_current, &task->msg_queue, 0);			rt_current->state |= (RT_SCHED_SEND | RT_SCHED_DELAYED);			rem_ready_current(rt_current);			enq_timed_task(rt_current);			rt_schedule();		} else {			rt_current->queue.prev = rt_current->queue.next = &rt_current->queue;		}	}	if (rt_current->msg_queue.task != rt_current) {		dequeue_blocked(rt_current);		rt_current->msg_queue.task = rt_current;		task = (RT_TASK *)0;	}	rt_global_restore_flags(flags);	return task;}/** * @ingroup msg * @anchor rt_send_timed * brief Send a message with a relative timeout. * * rt_send_timed sends the message @e msg to the task @e task. If the  * receiver task is ready to get the message, this function does not * block the sending task, but its execution can be preempted if the * receiving task has a higher priority. Otherwise the caller task is * blocked and queued up in priority order on the receive list of the sent * task. * In this case the function returns if: * - the caller task is in the first place of the waiting queue and *   the receiver gets the message and has a lower priority; * - a timeout occurs; * - an error occurs (e.g. the receiver task is killed). * * @param task is a pointer to a task structure. * * @param msg corresponds to the message that has to be sent. * * @param delay is the timeout relative to the current time. * * @return on success, the pointer to the task that received the * message i.e. the message received before timeout expiration.<br> * 0 if the message has not been sent.<br> * A special value on other failure. The errors * are described below:   * - @b 0: operation timed out, message was not delivered;  * - @b 0xFFFF: @e task does not refer to a valid task. * * See also: @ref rt_send_until(). * * @note Since all the messaging functions return a task address * 0xFFFF could seem an inappropriate return value.  However on all * the CPUs RTAI runs on 0xFFFF is not an address that can be used by * any RTAI task, so it is should be safe always. (FIXME) */RT_TASK *rt_send_timed(RT_TASK *task, unsigned int msg, RTIME delay){	return rt_send_until(task, msg, get_time() + delay);}/* ++++++++++++++++++++++++++++++++ RPCS +++++++++++++++++++++++++++++++++++ *//** * @ingroup rpc * @anchor rt_rpc * @brief Make a remote procedure call * * rt_rpc makes a Remote Procedure Call (RPC). rt_rpc is used for * synchronous inter task messaging as it sends the message @e msg to the * task @e task and blocks waiting until a return is * received from the called task. So the caller task is always blocked * and queued up in priority order while the receiver * inheredits the blocked sender priority if it is higher (lower in value) * than its. * The receiver task may get the message with any * rt_receive function. It can send an answer with @ref rt_return(). * * @param task pointer to a RT_TASK structure. * * @param msg message to send. * * @param reply points to a buffer provided by the caller were the * returned result message, any 4 bytes integer, is to be place. * * @return On success, task (the pointer to the task that received the * message) is returned. If the message has not been sent (e.g. the * task @e task was killed before receiving the message) 0 is returned. * On other failure, a special value is returned as described below: * - @b 0: the receiver task was killed before receiving the message. * - @b 0xFFFF: @e task does not refer to a valid task. * * See also: rt_receive_*, @ref rt_return(), @ref rt_isrpc(). * * @note Since all the messaging functions return a task address, *       0xFFFF could seem an inappropriate return value. However on *       all the CPUs RTAI runs on, 0xFFFF is not an address that can *       be used by any RTAI task, so it is should be always safe.<br> *	 The trio @ref rt_rpc(), @ref rt_receive(), @ref rt_return() * 	 implement functions similar to its peers send-receive-replay * 	 found in QNX, except that in RTAI only four bytes messages * 	 contained in any integer can be exchanged. That's so because * 	 it is more efficient and often enough. If you need to pass  *       arbitrarely long messages see the extended intertask messaging *       functions.  Moreover note also that we prefer * 	 the idea of calling a function by using a message and then * 	 wait for a return value since it is believed to give a better *  	 idea of what is meant for synchronous message passing. For * 	 a more truly QNX like way of inter task messaging use the support * 	 of the upper cased functions: rt_Send-rt_Recieve-rt_Reply. */RT_TASK *rt_rpc(RT_TASK *task, unsigned int to_do, unsigned int *result){	DECLARE_RT_CURRENT;	unsigned long flags;	if (task->magic != RT_TASK_MAGIC) {		return MSG_ERR;	}	flags = rt_global_save_flags_and_cli();	ASSIGN_RT_CURRENT;	if ((task->state & RT_SCHED_RECEIVE) &&

⌨️ 快捷键说明

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