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

📄 msg.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 5 页
字号:
		(!task->msg_queue.task || task->msg_queue.task == rt_current)) {		rt_current->msg = task->msg = to_do;		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);		}		enqueue_blocked(rt_current, &task->ret_queue, 0);		rt_current->state |= RT_SCHED_RETURN;	} else {		rt_current->msg = to_do;                enqueue_blocked(rt_current, &task->msg_queue, 0);		rt_current->state |= RT_SCHED_RPC;	}	task->owndres += RPCINC;	pass_prio(task, rt_current);	rem_ready_current(rt_current);	rt_current->msg_queue.task = task;	RT_SCHEDULE_BOTH(task, cpuid);	if (rt_current->msg_queue.task == rt_current) {		*result = rt_current->msg;	} else {		rt_current->msg_queue.task = rt_current;		task = (RT_TASK *)0;	}	rt_global_restore_flags(flags);	return task;}/** * @ingroup rpc * @anchor rt_rpc_if * @brief Make a remote procedure call, only if the calling task will * not be blocked. * * rt_rpc_if tries to make a Remote Procedure Call (RPC). If the * receiver task is ready to accept a message rt_rpc_if sends the * message @e msg then it always block until a return is received. In * this case the caller task is blocked and queued up * in priority order while the receiver * inheredits the blocked sender priority if it is higher (lower in value) * than its. * If the receiver is not ready * rt_rpc_if returns immediately. The receiver task may get the * message with any rt_receive function. It can send the 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. * * @return On success, task (the pointer to the task that received the * message) is returned. If message has not been sent, 0 is * returned. On other failure, a special value is returned as * described below: * - @b 0: The task @e task was not ready to receive the message or *   	   it was killed before sending the reply. * - @b 0xFFFF: @e task does not refer to a valid task. * * See also: notes under @ref rt_rpc(). * * @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_rpc_if(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) &&	      (!task->msg_queue.task || task->msg_queue.task == rt_current)) {		rt_current->msg = task->msg = to_do;		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);		}		enqueue_blocked(rt_current, &task->ret_queue, 0);		rt_current->state |= RT_SCHED_RETURN;		task->owndres += RPCINC;		pass_prio(task, rt_current);		rem_ready_current(rt_current);		rt_current->msg_queue.task = task;		RT_SCHEDULE_BOTH(task, cpuid);		if (rt_current->msg_queue.task == rt_current) {			*result = rt_current->msg;		} else {			rt_current->msg_queue.task = rt_current;			task = (RT_TASK *)0;		}	} else {		task = (RT_TASK *)0;	}	rt_global_restore_flags(flags);	return task;}/**  * @ingroup rpc * @anchor rt_rpc_until * @brief Make a remote procedure call with an absolute timeout. * * rt_rpc_until makes a Remote Procedure Call. It sends the message @e * msg to the task @e task then always waits until a return is * received or a timeout occurs. 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 @ref * rt_receive() function. It can send the 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. * * @param time is an absolute timeout value. * * @return On success, task (the pointer to the task that received the * message) is returned. If message has not been sent or no answer * arrived, 0 is returned. * On other failure, a special value is returned as described below: * - @b 0: The message could not be sent or the answer did not arrived *    	   in time.   * - @b 0xFFFF: @e task does not refer to a valid task. * * See also: @ref 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> * See also the notes under @ref rt_rpc(). */RT_TASK *rt_rpc_until(RT_TASK *task, unsigned int to_do, unsigned int *result, 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)) {		rt_current->msg = task->msg = to_do;		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);		}		enqueue_blocked(rt_current, &task->ret_queue, 0);		rt_current->state |= (RT_SCHED_RETURN | RT_SCHED_DELAYED);	} else {		if ((rt_current->resume_time = time) <= rt_time_h) {			rt_global_restore_flags(flags);			return (RT_TASK *)0;		}		rt_current->msg = to_do;		enqueue_blocked(rt_current, &task->msg_queue, 0);		rt_current->state |= (RT_SCHED_RPC | RT_SCHED_DELAYED);	}	task->owndres += RPCINC;	pass_prio(task, rt_current);	rem_ready_current(rt_current);	rt_current->msg_queue.task = task;	enq_timed_task(rt_current);	RT_SCHEDULE_BOTH(task, cpuid);	if (rt_current->msg_queue.task == rt_current) {		*result = rt_current->msg;	} else {		dequeue_blocked(rt_current);		rt_current->msg_queue.task = rt_current;		task = (RT_TASK *)0;	}	rt_global_restore_flags(flags);	return task;}/**  * @ingroup rpc * @anchor rt_rpc_timed * @brief Make a remote procedure call with a relative timeout. * * rt_rpc_timed makes a Remote Procedure Call. It sends the message @e * msg to the task @e task then always waits until a return is * received or a timeout occurs. 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 @ref * rt_receive() function. It can send the 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. * * @param delay is a timeout relative to the current time. * * @return On success, task (the pointer to the task that received the * message) is returned. If message has not been sent or no answer * arrived, 0 is returned. * On other failure, a special value is returned as described below: * - @b 0: The message could not be sent or the answer did not arrived *    	   in time.   * - @b 0xFFFF: @e task does not refer to a valid task. * * See also: @ref 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> * See also the notes under @ref rt_rpc(). */RT_TASK *rt_rpc_timed(RT_TASK *task, unsigned int to_do, unsigned int *result, RTIME delay){	return rt_rpc_until(task, to_do, result, get_time() + delay);}/* ++++++++++++++++++++++++++++++ RPC_RETURN +++++++++++++++++++++++++++++++ *//** * @ingroup rpc * @anchor rt_isrpc * @brief Check if sender waits for reply or not. * * After receiving a message, by calling rt_isrpc a task can figure * out whether the sender task @e task is waiting for a reply or * not. Such an inquiry may be needed when a server task * must provide services to both rt_sends (FIXME) and rt_rtcs. * No answer is required if the message is sent by an @e rt_send function * or the sender called @ref rt_rpc_timed() or @ref rt_rpc_until() but it * is already timed out. * * @param task pointer to a task structure. * * @return If the task waits for a return reply, a nonzero value is returned. * 	   Otherwise 0 is returned. * * @note rt_isrpc does not perform any check on pointer task. rt_isrpc *  cannot figure out what RPC result the sender is waiting for.<br> * @ref rt_return() is intelligent enough to not send an answer to a * task which is not waiting for it. Therefore using rt_isrpc might not * be necessary.  */int rt_isrpc(RT_TASK *task){	return task->state & RT_SCHED_RETURN;}/** * @ingroup rpc * @anchor rt_return * @brief Return (sends) the result back to the task that made the  *  related remote procedure call. * * rt_return sends the result @e result to the task @e task. If the task * calling rt_rpc is not waiting the answer (i.e. killed or * timed out) this return message is silently discarded. The returning task * tries to release any previously inheredited priority inherediting the  * highest priority of any rpcing task still waiting for * a return, but only if does not own a resource semaphore. In the latter  * case it will keep the eighest inheredited priority till it has released * the resource ownership and no further message is waiting for a return. * That means that in the case priority inheritance is coming only * from rpced messages the task will return to its base priority when no * further message is queued for a return. Such a scheme automatically  * sets a dynamic priority ceiling in the case priorities are  * inheredited both from intertask messaging and resource semaphores  * ownership. * * @return On success, task (the pointer to the task that is got the * reply) is returned. If the reply message has not been sent, 0 is * returned. On other failure, a special value is returned as * described below: * - @b 0: The reply message was not delivered. * - @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 always safe. * * See also: notes under @ref rt_rpc(). */RT_TASK *rt_return(RT_TASK *task, 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_RETURN) && task->msg_queue.task == rt_current) {		int sched;		dequeue_blocked(task);		if (rt_current->owndres & RPCHLF) {			rt_current->owndres -= RPCINC;		}		if (!rt_current->owndres) {			sched = renq_current(rt_current, rt_current->base_priority);		} else if (!(rt_current->owndres & SEMHLF)) {			int priority;			sched = renq_current(rt_current, rt_current->base_priority > (priority = ((rt_current->msg_queue.next)->task)->priority) ? priority : rt_current->base_priority);		} else {			sched = 0;		}		task->msg = result;		task->msg_queue.task = task;		rem_timed_task(task);		if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_RETURN | RT_SCHED_DELAYED)) == RT_SCHED_READY) {			enq_ready_task(task);			if (sched) {				RT_SCHEDULE_BOTH(task, cpuid);			} else {				RT_SCHEDULE(task, cpuid);			}                } else if (sched) {                        rt_schedule();                }	} else {		task = (RT_TASK *)0;	}	rt_global_restore_flags(flags);	return task;}/* ++++++++++++++++++++++++++++++ RECEIVES +++++++++++++++++++++++++++++++++ *//** * @ingroup msg * @anchor rt_evdrp * @brief Eavedrop (spy) the content of a message. * * rt_evdrp spies the content of a message from the task specified by @e task  * while leaving it on the queue. To actually receive the message any of the  * rt_receive function must be used specifically. If task * is equal to 0, the caller eavdrops the first message of its receive queue,

⌨️ 快捷键说明

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