* @brief This function will send an urgent message to the messagequeue object. * * @note This function is almost the same as the rt_mq_send() function. The only difference is that * when sending an urgent message, the message is placed at the head of the messagequeue so that * the recipient can receive the urgent message first. * * @see rt_mq_send() * * @par
| 3655 | * If the return value is any other values, it means that the mailbox detach failed. |
| 3656 | */ |
| 3657 | rt_err_t rt_mq_urgent(rt_mq_t mq, const void *buffer, rt_size_t size) |
| 3658 | { |
| 3659 | rt_base_t level; |
| 3660 | struct rt_mq_message *msg; |
| 3661 | |
| 3662 | /* parameter check */ |
| 3663 | RT_ASSERT(mq != RT_NULL); |
| 3664 | RT_ASSERT(rt_object_get_type(&mq->parent.parent) == RT_Object_Class_MessageQueue); |
| 3665 | RT_ASSERT(buffer != RT_NULL); |
| 3666 | RT_ASSERT(size != 0); |
| 3667 | |
| 3668 | /* greater than one message size */ |
| 3669 | if (size > mq->msg_size) |
| 3670 | return -RT_ERROR; |
| 3671 | |
| 3672 | RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mq->parent.parent))); |
| 3673 | |
| 3674 | level = rt_spin_lock_irqsave(&(mq->spinlock)); |
| 3675 | |
| 3676 | /* get a free list, there must be an empty item */ |
| 3677 | msg = (struct rt_mq_message *)mq->msg_queue_free; |
| 3678 | /* message queue is full */ |
| 3679 | if (msg == RT_NULL) |
| 3680 | { |
| 3681 | rt_spin_unlock_irqrestore(&(mq->spinlock), level); |
| 3682 | |
| 3683 | return -RT_EFULL; |
| 3684 | } |
| 3685 | /* move free list pointer */ |
| 3686 | mq->msg_queue_free = msg->next; |
| 3687 | |
| 3688 | rt_spin_unlock_irqrestore(&(mq->spinlock), level); |
| 3689 | |
| 3690 | /* add the length */ |
| 3691 | ((struct rt_mq_message *)msg)->length = size; |
| 3692 | /* copy buffer */ |
| 3693 | rt_memcpy(GET_MESSAGEBYTE_ADDR(msg), buffer, size); |
| 3694 | |
| 3695 | level = rt_spin_lock_irqsave(&(mq->spinlock)); |
| 3696 | |
| 3697 | /* link msg to the beginning of message queue */ |
| 3698 | msg->next = (struct rt_mq_message *)mq->msg_queue_head; |
| 3699 | mq->msg_queue_head = msg; |
| 3700 | |
| 3701 | /* if there is no tail */ |
| 3702 | if (mq->msg_queue_tail == RT_NULL) |
| 3703 | mq->msg_queue_tail = msg; |
| 3704 | |
| 3705 | if(mq->entry < RT_MQ_ENTRY_MAX) |
| 3706 | { |
| 3707 | /* increase message entry */ |
| 3708 | mq->entry ++; |
| 3709 | } |
| 3710 | else |
| 3711 | { |
| 3712 | rt_spin_unlock_irqrestore(&(mq->spinlock), level); |
| 3713 | return -RT_EFULL; /* value overflowed */ |
| 3714 | } |
no test coverage detected