📄 msg.c
字号:
* @param msg points to the message to be sent. * * @param size size of the message to be sent. * * @param delay is r timeout elative to the current time. * * @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 0: operation timed out, 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 safe always. */RT_TASK *rt_sendx_timed(RT_TASK *task, void *msg, int size, RTIME delay){ if (task) { SET_SEND_MCB(); return rt_send_timed(task, (unsigned int)&task_mcb, delay); } return 0;}/** * @ingroup rpc * @anchor rt_returnx * @brief Return (sends) an extended result back to the task that made the * related extended remote procedure call. * * rt_returns sends the result @e msg of size @e size to the task @e task. * If the task calling rt_rpcx 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_rpcx(). */RT_TASK *rt_returnx(RT_TASK *task, void *msg, int size){ if (task) { struct mcb_t *mcb; if ((mcb = (struct mcb_t *)task->msg)->rbytes < size) { size = mcb->rbytes; } if (size) { memcpy(mcb->rbuf, msg, size); } return rt_return(task, 0); } return 0;}#define DO_RCV_MSG() \ do { \ if ((*len = size <= mcb->sbytes ? size : mcb->sbytes)) { \ memcpy(msg, mcb->sbuf, *len); \ } \ } while (0)/** * @ingroup msg * @anchor rt_evdrpx * @brief Eavedrop (spy) the content of an extended message. * * rt_evdrpx 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_receivex function must be used specifically. If task * is equal to 0, the caller eavdrops the first message of its receive queue, * if any. rt_evdrpix never blocks. * * @param task is a pointer to a @e RT_TASK structure. * * @param msg points to the message to be eavedropped, without receive. * * @param size size of the message to be eavedropped. * * @param len is a pointer to an integer to be set to the actual len of the * eavedropped message. * * @return a pointer to the sender task is returned upon success.<br> * 0 is returned if no message is available. * A special value is returned on other failure. The errors * are described below: * - @b 0: the sender task was killed before sending 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 always safe. */RT_TASK *rt_evdrpx(RT_TASK *task, void *msg, int size, int *len){ struct mcb_t *mcb; if ((task = rt_evdrp(task, (unsigned int *)&mcb))) { DO_RCV_MSG(); return task; } return 0;}/** * @ingroup msg * @anchor rt_receivex * @brief Receive an extended message. * * rt_receivex gets an extended message @msg of size @size from the task * specified by @e task task. If task * is equal to 0, the caller accepts messages from any task. If there * is a pending message, rt_receivex does not block but can be * preempted if the task that rt_sent the just received message has a * higher priority. The task will not block if it receives rpcxed messages * since rpcxing tasks always wait for a returned message. Moreover it * inheredits the highest priority of any rpcxing task waiting on the receive * queue. The receiving task will then recover its priority as explained in * rt_returnx. Otherwise the caller task is blocked waiting for any * message to be sentx/rpcxed. * * @param task is a pointer to a @e RT_TASK structure. * * @param msg points to the message to be eavedropped, without receive. * * @param size size of the message to be eavedropped. * * @param len is a pointer to an integer to be set to the actual len of the * eavedropped message. * * @return a pointer to the sender task is returned upon success.<br> * 0 is returned if the caller is unblocked but no message has * been received (e.g. the task @e task was killed before sending the * message.)<br> * A special value is returned on other failure. The errors * are described below: * - @b 0: the sender task was killed before sending 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 always safe. */RT_TASK *rt_receivex(RT_TASK *task, void *msg, int size, int *len){ struct mcb_t *mcb; if ((task = rt_receive(task, (unsigned int *)&mcb))) { DO_RCV_MSG(); return task; } return 0;}/** * @ingroup msg * @anchor rt_receivex_if * @brief Receive an extended message, only if the calling task is not blocked. * * rt_receivex gets an extended message @msg of size @size from the task * specified by @e task task. If task * is equal to 0, the caller accepts messages from any task. The caller task * is never blocked but can be preempted if the task that rt_sentx the just * received message has a higher priority. * The task will not block if it receives rpcxed messages * since rpcxing tasks always wait for a returned message. Moreover it * inheredits the highest priority of any rpcxing task waiting on the receive * queue. The receiving task will then recover its priority as explained in * rt_returnx. Otherwise the caller task is blocked waiting for any * message to be sentx/rpcxed. * * @param task is a pointer to a @e RT_TASK structure. * * @param msg points to the message to be eavedropped, without receive. * * @param size size of the message to be eavedropped. * * @param len is a pointer to an integer to be set to the actual len of the * eavedropped message. * * @return a pointer to the sender task is returned upon success.<br> * 0 is returned if the caller is unblocked but no message has * been received (e.g. the task @e task was killed before sending the * message.)<br> * A special value is returned on other failure. The errors * are described below: * - @b 0: the sender task was killed before sending 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 always safe. */RT_TASK *rt_receivex_if(RT_TASK *task, void *msg, int size, int *len){ struct mcb_t *mcb; if ((task = rt_receive_if(task, (unsigned int *)&mcb))) { DO_RCV_MSG(); return task; } return 0;}/** * @ingroup msg * @anchor rt_receivex_until * @brief Receive an extended message with an absolute timeout. * * rt_receivex_until gets an extended message @msg of size @size from the task * specified by @e task task. If task * is equal to 0, the caller accepts messages from any task. If there * is a pending message, rt_receivex does not block but can be * preempted if the task that rt_sent the just received message has a * higher priority. The task will not block if it receives rpcxed messages * since rpcxing tasks always wait for a returned message. Moreover it * inheredits the highest priority of any rpcxing task waiting on the receive * queue. The receiving task will then recover its priority as explained in * rt_returnx. Otherwise the caller task is blocked waiting for any * message to be sentx/rpcxed. * * In this case these functions return if: * a sender sendxs a message and has a lower priority; * any rpcxed message is received; * - timeout occurs; * - an error occurs (e.g. the sender task is killed.) * @param task is a pointer to a @e RT_TASK structure. * * @param msg points to the message to be eavedropped, without receive. * * @param size size of the message to be eavedropped. * * @param len is a pointer to an integer to be set to the actual len of the * eavedropped message. * * @param time is an absolute timout value. * * @return a pointer to the sender task is returned upon success.<br> * 0 is returned if the caller is unblocked but no message has * been received (e.g. the task @e task was killed before sending the * message.)<br> * A special value is returned on other failure. The errors * are described below: * - @b 0: the sender task was killed before sending 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 always safe. */RT_TASK *rt_receivex_until(RT_TASK *task, void *msg, int size, int *len, RTIME time){ struct mcb_t *mcb; if ((task = rt_receive_until(task, (unsigned int *)&mcb, time))) { DO_RCV_MSG(); return task; } return 0;}/** * @ingroup msg * @anchor rt_receivex_timed * @brief Receive an extended message with a relative timeout. * * rt_receivex_until gets an extended message @msg of size @size from the task * specified by @e task task. If task * is equal to 0, the caller accepts messages from any task. If there * is a pending message, rt_receivex does not block but can be * preempted if the task that rt_sent the just received message has a * higher priority. The task will not block if it receives rpcxed messages * since rpcxing tasks always wait for a returned message. Moreover it * inheredits the highest priority of any rpcxing task waiting on the receive * queue. The receiving task will then recover its priority as explained in * rt_returnx. Otherwise the caller task is blocked waiting for any * message to be sentx/rpcxed. * * In this case these functions return if: * a sender sendxs a message and has a lower priority; * any rpcxed message is received; * - timeout occurs; * - an error occurs (e.g. the sender task is killed.) * @param task is a pointer to a @e RT_TASK structure. * * @param msg points to the message to be eavedropped, without receive. * * @param size size of the message to be eavedropped. * * @param len is a pointer to an integer to be set to the actual len of the * eavedropped message. * * @param delay is a timeout relative to the current time. * * @return a pointer to the sender task is returned upon success.<br> * 0 is returned if the caller is unblocked but no message has * been received (e.g. the task @e task was killed before sending the * message.)<br> * A special value is returned on other failure. The errors * are described below: * - @b 0: the sender task was killed before sending 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 always safe. */RT_TASK *rt_receivex_timed(RT_TASK *task, void *msg, int size, int *len, RTIME delay){ struct mcb_t *mcb; if ((task = rt_receive_timed(task, (unsigned int *)&mcb, delay))) { DO_RCV_MSG(); return task; } return 0;}/* +++++++++++++++++++++++++++++++ PROXIES ++++++++++++++++++++++++++++++++++ */// What any proxy is supposed to do, raw RTAI implementation.static void proxy_task(RT_TASK *me){ struct proxy_t *my; unsigned int ret; my = (struct proxy_t *)me->stack_bottom; while (1) { while (my->nmsgs) { atomic_dec((atomic_t *)&my->nmsgs); rt_rpc(my->receiver, *((unsigned int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -