microkernel: introduce support for private pipes

This enable defining pipes in source code in addition to
defining in MDEF files. This introduces the macro
DEFINE_PIPE(pipe_name, ...). The pipes created this
way are the same, in functionality, as those defined in MDEF
files. They can be manipulated by the standard microkernel
pipe APIs.

Define the pipe using:

  DEFINE_PIPE(pipe1, size);

and "pipe1" can be used, for example:

  task_pipe_put(pipe1, ...);

or,

  task_pipe_get(pipe1, ...);

etc.

To use the pipe defined in another source file, simply add:

extern const kpipe_t pipe1;

to the desired C or header file.

Change-Id: Iae8e04706359bc18aae51acc75df3e3d26388882
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2015-07-28 11:18:35 -07:00 committed by Anas Nashif
commit b5517ab61c
5 changed files with 62 additions and 5 deletions

View file

@ -40,8 +40,8 @@ and receiver identities.
Usage
=====
Defining a pipe
---------------
Defining a pipe in MDEF file
----------------------------
The following parameters must be defined:
@ -67,6 +67,35 @@ For example, the file :file:`projName.mdef` defines a pipe as follows:
% ===============================
PIPE DATA_PIPE 1024
Defining pipes in source code
-----------------------------
In addition to defining pipes in MDEF file, it is also possible to
define pipes inside code. The macro ``DEFINE_PIPE(...)`` can be
used for this purpose.
For example, the following code can be used to define a global pipe
``PRIV_PIPE``.
.. code-block:: c
DEFINE_PIPE(PRIV_PIPE, size);
where the parameters are the same as pipes defined in MDEF file.
The task ``PRIV_PIPE`` can be used in the same style as those
defined in MDEF file.
It is possible to utilize this pipe in another source file, simply
add:
.. code-block:: c
extern const kpipe_t PRIV_PIPE;
to that file. The pipe ``PRIV_PIPE`` can be then used there.
Example: Writing Fixed-Size Data Items to a Pipe
------------------------------------------------

View file

@ -207,6 +207,7 @@ SECTIONS
{
_k_pipe_ptr_start = .;
*(._k_pipe_ptr.public.*)
*(._k_pipe_ptr.private.*)
KEEP(*(SORT_BY_NAME("._k_pipe_ptr*")))
_k_pipe_ptr_end = .;
} GROUP_LINK_IN(RAMABLE_REGION)

View file

@ -178,6 +178,7 @@ SECTIONS
{
_k_pipe_ptr_start = .;
*(._k_pipe_ptr.public.*)
*(._k_pipe_ptr.private.*)
KEEP(*(SORT_BY_NAME("._k_pipe_ptr*")))
_k_pipe_ptr_end = .;
} GROUP_LINK_IN(RAM)

View file

@ -37,6 +37,8 @@
extern "C" {
#endif
#include <sections.h>
extern int _task_pipe_put(kpipe_t id,
void *pBuffer,
int iNbrBytesToWrite,
@ -75,6 +77,31 @@ extern int _task_pipe_put_async(kpipe_t id,
#define task_pipe_put_async(id, block, size, sema) \
_task_pipe_put_async(id, block, size, sema)
/**
* @brief Initialize a pipe struct.
*
* @param size Size of pipe buffer.
* @param buffer Pointer to the buffer.
*/
#define __K_PIPE_INITIALIZER(size, buffer) \
{ \
.iBufferSize = size, \
.Buffer = buffer, \
}
/**
* @brief Define a private microkernel pipe.
*
* @param name Name of the pipe.
* @param size Size of the pipe buffer, in bytes.
*/
#define DEFINE_PIPE(name, size) \
char __noinit __pipe_buffer_##name[size]; \
struct _k_pipe_struct _k_pipe_obj_##name = \
__K_PIPE_INITIALIZER(size, __pipe_buffer_##name); \
const kpipe_t name \
__section(_k_pipe_ptr, private, pipe) = \
(kpipe_t)&_k_pipe_obj_##name;
#ifdef __cplusplus
}

View file

@ -592,7 +592,7 @@ def kernel_main_c_pipes():
size = pipe[1]
buffer = "__" + pipe[0] + "_buffer"
kernel_main_c_out("struct _k_pipe_struct _k_pipe_obj_%s = " % (name) +
" {%d, %s};\n" % (size, buffer) +
" __K_PIPE_INITIALIZER(%d, %s);\n" % (size, buffer) +
"kpipe_t _k_pipe_ptr_%s " % (name) +
" __section(_k_pipe_ptr, public, pipe) =\n" +
" (kpipe_t)&_k_pipe_obj_%s;\n" % (name))
@ -744,8 +744,7 @@ def kernel_main_c_node_init():
kernel_main_c_out("\n" +
"void _k_init_node(void)\n{\n")
if (len(pipe_list) > 0):
kernel_main_c_out(" _k_pipe_init();\n")
kernel_main_c_out(" _k_pipe_init();\n")
if (len(map_list) > 0):
kernel_main_c_out(" _k_mem_map_init();\n")
if (len(pool_list) > 0):