/* Fetch a message from queue 'q' and store it in 'm' */ int mbox_recv(int q, msg_t * m) { lock_acquire(&Q[q].l); print_trace("Recv", q, -1); /* If no messages available, wait until there is one */ while (Q[q].count == 0) { condition_wait(&Q[q].l, &Q[q].moreData); } /* copy header from mbox.buffer to m */ buffer_to_msg(Q[q].buffer, Q[q].tail, (char *) &m->size, MSG_T_HEADER_SIZE); /* Move tail to the body of message */ Q[q].tail = (Q[q].tail + MSG_T_HEADER_SIZE) % BUFFER_SIZE; /* Copy body of message from mbox.buffer to m->body */ buffer_to_msg(Q[q].buffer, Q[q].tail, (char *) &m->body[0], m->size); /* Move tail to the next message */ Q[q].tail = (Q[q].tail + MSG_SIZE(m) - MSG_T_HEADER_SIZE) % BUFFER_SIZE; /* Freeing space can satisy more than one writter */ condition_broadcast(&Q[q].moreSpace); Q[q].count--; lock_release(&Q[q].l); return 1; }
/* ************************************************************************************************************************ * Receive a msg * * Description: This function is called to receive a msg * * Arguments :q_b is the address of the queue buffer object * ----- * msg is the address of a point, and it will be filled data lwithin this api. * if you want to use the extension memcpy, make sure the msg address is 4 bytes aligned. * ----- * wait_option: is how the service behaves if the msg queue is full. * The wait options are * defined as follows: * RAW_NO_WAIT (0x00000000) * RAW_WAIT_FOREVER (0xFFFFFFFF) * timeout value (0x00000001 * through * 0xFFFFFFFE) * receive_size:is the msg size received. * * Returns * RAW_SUCCESS: raw os return success * RAW_BLOCK_DEL: if this queue is deleted. * RAW_BLOCK_TIMEOUT: queue is still full during waiting time when sending msg. * RAW_BLOCK_ABORT:queue is aborted during waiting time when sending msg. * RAW_STATE_UNKNOWN: possibly system error. * Note(s) * * ************************************************************************************************************************ */ RAW_U16 raw_queue_buffer_receive(RAW_QUEUE_BUFFER *q_b, RAW_TICK_TYPE wait_option, RAW_VOID *msg, MSG_SIZE_TYPE *receive_size) { RAW_U16 result; RAW_SR_ALLOC(); #if (RAW_QUEUE_BUFFER_FUNCTION_CHECK > 0) if (raw_int_nesting) { return RAW_NOT_CALLED_BY_ISR; } if (q_b == 0) { return RAW_NULL_OBJECT; } if (msg == 0) { return RAW_NULL_POINTER; } #endif RAW_CRITICAL_ENTER(); if (q_b->common_block_obj.object_type != RAW_QUEUE_BUFFER_OBJ_TYPE) { RAW_CRITICAL_EXIT(); return RAW_ERROR_OBJECT_TYPE; } if (!is_buffer_empty(q_b)) { *receive_size = buffer_to_msg(q_b, msg); RAW_CRITICAL_EXIT(); return RAW_SUCCESS; } if (wait_option == RAW_NO_WAIT) { RAW_CRITICAL_EXIT(); return RAW_NO_PEND_WAIT; } SYSTEM_LOCK_PROCESS(); raw_task_active->msg = msg; raw_pend_object((RAW_COMMON_BLOCK_OBJECT *)q_b, raw_task_active, wait_option); RAW_CRITICAL_EXIT(); raw_sched(); result = block_state_post_process(raw_task_active, 0); /*if get the msg successful then take it*/ if (result == RAW_SUCCESS) { *receive_size = raw_task_active->qb_msg_size; } return result; }