📄 mbx.c
字号:
CHK_MBX_MAGIC; flags = rt_global_save_flags_and_cli(); if (mbx->sndsem.count && mbx->frbs) { mbx->sndsem.count = 0; if (mbx->sndsem.type > 0) { (mbx->sndsem.owndby = mbx->owndby = rt_current)->owndres += 2; } rt_global_restore_flags(flags); msg_size = mbxput(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); rt_sem_signal(&mbx->sndsem); } else { rt_global_restore_flags(flags); } return msg_size;}/** * @brief Sends a message, only if the whole message can be passed * without blocking the calling task. * * rt_mbx_send_if tries to atomically send the message @e msg of @e * msg_size bytes to the mailbox @e mbx. It returns immediately and * the caller is never blocked. * * @return On success, the number of unsent bytes (0 or @e msg_size) * is returned. On failure a negative value is returned as described * below: * - @b EINVAL: @e mbx points to an invalid mailbox. */int _rt_mbx_send_if(MBX *mbx, void *msg, int msg_size, int space){ unsigned long flags; RT_TASK *rt_current = RT_CURRENT; CHK_MBX_MAGIC; flags = rt_global_save_flags_and_cli(); if (mbx->sndsem.count && msg_size <= mbx->frbs) { mbx->sndsem.count = 0; if (mbx->sndsem.type > 0) { (mbx->sndsem.owndby = mbx->owndby = rt_current)->owndres += 2; } rt_global_restore_flags(flags); mbxput(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); rt_sem_signal(&mbx->sndsem); return 0; } rt_global_restore_flags(flags); return msg_size;}/** * @brief Sends a message with absolute timeout. * * rt_mbx_send_until sends a message @e msg of @e msg_size bytes to * the mailbox @e mbx. The caller will be blocked until all bytes of * message is enqueued, timeout expires or an error occurs. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg is the message to be sent. * * @param msg_size corresponds to the size of the message. * * @param time is an absolute value for the timeout. * * @return On success, 0 is returned. * On failure a value is returned as described below: * - the number of bytes not received: an error is occured * in the queueing of all sending tasks or the timeout has expired. * - @b EINVAL: mbx points to an invalid mailbox. * * See also: notes under @ref rt_mbx_send_timed(). */int _rt_mbx_send_until(MBX *mbx, void *msg, int msg_size, RTIME time, int space){ RT_TASK *rt_current = RT_CURRENT; CHK_MBX_MAGIC; if (rt_sem_wait_until(&mbx->sndsem, time) > 1) { return msg_size; } while (msg_size) { if (mbx_wait_until(mbx, &mbx->frbs, time, rt_current)) { rt_sem_signal(&mbx->sndsem); return msg_size; } msg_size = mbxput(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); } rt_sem_signal(&mbx->sndsem); return 0;}/** * @brief Sends a message with relative timeout. * * rt_mbx_send_timed send a message @e msg of @e msg_size bytes to the * mailbox @e mbx. The caller will be blocked until all bytes of message * is enqueued, timeout expires or an error occurs. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg is the message to be sent. * * @param msg_size corresponds to the size of the message. * * @param delay is the timeout value relative to the current time. * * @return On success, 0 is returned. * On failure a value is returned as described below: * - the number of bytes not received: an error is occured * in the queueing of all sending tasks or the timeout has expired. * - @b EINVAL: mbx points to an invalid mailbox. * * See also: notes under @ref rt_mbx_send_until(). */int _rt_mbx_send_timed(MBX *mbx, void *msg, int msg_size, RTIME delay, int space){ return _rt_mbx_send_until(mbx, msg, msg_size, get_time() + delay, space);}/** * @brief Receives a message unconditionally. * * rt_mbx_receive receives a message of @e msg_size bytes from the * mailbox @e mbx. The caller will be blocked until all bytes of the * message arrive or an error occurs. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg points to a buffer provided by the caller. * * @param msg_size corresponds to the size of the message to be received. * * @return On success, 0 is returned. * On failure a value is returned as described below: * - the number of bytes not received: an error is occured * in the queueing of all receiving tasks. * - @b EINVAL: mbx points to an invalid mailbox. */int _rt_mbx_receive(MBX *mbx, void *msg, int msg_size, int space){ RT_TASK *rt_current = RT_CURRENT; CHK_MBX_MAGIC; if (rt_sem_wait(&mbx->rcvsem) > 1) { return msg_size; } while (msg_size) { if (mbx_wait(mbx, &mbx->avbs, rt_current)) { rt_sem_signal(&mbx->rcvsem); return msg_size; } msg_size = mbxget(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); } rt_sem_signal(&mbx->rcvsem); return 0;}/** * @brief Receives bytes as many as possible, without blocking the * calling task. * * rt_mbx_receive_wp receives at most @e msg_size of bytes of message * from the mailbox @e mbx then returns immediately. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg points to a buffer provided by the caller. * * @param msg_size corresponds to the size of the message to be received. * * @return On success, the number of bytes not received is returned. On * failure a negative value is returned as described below: * - @b EINVAL: mbx points to not a valid mailbox. */int _rt_mbx_receive_wp(MBX *mbx, void *msg, int msg_size, int space){ unsigned long flags; RT_TASK *rt_current = RT_CURRENT; CHK_MBX_MAGIC; flags = rt_global_save_flags_and_cli(); if (mbx->rcvsem.count && mbx->avbs) { mbx->rcvsem.count = 0; if (mbx->rcvsem.type > 0) { (mbx->rcvsem.owndby = mbx->owndby = rt_current)->owndres += 2; } rt_global_restore_flags(flags); msg_size = mbxget(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); rt_sem_signal(&mbx->rcvsem); } else { rt_global_restore_flags(flags); } return msg_size;}/** * @brief Receives a message only if the whole message can be passed * without blocking the calling task. * * rt_mbx_receive_if receives a message from the mailbox @e mbx if the * whole message of @e msg_size bytes is available immediately. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg points to a buffer provided by the caller. * * @param msg_size corresponds to the size of the message to be received. * * @return On success, the number of bytes not received (0 or @e msg_size) * is returned. On failure a negative value is returned as described * below: * - @b EINVAL: mbx points to an invalid mailbox. */int _rt_mbx_receive_if(MBX *mbx, void *msg, int msg_size, int space){ unsigned long flags; RT_TASK *rt_current = RT_CURRENT; CHK_MBX_MAGIC; flags = rt_global_save_flags_and_cli(); if (mbx->rcvsem.count && msg_size <= mbx->avbs) { mbx->rcvsem.count = 0; if (mbx->rcvsem.type > 0) { (mbx->rcvsem.owndby = mbx->owndby = rt_current)->owndres += 2; } rt_global_restore_flags(flags); mbxget(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); rt_sem_signal(&mbx->rcvsem); return 0; } rt_global_restore_flags(flags); return msg_size;}/** * @brief Receives a message with absolute timeout. * * rt_mbx_receive_until receives a message of @e msg_size bytes from * the mailbox @e mbx. The caller will be blocked until all bytes of * the message arrive, timeout expires or an error occurs. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg points to a buffer provided by the caller. * * @param msg_size corresponds to the size of the message received. * * @param time is an absolute value of the timeout. * * @return On success, 0 is returned. * On failure a value is returned as described below: * - the number of bytes not received: an error is occured * in the queueing of all receiving tasks or the timeout has expired. * - @b EINVAL: mbx points to an invalid mailbox. * * See also: notes under rt_mbx_received_timed(). */int _rt_mbx_receive_until(MBX *mbx, void *msg, int msg_size, RTIME time, int space){ RT_TASK *rt_current = RT_CURRENT; CHK_MBX_MAGIC; if (rt_sem_wait_until(&mbx->rcvsem, time) > 1) { return msg_size; } while (msg_size) { if (mbx_wait_until(mbx, &mbx->avbs, time, rt_current)) { rt_sem_signal(&mbx->rcvsem); return msg_size; } msg_size = mbxget(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); } rt_sem_signal(&mbx->rcvsem); return 0;}/** * @brief Receives a message with relative timeout. * * rt_mbx_receive_timed receives a message of @e msg_size bytes from * the mailbox @e mbx. The caller will be blocked until all bytes of * the message arrive, timeout expires or an error occurs. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg points to a buffer provided by the caller. * * @param msg_size corresponds to the size of the message received. * * @param delay is the timeout value relative to the current time. * * @return On success, 0 is returned. * On failure a value is returned as described below: * - the number of bytes not received: an error is occured * in the queueing of all receiving tasks or the timeout has expired. * - @b EINVAL: mbx points to an invalid mailbox. * * See also: notes under rt_mbx_received_until(). */int _rt_mbx_receive_timed(MBX *mbx, void *msg, int msg_size, RTIME delay, int space){ return _rt_mbx_receive_until(mbx, msg, msg_size, get_time() + delay, space);}/** * @brief Sends a message overwriting what already in the buffer * if there is no place for the message. * * rt_mbx_ovrwr_send sends the message @e msg of @e msg_size bytes * to the mailbox @e mbx overwriting what already in the mailbox * buffer if there is no place for the message. Useful for logging * purposes. It returns immediately and the caller is never blocked. * * @return On success, 0 is returned. On failure a negative value * is returned as described below: * - @b EINVAL: @e mbx points to an invalid mailbox. */int _rt_mbx_ovrwr_send(MBX *mbx, void *msg, int msg_size, int space){ unsigned long flags; RT_TASK *rt_current = RT_CURRENT; CHK_MBX_MAGIC; flags = rt_global_save_flags_and_cli(); if (mbx->sndsem.count) { mbx->sndsem.count = 0; if (mbx->sndsem.type > 0) { (mbx->sndsem.owndby = mbx->owndby = rt_current)->owndres += 2; } rt_global_restore_flags(flags); msg_size = mbxovrwrput(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); rt_sem_signal(&mbx->sndsem); } else { rt_global_restore_flags(flags); } return msg_size;}/* ++++++++++++++++++++++++++ NAMED MAIL BOXES ++++++++++++++++++++++++++++++ */#include <rtai_registry.h>/** * @brief Initializes a specifically typed (fifo queued, priority queued * or resource queued) mailbox identified by a name. * * _rt_typed_named_mbx_init initializes a mailbox of type @e qtype * and size @e size identified by @e name. Named mailboxed * are useful for use among different processes, kernel/user space and * in distributed applications, see netrpc. * * @param mbx_name is the mailbox name; since it can be a clumsy identifier, * services are provided to convert 6 characters identifiers to unsigned long * (see nam2num()). * * @param size corresponds to the size of the mailbox. * * @param qtype corresponds to the queueing policy: FIFO_Q, PRIO_Q or RES_Q. * * @return On success the pointer to the allocated mbx is returned. * On failure, NULL is returned. * * See also: notes under rt_mbx_init() and rt_typed_mbx_init(). */MBX *_rt_typed_named_mbx_init(unsigned long mbx_name, int size, int qtype){ MBX *mbx; if ((mbx = rt_get_adr_cnt(mbx_name))) { return mbx; } if ((mbx = rt_malloc(sizeof(MBX)))) { rt_typed_mbx_init(mbx, size, qtype); if (rt_register(mbx_name, mbx, IS_MBX, 0)) { return mbx; } rt_mbx_delete(mbx); } rt_free(mbx); return (MBX *)0;}/** * * @brief Deletes a named mailbox. * * rt_named_mbx_delete removes a mailbox previously created * with _rt_typed_named_mbx_init(). * * @param mbx is the pointer to the structure returned by a corresponding * call to _rt_typed_named_mbx_init. * * As it is done by all the named allocation functions delete calls have just * the effect of decrementing a usage count till the last is done, as that is * the one that really frees the object. * * @return On success, an integer >=0 is returned. * On failure, a negative value is returned as described below: * - @b EFAULT: deletion of mailbox failed. * * See also: notes under rt_mbx_delete(). */int rt_named_mbx_delete(MBX *mbx){ int ret; if (!(ret = rt_drg_on_adr_cnt(mbx))) { if (!rt_mbx_delete(mbx)) { rt_free(mbx); return 0; } else { return -EFAULT; } } return ret;}/* +++++++++++++++++++++++++ MAIL BOXES ENTRIES +++++++++++++++++++++++++++++ */struct rt_native_fun_entry rt_mbx_entries[] = { { { 0, rt_typed_mbx_init }, TYPED_MBX_INIT }, { { 0, rt_mbx_delete }, MBX_DELETE }, { { 0, _rt_typed_named_mbx_init }, NAMED_MBX_INIT }, { { 0, rt_named_mbx_delete }, NAMED_MBX_DELETE }, { { 1, _rt_mbx_send }, MBX_SEND }, { { 1, _rt_mbx_send_wp }, MBX_SEND_WP }, { { 1, _rt_mbx_send_if }, MBX_SEND_IF }, { { 1, _rt_mbx_send_until }, MBX_SEND_UNTIL }, { { 1, _rt_mbx_send_timed }, MBX_SEND_TIMED }, { { 1, _rt_mbx_receive }, MBX_RECEIVE }, { { 1, _rt_mbx_receive_wp }, MBX_RECEIVE_WP }, { { 1, _rt_mbx_receive_if }, MBX_RECEIVE_IF }, { { 1, _rt_mbx_receive_until }, MBX_RECEIVE_UNTIL }, { { 1, _rt_mbx_receive_timed }, MBX_RECEIVE_TIMED }, { { 1, _rt_mbx_ovrwr_send }, MBX_OVRWR_SEND }, { { 1, _rt_mbx_evdrp }, MBX_EVDRP }, { { 0, 0 }, 000 }};extern int set_rt_fun_entries(struct rt_native_fun_entry *entry);extern void reset_rt_fun_entries(struct rt_native_fun_entry *entry);int __rtai_mbx_init (void){ return set_rt_fun_entries(rt_mbx_entries);}void __rtai_mbx_exit (void){ reset_rt_fun_entries(rt_mbx_entries);}/*@}*/#ifndef CONFIG_RTAI_MBX_BUILTINmodule_init(__rtai_mbx_init);module_exit(__rtai_mbx_exit);#endif /* !CONFIG_RTAI_MBX_BUILTIN */#ifdef CONFIG_KBUILDEXPORT_SYMBOL(_rt_mbx_evdrp);EXPORT_SYMBOL(rt_typed_mbx_init);EXPORT_SYMBOL(rt_mbx_init);EXPORT_SYMBOL(rt_mbx_delete);EXPORT_SYMBOL(_rt_mbx_send);EXPORT_SYMBOL(_rt_mbx_send_wp);EXPORT_SYMBOL(_rt_mbx_send_if);EXPORT_SYMBOL(_rt_mbx_send_until);EXPORT_SYMBOL(_rt_mbx_send_timed);EXPORT_SYMBOL(_rt_mbx_receive);EXPORT_SYMBOL(_rt_mbx_receive_wp);EXPORT_SYMBOL(_rt_mbx_receive_if);EXPORT_SYMBOL(_rt_mbx_receive_until);EXPORT_SYMBOL(_rt_mbx_receive_timed);EXPORT_SYMBOL(_rt_mbx_ovrwr_send);EXPORT_SYMBOL(_rt_typed_named_mbx_init);EXPORT_SYMBOL(rt_named_mbx_delete);#endif /* CONFIG_KBUILD */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -