① Implementation difference between Send Data Queue and Send Message Buffer
Message buffer has one more parameter to save that is message length. Similarly, in synchronous message passing the length needs to be passed to the contexts error code so that it would be returned in the rcv_mbf();
② ITRON implementation of sending message buffer
ER snd_mbf(ID mbfid, VP msg, UINT msgsz)
{
Sanity check on arguments
Enter critical section (Interrupt Disable)
/* Check any Rx task is waiting. Can copy message directly (synchronous message passing) */
Check head of receive wait queue
If there is valid task id {
Get the pointer to store data from task's context and copy the message;
Get the register for return error code and store the size of the message in it;
if task is waiting in Timeout
remove from timer queue
Set task status as Ready
if the task is NOT suspended {
Change the task to the Ready Queue of priority
If (the task priority is higher than the current){
call scheduler
return error code from scheduler
} else {
Exit critical section and return error code from it (E_OK)
(return E_OK)
}
} else {
Just delete the task from the receive wait queue
Exit critical section and return the error code from it (E_OK)
(return E_OK)
}
}
/* No Rx task is waiting here */
/* if have valid data length, need to put over the buffer */
If (have valid message size to send) {
Check sending wait queue for any waiting task at head of each priority level
if (No send task is waiting) {
/* No sending task; so put the message in the buffer */
/* if you could put successfully, then return. Otherwise, wait go and wait */
/* Try to put the message in the buffer as follows */
Just separate the count as signle and multiple
/* Because, if maximum message size is 1, then it will be very much
similar to the Data Queue. No separate count mechanism inside the buffer is needed */
If free size is 0, then set message copying = Failure;
Decrement the free count
Place the data
Update the put pointer
/* Otherwise extra data of two bytes are needed just to remeber the number of valid bytes placed on the buffer */
Reduce the free buffer count;
Put each and each byte of the length by checking the boundary of the buffer and wrapping.
Place the data with consideration of Wrapping the buffer out
message copying = Success;
If (message is copied successfully) {
Exit critical section and return the error code from it (E_OK)
return E_OK;
}
/* Otherwise go down for waiting. If message is longer than buffer, all calls may wait */
}
/* Some task is already waiting. You also need to wait */
If (polling mode)
Exit critical section and return E_TMOUT;
If (this function is called from interrupt context) or
If (called from task independent state ex: timer handlers) or
If (called from dispatch disabled state)
Return E_CTX;
If (Timeout value is specified) {
Add task into timer queue;
Set TCB flags that 'Waiting for send message buffer, Check for Timeout'
} else (Wait forever) {
Set TCB flags that 'Waiting forever for send message buffer'
}
Set data queue ID in TCB
Store the message pointer in context
Store the message size in context
Select Queue according to queueing order
If (Tasks should be granted in FIFO order)
Select send wait queue->Queue[0] as Queue
Else (Should be granted in Priority order)
Select send wait queue->Queue[Current Tasks Priority]
Change the task from ReadyQueue to the Data queue's send wait Queue
Schedule the tasks, since this task is going to sleep
(Once the task is released, execution will return here)
Return the value set by scheduler(Scheduler directly set return value before return here)
}
Exit critical section and return the error code from it (E_OK)
return E_OK;
}
No comments:
Post a Comment