Blame |
Last modification |
View Log
| RSS feed
%----------------------------------------------------------------------------
\section{Communication Ports \footnote{The S.Ha.R.K. communication ports are
directly derived from the previous varsions of the Hartik Kernel.}}
%----------------------------------------------------------------------------
S.Ha.R.K. communication ports allow tasks to exchange messages. Each
port is uniquely identified by a symbolic name (i.e., a string of
characters); a task willing to use this communication facility has
to open the channel using the
\texttt{port\_create()} call, thus becoming
the owner of the resource. Any other task that wants to use this communication
end-point to send or receive data needs to connect to it by using
the \texttt{port\_connect()} primitive.
S.Ha.R.K. offers three types of ports:
\begin{itemize}
\item \texttt{STREAM}: it is a one-to-one communication facility, which
can be opened either by the reader or by the writer task. The task
executing the \texttt{port\_create()} must specify the message size
and maximum number of messages in the queue. The task executing the
\texttt{port\_connect()} must only specify the size of the messages
it wants to receive/send, which can be different from the one specified
by the owner. For example, a task may open a port for reading messages
of 4 bytes, while another task can connect to it to write one-byte
messages. This mechanism turns out to be useful for character oriented
device drivers which need to fill a given structure, before the message
can be processed further by a higher-level task.
\item \texttt{MAILBOX}: it is a many-to-one communication facility, thought
for being used in classical client/server mechanisms. This kind of
port can only be opened by the reader task (the server) which wants
to receive data from writer tasks (the clients). Message size is fixed
and defined by the reader.
\item \texttt{STICK}: it is a one-to-many communication facility intended
to be used for exchanging periodic state-messages, for which the most
recent information is relevant. It can be opened only by the (unique)
writer task and the reading tasks must connect to it. It contains
just one message and any new message posted by the writer will overwrite
the previous one. Messages are non-consumable: a reader task can perform
many readings of a given message until the writer posts a new one.
\end{itemize}
The first two kinds of port implement the synchronous communication
paradigm, while \texttt{STICK} ports implement an asynchronous (state-message)
paradigm. It is worth noting that in order to protect the internal
data structures, \texttt{STREAM} ports use semaphores for synchronizing
the accesses, \texttt{STICK} ports just use a mutual exclusion semaphore,
and the \texttt{MAILBOX} ports use both kinds of semaphores.
For this reason, \texttt{MAILBOX} and \texttt{STICK} ports should
not be used by critical tasks, whereas \texttt{STREAM} ports can be
used by any task requiring a state-message non-blocking semantics.
Moreover, the execution time of a transaction depends on the message
size (the message is copied in/from the buffer when a send/receive
is performed). The semantics associated with each port is graphically
illustrated in Figure \ref{fg:port-type}.
An application that uses the communication ports, must register the
HARTPORT Module. Please see Volume III - S.Ha.R.K. Modules for details.
\begin{figure}
\begin{center}\includegraphics[width=8cm]{port.eps}\end{center}
\caption{HARTIK ports.\label{fg:port-type}}
\end{figure}
%----------------------------------------------------------------------------
\begin{intest}
PORT\_CREATE\index{port\_create()}
\end{intest}
\begin{description}
\item [\textbf{PORT port\_create(char {*}name, int dim, int num,
int type, int mode);}]
\item [\textbf{Description:}]It opens the port identified by the string
\texttt{name}.
The argument \texttt{dim} specifies the message size in bytes, \texttt{num}
specifies the queue size, \texttt{type} the port type (\texttt{STREAM},
\texttt{MAILBOX}, or \texttt{STICK}), and \texttt{mode} the access
mode (\texttt{READ} or \texttt{WRITE}).
\item [\textbf{Return Value:}] The primitive returns the port identifier,
which identifies the connection between the port and the task, and
not the port itself, which is identified through its name. A return
value -1 indicates that an error is occurred.
\item [\textbf{See also}:] \texttt{port\_delete(), port\_connect(),
port\_disconnect(), port\_send(), port\_receive()}.
\end{description}
\begin{description}
\item [Example:\label{pg:port-ex}]
\item \texttt{TASK demo(void)} \{
\item \texttt{~~PORT p; }
\item \texttt{~~char msg{[}6{]}; }
\item \texttt{~~\ldots{}}
\item \texttt{~~/{*} Demo task, of NRT type, opens the \char`\"{}goofy\char`\"{}
port {*}/}
\item \texttt{~~/{*} and sends a message of 6 bytes. {*}/}
\item \texttt{~~p = port\_create(\char`\"{}goofy\char`\"{}, 6, 8, STREAM,
WRITE);}
\item \texttt{~~\ldots{}}
\item \texttt{~~port\_send(p, msg, BLOCK); }
\item \texttt{\}}
\item \texttt{~}
\item \texttt{TASK duro(void)} \{
\item \texttt{~~PORT q; }
\item \texttt{~~char msg{[}2{]}; }
\item \texttt{~~/{*} Duro task (HARD) connects to the \char`\"{}goofy\char`\"{}
{*}/}
\item \texttt{~~/{*} port and receives messages of 2 bytes {*}/ }
\item \texttt{~~q = port\_connect(\char`\"{}goofy\char`\"{}, 2, STREAM,
READ);}
\item \texttt{~~while (condition) \{}
\item \texttt{~~~~\ldots{}}
\item \texttt{~~~~if (port\_receive(q, msg, NON\textbackslash{}\_BLOCK) \{}
\item \texttt{~~~~~~<action 1>;~/{*} Ready Message! {*}/}
\item \texttt{~~~~\}}
\item \texttt{~~~~else \{}
\item \texttt{~~~~~~<action 2>;~/{*} Message not Ready! {*}/}
\item \texttt{~~~~\}}
\item \texttt{~~~~\ldots{}}
\item \texttt{~~~~task\_endcycle();}
\item \texttt{~~\}}
\item \texttt{\}}
\end{description}
%----------------------------------------------------------------------------
\begin{intest}
PORT\_DELETE\index{port\_delete()}
\end{intest}
\begin{description}
\item [\textbf{void port\_delete(PORT p)};]
\item [\textbf{Description:}]It destroys the port identified by \texttt{p}.
\item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
port\_disconnect(),
port\_send(), port\_receive()}.
\item [\textbf{Example:}]see the example at page \pageref{pg:port-ex}.
\end{description}
%----------------------------------------------------------------------------
\begin{intest}
PORT\_CONNECT\index{port\_connect()}
\end{intest}
\begin{description}
\item [\textbf{PORT port\_connect(char {*}name, int dim, int type,
int mode);}]
\item [\textbf{Description:}]It connects the calling task to the port identified
by \texttt{name}. The argument \texttt{dim} specifies the message
size in bytes, \texttt{type} the port type (\texttt{STREAM}, \texttt{MAILBOX},
or \texttt{STICK}), and \texttt{mode} the access mode (\texttt{READ}
or \texttt{WRITE}). If the port has not been opened by \texttt{port\_create()},
the task is blocked, waiting for port creation. To avoid synchronization
delays, connection should be established only \underbar{after} opening
the port.
\item [\textbf{Return value:}] The function returns the port identification
number in the case of successful operation; else -1 is returned.
\item [\textbf{See also}:] \texttt{port\_create(), port\_delete(),
port\_disconnect(), port\_send(), port\_receive()}.
\end{description}
%----------------------------------------------------------------------------
\begin{intest}
PORT\_DISCONNECT\index{port\_disconnect()}
\end{intest}
\begin{description}
\item [\textbf{void port\_disconnect(PORT p)};]
\item [\textbf{Description:}]It closes the connection identified by \texttt{p}.
\item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
port\_delete(), port\_send(), port\_receive()}.
\end{description}
%----------------------------------------------------------------------------
\begin{intest}
PORT\_SEND\index{port\_send()}
\end{intest}
\begin{description}
\item [\textbf{int port\_send(PORT p, char {*}msg, BYTE b);}]
\item [\textbf{Description:}]It sends a message pointed by \texttt{msg} to the
port identified by \texttt{p}. Message dimension is defined through
\texttt{port\_create()}
or \texttt{port\_connect()} and cannot be dynamically changed. The
argument \texttt{b} can be \texttt{BLOCK} or \texttt{NON\_BLOCK}.
If \texttt{b = BLOCK} and the port queue is full, then the task is
blocked until the buffer is freed. If \texttt{b = NON\_BLOCK} and
the port queue is full, then the primitive returns 0 and the message
is not sent.
\item [\textbf{Return value:}] 1 (TRUE) if the operation can be performed,
0 otherwise.
\item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
port\_disconnect(),
port\_send(), port\_receive()}.
\item [\textbf{Example:}]see the example at page \pageref{pg:port-ex}.
\end{description}
%----------------------------------------------------------------------------
\begin{intest}
PORT\_RECEIVE\index{port\_receive()}
\end{intest}
\begin{description}
\item [\textbf{int port\_receive(PORT p, char {*}msg, BYTE b);}]
\item [\textbf{Description:}]It receives a message from the port identified by
\texttt{p} and copies it in a memory buffer pointed by \texttt{msg}. Message
dimension is defined through \texttt{port\_create()} or \texttt{port\_connect()}
and cannot be dynamically changed. The argument \texttt{b} can be
\texttt{BLOCK} or \texttt{NON\_BLOCK}. If \texttt{b = BLOCK} and the
port queue is empty, then the task is blocked until a message is available.
If \texttt{b = NON\_BLOCK} and the port queue is empty, then the primitive
returns 0 and no message is received.
\item [\textbf{Return value:}] 1 (TRUE) if the operation can be performed,
0 otherwise.
\item [\textbf{See also}:] \texttt{port\_create(), port\_connect(),
port\_disconnect(), port\_send(), port\_receive()}.
\item [\textbf{Example:}]see the example at page \pageref{pg:port-ex}.
\end{description}