Add In-Code Documentation Guidelines
The in-code Documentation Guidelines contains the best practices for documenting code using Doxygen. The guidelines offer options for both novice and expert developers to document their code in a compatible and correct manner. Fully marked and simplified templates are provided to ease the documentation effort. Examples taken directly from Tiny Mountain's code show the difference clearly. The .c files contained here are used for the examples only and do not have any function within Tiny Mountain. Finally, the doxygen.rst file was updated to include the new content. Change-Id: I6a39a54feed5fa95f2f21545c3967ff0755d85ae Signed-off-by: Rodrigo Caballero <rodrigo.caballero.abraham@intel.com>
This commit is contained in:
parent
1d339cd724
commit
fb74cd4a79
14 changed files with 1256 additions and 1 deletions
|
@ -23,4 +23,5 @@ This would be an example of referencing function
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
doxygen_output.rst
|
||||
doxygen_guidelines.rst
|
||||
doxygen_output.rst
|
44
doc/doxygen/doxygen_guidelines.rst
Normal file
44
doc/doxygen/doxygen_guidelines.rst
Normal file
|
@ -0,0 +1,44 @@
|
|||
.. _In-Code Documentation Guidelines:
|
||||
|
||||
In-Code Documentation Guidelines
|
||||
################################
|
||||
|
||||
Follow these guidelines to document your code using comments. We provide
|
||||
examples on how to comment different parts of the code. Files,
|
||||
functions, defines, structures, variables and type definitions must be
|
||||
documented.
|
||||
|
||||
We have grouped the guidelines according to the object that is being
|
||||
documented. Read the information regarding all elements carefully since
|
||||
each type of object provides further details as to how to document the
|
||||
code as a whole.
|
||||
|
||||
These simple rules apply to all the code that you wish to include in the
|
||||
documentation:
|
||||
|
||||
#. Start and end a comment block with :literal:`/*!` and :literal:`*/`
|
||||
|
||||
#. Use \@ for all Doxygen special commands.
|
||||
|
||||
#. Files, functions, defines, structures, variables and type
|
||||
definitions must have a brief description.
|
||||
|
||||
#. All comments must start with a capital letter and end in a period.
|
||||
Even if the comment is a sentence fragment.
|
||||
|
||||
.. important::
|
||||
|
||||
Always use :literal:`/*!` This is a comment. :literal:`*/` if that comment should
|
||||
become part of the documentation.
|
||||
Use :literal:`/*` This comment won't appear in the documentation :literal:`*/` for
|
||||
comments that you want in the code but not in the documentation.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
doxygen_guidelines_files.rst
|
||||
doxygen_guidelines_functions.rst
|
||||
doxygen_guidelines_variables.rst
|
||||
doxygen_guidelines_defines.rst
|
||||
doxygen_guidelines_structs.rst
|
||||
doxygen_guidelines_typedefs.rst
|
76
doc/doxygen/doxygen_guidelines_defines.rst
Normal file
76
doc/doxygen/doxygen_guidelines_defines.rst
Normal file
|
@ -0,0 +1,76 @@
|
|||
.. _Define Documentation:
|
||||
|
||||
Define Documentation
|
||||
####################
|
||||
|
||||
Defines are documented similarly as functions. There are some note
|
||||
worthy differences:
|
||||
|
||||
* The best practice for defines requires the use of the **@def**
|
||||
special command.
|
||||
|
||||
* Just as with functions we provide a full and a simplified template.
|
||||
The simplified template is also accepted. The syntax used in the
|
||||
simplified template should only be used if you are familiar with
|
||||
Doxygen. If you are having problems getting the documentation to
|
||||
generate properly use the full template.
|
||||
|
||||
Define Comment Templates
|
||||
************************
|
||||
|
||||
Full template:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*! @def name_of_define
|
||||
|
||||
@brief Brief description of the define.
|
||||
|
||||
@details Multiple lines describing in detail what is the
|
||||
purpose of the define and what it does.
|
||||
*/
|
||||
|
||||
#define name_of_define
|
||||
|
||||
Simplified template:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*!
|
||||
Brief description of the define.
|
||||
|
||||
Multiple lines describing in detail what is the
|
||||
purpose of the define and what it does.
|
||||
*/
|
||||
#define name_of_define
|
||||
|
||||
Define Documentation Example
|
||||
****************************
|
||||
|
||||
This simple example shows how to document a define with the least amount
|
||||
of effort while still following the best practices.
|
||||
|
||||
Correct:
|
||||
|
||||
.. literalinclude:: phil_commented.h
|
||||
:language: c
|
||||
:lines: 46-54
|
||||
:emphasize-lines: 2, 3, 5
|
||||
:linenos:
|
||||
|
||||
Observe how each piece of information is clearly marked. There is no
|
||||
confusion regarding to what part of the code the comment belongs thanks
|
||||
to the @def on line 2.
|
||||
|
||||
Incorrect:
|
||||
|
||||
.. literalinclude:: ../../samples/microkernel/apps/philosophers/src/phil.h
|
||||
:language: c
|
||||
:lines: 42-47
|
||||
:emphasize-lines: 2, 5
|
||||
:linenos:
|
||||
|
||||
Observe that the comment does not start with
|
||||
:literal:`/*!` and therefore Doxygen will ignore it.
|
||||
|
||||
The comment is ambiguous; it could apply to either the define or the #if.
|
58
doc/doxygen/doxygen_guidelines_files.rst
Normal file
58
doc/doxygen/doxygen_guidelines_files.rst
Normal file
|
@ -0,0 +1,58 @@
|
|||
.. _File Header Documentation:
|
||||
|
||||
File Header Documentation
|
||||
#########################
|
||||
|
||||
Every .c, .h and .s file must contain a file header comment at the
|
||||
beginning of the file. The file header must contain:
|
||||
|
||||
#. The filename. Use **@file** for Doxygen to auto-complete the
|
||||
filename.
|
||||
|
||||
#. The brief description: A single line summarizing the contents of
|
||||
the file. Use **@brief** to clearly mark the brief description.
|
||||
|
||||
#. The detailed description: One or multiple lines describing the
|
||||
purpose of the file, how it works and any other pertinent
|
||||
information such as copyrights, authors, etc.
|
||||
|
||||
.. note::
|
||||
|
||||
Doxygen has special commands for copyrights (@copyright), authors
|
||||
(@author), and other important information. Please refer to the
|
||||
`Doxygen documentation`_ for further details.
|
||||
|
||||
.. _Doxygen documentation: http://www.stack.nl/~dimitri/doxygen/manual/index.html
|
||||
|
||||
Examples
|
||||
********
|
||||
|
||||
Correct:
|
||||
|
||||
* A file header with a single line description.
|
||||
|
||||
|
||||
|
||||
.. literalinclude:: hello_commented.c
|
||||
:language: c
|
||||
:lines: 1-5
|
||||
:emphasize-lines: 1,2,4
|
||||
:linenos:
|
||||
|
||||
* A file header with a larger description.
|
||||
|
||||
.. literalinclude:: phil_task_commented.c
|
||||
:language: c
|
||||
:lines: 1-10
|
||||
:emphasize-lines: 5-8
|
||||
:linenos:
|
||||
|
||||
Incorrect:
|
||||
|
||||
A file header without a detailed description.
|
||||
|
||||
.. literalinclude:: phil_fiber_commented.c
|
||||
:language: c
|
||||
:lines: 1-3
|
||||
:emphasize-lines: 4
|
||||
:linenos:
|
149
doc/doxygen/doxygen_guidelines_functions.rst
Normal file
149
doc/doxygen/doxygen_guidelines_functions.rst
Normal file
|
@ -0,0 +1,149 @@
|
|||
.. _Function Documentation:
|
||||
|
||||
Function Documentation
|
||||
######################
|
||||
|
||||
Doxygen recognizes a wide variety of syntaxes and structures for the
|
||||
function comments. The syntax described here is in not the only
|
||||
possible one nor does it exhaust all possible options. If your
|
||||
development needs the use of an option not described here use it. Use
|
||||
the following syntax:
|
||||
|
||||
Function Comment Templates
|
||||
**************************
|
||||
|
||||
The full template shows the best practices for documenting a function.
|
||||
The simplified version shows the minimal acceptable amount of
|
||||
documentation for a function. Use the simplified template only if you
|
||||
are familiar with Doxygen and how it uses blank lines to recognize the
|
||||
parts of the comment.
|
||||
|
||||
Full template:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*!
|
||||
* @brief Short description of my_function().
|
||||
*
|
||||
* @details Longer multi-paragraph description.
|
||||
* Use this longer description to provide details about the
|
||||
* function's purpose, operation, limitations, etc.
|
||||
*
|
||||
* @param a This is the first parameter.
|
||||
* @param b This is the second parameter.
|
||||
*
|
||||
* @return Information about the return value.
|
||||
*
|
||||
* @error
|
||||
* Details about the possible error.
|
||||
*
|
||||
* @warning
|
||||
* This would be a warning.
|
||||
*/
|
||||
my_function(int a, int b){}
|
||||
|
||||
Simplified template:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*!
|
||||
* Short description of my_function().
|
||||
*
|
||||
* Longer multi-paragraph description.
|
||||
* Use this longer description to provide details about the
|
||||
* function's purpose, operation, limitations, etc.
|
||||
*
|
||||
* @param a This is the first parameter.
|
||||
* @param b This is the second parameter.
|
||||
*
|
||||
* @return Information about the return value.
|
||||
*/
|
||||
my_function(int a, int b){}
|
||||
|
||||
.. important::
|
||||
Ensure that there is **no** blank line between the comment block
|
||||
and the function's signature. That way Doxygen can link the comment
|
||||
to the function.
|
||||
|
||||
Function Documentation Examples
|
||||
*******************************
|
||||
|
||||
Example 1
|
||||
=========
|
||||
|
||||
Take the very simple function :c:func:`taskA()`:
|
||||
|
||||
.. literalinclude:: ../../samples/microkernel/apps/hello_world/src/hello.c
|
||||
:language: c
|
||||
:lines: 77-85
|
||||
:emphasize-lines: 3, 6
|
||||
:linenos:
|
||||
|
||||
The highlighted lines show comments that would not be added to the
|
||||
documentation. That is unacceptable. The appropriate way to document
|
||||
:c:func:`taskA()` is:
|
||||
|
||||
.. literalinclude:: hello_commented.c
|
||||
:language: c
|
||||
:lines: 97-110
|
||||
:emphasize-lines: 5-7, 11, 13
|
||||
:linenos:
|
||||
|
||||
The highlighted lines show how to reference the code from within a
|
||||
comment block. The direct reference is optional and the comments on
|
||||
lines 11 and 13 are not added to the documentation. This method allows
|
||||
for easy maintenance of the code blocks and easy addition of further
|
||||
details. It also helps maintain the 72 characters line length.
|
||||
|
||||
Example 2
|
||||
=========
|
||||
Take the more complex function hello_loop():
|
||||
|
||||
.. literalinclude:: ../../samples/microkernel/apps/hello_world/src/hello.c
|
||||
:language: c
|
||||
:lines: 56-76
|
||||
:emphasize-lines: 1, 3-5, 7, 8, 13, 16
|
||||
:linenos:
|
||||
|
||||
The function parameters have been documented using the correct Doxygen
|
||||
command but notice line 1. The comment block was not started with
|
||||
:literal:`/*!` and therefore Doxygen won't parse it correctly.
|
||||
|
||||
The parameters have been documented using the \\param command. This is
|
||||
equivalent to using @param but incorrect according to these guidelines.
|
||||
Restructured Text uses the \\ as the escape for special characters. In
|
||||
order to avoid possible conflicts the \@ symbol must be used instead.
|
||||
|
||||
Notice that there is no blank line between the comment and the
|
||||
function's signature, lines 7 and 8. This allows Doxygen to correctly
|
||||
link the comment to the function.
|
||||
|
||||
Lines 13 and 16 contain two comments that won't be included by Doxygen
|
||||
in the documentation. Use the brief description or the detailed
|
||||
description inside the comment block to include that information.
|
||||
Remember that variables have to be documented separately. See
|
||||
:ref:`Variable Documentation` for more details.
|
||||
|
||||
.. literalinclude:: hello_commented.c
|
||||
:language: c
|
||||
:lines: 72-95
|
||||
:emphasize-lines: 2, 4-7, 9-11, 19, 21
|
||||
:linenos:
|
||||
|
||||
Comment blocks must have the following structure:
|
||||
|
||||
#. Brief description. See line 2.
|
||||
|
||||
#. Detailed description. See lines 4-7.
|
||||
|
||||
#. Parameter information. See lines 9-11.
|
||||
|
||||
#. Return information. Return information is optional for void
|
||||
functions.
|
||||
|
||||
#. Other special commands. There is no specific order for any further
|
||||
special commands.
|
||||
|
||||
The description of the actions referenced in lines 19 and 21 is part of
|
||||
the detailed description in the comment block. The references shown in
|
||||
lines 19 and 21 are optional.
|
53
doc/doxygen/doxygen_guidelines_structs.rst
Normal file
53
doc/doxygen/doxygen_guidelines_structs.rst
Normal file
|
@ -0,0 +1,53 @@
|
|||
.. _Structure Documentation:
|
||||
|
||||
Structure Documentation
|
||||
#######################
|
||||
|
||||
Structures, or structs for short, require very little documentation.
|
||||
Structs must be documented wherever they are defined. Basically,
|
||||
structs only require a brief description detailing why they are needed.
|
||||
Each variable that composes a struct must be commented. A fully
|
||||
simplified syntax is therefore appropriate.
|
||||
|
||||
Structure Comments Template
|
||||
***************************
|
||||
Structs only have a simplified template:
|
||||
|
||||
.. literalinclude:: ex_struct_pre.c
|
||||
:language: c
|
||||
:lines: 1-11
|
||||
:emphasize-lines: 8
|
||||
:linenos:
|
||||
|
||||
Doxygen does not require any commands to recognize the different
|
||||
comments. It does require that line 8 be left blank though.
|
||||
|
||||
Structure Documentation Example
|
||||
*******************************
|
||||
|
||||
Correct:
|
||||
|
||||
.. literalinclude:: irq_test_common_commented.h
|
||||
:language: c
|
||||
:lines: 117-125
|
||||
:emphasize-lines: 6
|
||||
:linenos:
|
||||
|
||||
Make sure to start every comment with
|
||||
:literal:`/*!` and end it with :literal:`*/`. Every comment must start
|
||||
with a capital letter and end with a period.
|
||||
|
||||
Doxygen requires that line 6 is left blank. Ensure a blank line
|
||||
separates each group of variable and comment.
|
||||
|
||||
Incorrect:
|
||||
|
||||
.. literalinclude:: ../../samples/include/irq_test_common.h
|
||||
:language: c
|
||||
:lines: 112-115
|
||||
:emphasize-lines: 1
|
||||
:linenos:
|
||||
|
||||
The struct has no documentation. Developers that want to expand its
|
||||
functionality have no way of understanding why the struct is defined
|
||||
this way nor what its components are.
|
56
doc/doxygen/doxygen_guidelines_typedefs.rst
Normal file
56
doc/doxygen/doxygen_guidelines_typedefs.rst
Normal file
|
@ -0,0 +1,56 @@
|
|||
.. _Type Definition Documentation:
|
||||
|
||||
Type Definition Documentation
|
||||
#############################
|
||||
|
||||
The documentation of type definitions, typedefs for short, is a simple
|
||||
but tricky matter. Typedefs are aliases for other types and as such
|
||||
need to be well documented. Always document typedefs even if the
|
||||
complex type it uses is documented already.
|
||||
|
||||
Type Definition Comment Template.
|
||||
*********************************
|
||||
|
||||
Typedefs require a simple comment explaining why they are being used and
|
||||
what type they are referencing.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*! Brief description with the type that is being used and why. */
|
||||
typedef int t_ie;
|
||||
|
||||
No further explanation is needed regarding the type even if it is
|
||||
complex. Each complex type must be documented where ever it was
|
||||
defined. Doxygen connects the typedef and the complex type it uses
|
||||
automatically.
|
||||
|
||||
Type Definition Documentation Example
|
||||
*************************************
|
||||
|
||||
Correct:
|
||||
|
||||
.. literalinclude:: irq_test_common_commented.h
|
||||
:language: c
|
||||
:lines: 69-73
|
||||
:emphasize-lines: 1, 3, 4
|
||||
:linenos:
|
||||
|
||||
Lines 1 and 4 name the type that is being used and with what purpose.
|
||||
Even if the purpose is the same, since the types are different, two
|
||||
comments are needed. Leaving line 3 blank not only increases
|
||||
readability but it also helps Doxygen link the comments to the typedefs
|
||||
appropriately.
|
||||
|
||||
Incorrect:
|
||||
|
||||
.. literalinclude:: ../../samples/include/irq_test_common.h
|
||||
:language: c
|
||||
:lines: 67-72
|
||||
:emphasize-lines: 3, 4
|
||||
:linenos:
|
||||
|
||||
The comments on lines 3 and 4 offer little insight into the code's
|
||||
behavior. Furthermore, they do not start with
|
||||
:literal:`/*!` and end with :literal:`*/`. Doxygen won't add the
|
||||
information to the documentation nor link it properly to the complex
|
||||
type documentation.
|
71
doc/doxygen/doxygen_guidelines_variables.rst
Normal file
71
doc/doxygen/doxygen_guidelines_variables.rst
Normal file
|
@ -0,0 +1,71 @@
|
|||
.. _Variable Documentation:
|
||||
|
||||
Variable Documentation
|
||||
######################
|
||||
|
||||
Variables are the smallest element that requires documentation. As such
|
||||
only a brief description is required detailing the purpose of the
|
||||
variable. Only significant variables have to be documented. A
|
||||
significant variable is a variable that adds functionality to a
|
||||
component. Review the `Variable Documentation Examples`_ to understand
|
||||
what constitutes a significant variable.
|
||||
|
||||
Variable Comment Template
|
||||
*************************
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*! Brief description of singificant_variable's purpose. */
|
||||
int significant_variable;
|
||||
|
||||
Variable Documentation Examples
|
||||
*******************************
|
||||
|
||||
Example 1
|
||||
=========
|
||||
|
||||
This example shows a function that has been fully documented following
|
||||
the best practices.
|
||||
|
||||
.. literalinclude:: phil_fiber_commented.c
|
||||
:language: c
|
||||
:lines: 110-168
|
||||
:emphasize-lines: 15, 18, 21-23, 25, 31
|
||||
:linenos:
|
||||
|
||||
Lines 15 and 18 show the documentation for two variables. Notice the
|
||||
blank line 17. That line is necessary not only to increase the clarity
|
||||
of the code but also to avoid Doxygen not determining properly where
|
||||
the comment belongs.
|
||||
|
||||
Lines 21-23 show another acceptable way to document two variables with a
|
||||
similar function. Notice that only one of the variables is documented,
|
||||
the first one. The argument can be made that **kmutex_t f2** is no
|
||||
longer a significant variable because it does not add any functionality
|
||||
that has not been described for **kmutex_t f1**.
|
||||
|
||||
Lines 25 and 31 show us a different situation. Although both variables
|
||||
are of the same type and very similar, they have different purposes.
|
||||
Therefore both have to be documented and the difference between them
|
||||
must be noted.
|
||||
|
||||
Example 2
|
||||
=========
|
||||
Variables outside of functions have to be documented as well.
|
||||
|
||||
.. literalinclude:: hello_commented.c
|
||||
:language: c
|
||||
:lines: 133-140
|
||||
:emphasize-lines: 1, 4, 7
|
||||
:linenos:
|
||||
|
||||
As you can see the syntax of the comment does not change. Always start
|
||||
the comment with :literal:`/*!` and end it with :literal:`*/`. Remember
|
||||
to begin with a capital letter and end with a period, even if the
|
||||
comment is only a sentence fragment.
|
||||
|
||||
Notice that the variable comments also apply for more complex types like
|
||||
structs. The comments on lines 4 and 7 apply only to the specific
|
||||
variable and not to the whole struct. Complex types must be documented
|
||||
wherever they are defined. See :ref:`Structure Documentation` and
|
||||
:ref:`Type Definition Documentation` for further details.
|
11
doc/doxygen/ex_struct_pre.c
Normal file
11
doc/doxygen/ex_struct_pre.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*! @brief Brief description of struct pre.
|
||||
*
|
||||
* Detailed description of struct pre. Optional
|
||||
* */
|
||||
struct pre {
|
||||
/*! Variable g brief description. */
|
||||
int g;
|
||||
|
||||
/*! Variable h brief description. */
|
||||
int h;
|
||||
};
|
203
doc/doxygen/hello_commented.c
Normal file
203
doc/doxygen/hello_commented.c
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*! @file
|
||||
@brief Hello World Demo
|
||||
|
||||
A Hello World demo for the Nanokernel and the Microkernel.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*! CONFIG_MICROKERNEL
|
||||
The microkernel hello world demo has two tasks that use semaphores
|
||||
and sleeps to take turns printing a greeting message at a
|
||||
controlled rate.*/
|
||||
|
||||
/*! #else || CONFIG_NANOKERNEL
|
||||
* The nanokernel hello world demo has a task and a fiber that use
|
||||
* semaphores and timers to take turns printing a greeting message at
|
||||
* a controlled rate.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@def SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000)
|
||||
@brief Compute equivalence in ticks.
|
||||
*/
|
||||
/*!
|
||||
@def SLEEPTIME
|
||||
@brief Specify delay between greetings (in ms).
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_STDOUT_CONSOLE)
|
||||
#include <stdio.h>
|
||||
#define PRINT printf
|
||||
#else
|
||||
#include <misc/printk.h>
|
||||
#define PRINT printk
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MICROKERNEL
|
||||
|
||||
#include <vxmicro.h>
|
||||
|
||||
#define SLEEPTIME 500
|
||||
#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000)
|
||||
|
||||
/*!
|
||||
@brief A loop saying hello.
|
||||
|
||||
@details
|
||||
Actions:
|
||||
-# Ouputs "Hello World!".
|
||||
-# Waits, then lets another task run.
|
||||
|
||||
@param taskname The task's identification string.
|
||||
@param mySem The task's semaphore.
|
||||
@param otherSem The other task's semaphore.
|
||||
*/
|
||||
void helloLoop(const char *taskname, ksem_t mySem, ksem_t otherSem)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
task_sem_take_wait (mySem);
|
||||
|
||||
PRINT ("%s: Hello World!\n", taskname); /* Action 1 */
|
||||
|
||||
task_sleep (SLEEPTICKS); /* Action 2 */
|
||||
task_sem_give (otherSem);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Exchanges Hello messages with taskB.
|
||||
|
||||
@details
|
||||
Actions:
|
||||
-# taskA gives its own semaphore, thus it says hello right away.
|
||||
-# Calls function helloLoop, thus taskA exchanges hello messages with taskB.
|
||||
*/
|
||||
void taskA(void)
|
||||
{
|
||||
task_sem_give (TASKASEM); /* Action 1 */
|
||||
|
||||
helloLoop (__FUNCTION__, TASKASEM, TASKBSEM); /* Action 2 */
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Exchanges Hello messages with taskA.
|
||||
|
||||
Actions:
|
||||
-# Calls function helloLoop, thus taskB exchanges hello messages with taskA.
|
||||
*/
|
||||
void taskB(void)
|
||||
{
|
||||
helloLoop (__FUNCTION__, TASKBSEM, TASKASEM); /* Action 1 */
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <nanokernel.h>
|
||||
#include <nanokernel/cpu.h>
|
||||
|
||||
#define SLEEPTIME 500
|
||||
#define SLEEPTICKS (SLEEPTIME * sys_clock_ticks_per_sec / 1000)
|
||||
|
||||
#define STACKSIZE 2000
|
||||
|
||||
/*! Declares a stack for a fiber with a size of 2000.*/
|
||||
char fiberStack[STACKSIZE];
|
||||
|
||||
/*! Declares a nanokernel semaphore for a task. */
|
||||
struct nano_sem nanoSemTask;
|
||||
|
||||
/*! Declares a nanokernel semaphore for a fiber.*/
|
||||
struct nano_sem nanoSemFiber;
|
||||
|
||||
/*!
|
||||
@brief Defines the turns taken by the tasks in the fiber.
|
||||
|
||||
Actions:
|
||||
-# Initializes semaphore.
|
||||
-# Initializes timer.
|
||||
-# Waits for task, then runs.
|
||||
-# Outputs "Hello World!".
|
||||
-# Waits, then yields to another task.
|
||||
*/
|
||||
void fiberEntry(void) {
|
||||
struct nano_timer timer;
|
||||
uint32_t data[2] = { 0, 0 };
|
||||
|
||||
nano_sem_init(&nanoSemFiber); /* Action 1 */
|
||||
|
||||
nano_timer_init(&timer, data); /* Action 2 */
|
||||
|
||||
while (1) {
|
||||
|
||||
nano_fiber_sem_take_wait(&nanoSemFiber); /* Action 3 */
|
||||
|
||||
PRINT("%s: Hello World!\n", __FUNCTION__); /* Action 4 */
|
||||
|
||||
nano_fiber_timer_start(&timer, SLEEPTICKS); /* Action 5 */
|
||||
nano_fiber_timer_wait(&timer);
|
||||
nano_fiber_sem_give(&nanoSemTask);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Implements the Hello demo.
|
||||
|
||||
Actions:
|
||||
-# Outputs "hello".
|
||||
-# Waits, then signals fiber's semaphore.
|
||||
-# Waits on fiber to yield.
|
||||
*/
|
||||
void main(void) {
|
||||
struct nano_timer timer;
|
||||
uint32_t data[2] = { 0, 0 };
|
||||
|
||||
task_fiber_start(&fiberStack[0], STACKSIZE, (nano_fiber_entry_t) fiberEntry,
|
||||
0, 0, 7, 0);
|
||||
|
||||
nano_sem_init(&nanoSemTask);
|
||||
nano_timer_init(&timer, data);
|
||||
|
||||
while (1) {
|
||||
|
||||
PRINT("%s: Hello World!\n", __FUNCTION__); /* Action 1 */
|
||||
|
||||
nano_task_timer_start(&timer, SLEEPTICKS); /* Action 2 */
|
||||
nano_task_timer_wait(&timer);
|
||||
nano_task_sem_give(&nanoSemFiber);
|
||||
|
||||
nano_task_sem_take_wait(&nanoSemTask); /* Action 3 */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
182
doc/doxygen/irq_test_common_commented.h
Normal file
182
doc/doxygen/irq_test_common_commented.h
Normal file
|
@ -0,0 +1,182 @@
|
|||
/* irq-test-common.h - IRQ utilities for tests */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
||||
Interrupt stuff, abstracted across CPU architectures.
|
||||
*/
|
||||
|
||||
#ifndef _IRQ_TEST_COMMON__H_
|
||||
#define _IRQ_TEST_COMMON__H_
|
||||
|
||||
/* defines */
|
||||
|
||||
#if defined(VXMICRO_ARCH_x86)
|
||||
#define IRQ_PRIORITY 3
|
||||
#elif defined(VXMICRO_ARCH_arm)
|
||||
#if defined(CONFIG_CPU_CORTEXM)
|
||||
#define IRQ_PRIORITY _EXC_PRIO(3)
|
||||
#endif /* CONFIG_CPU_CORTEXM */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NUM_SW_IRQS must be defined before this file is included, and it
|
||||
* currently only supports 1 or 2 as valid values.
|
||||
*/
|
||||
#if !defined(NUM_SW_IRQS)
|
||||
#error NUM_SW_IRQS must be defined before including irq-test-common.h
|
||||
#elif NUM_SW_IRQS < 1 || NUM_SW_IRQS > 2
|
||||
#error NUM_SW_IRQS only supports 1 or 2 IRQs
|
||||
#endif
|
||||
|
||||
#if defined(VXMICRO_ARCH_x86)
|
||||
static NANO_CPU_INT_STUB_DECL(nanoIntStub1);
|
||||
#if NUM_SW_IRQS >= 2
|
||||
static NANO_CPU_INT_STUB_DECL(nanoIntStub2);
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
#endif
|
||||
|
||||
/*! Declares a void-void function pointer to test the ISR. */
|
||||
typedef void (*vvfn)(void);
|
||||
|
||||
/*! Declares a void-void_pointer function pointer to test the ISR. */
|
||||
typedef void (*vvpfn)(void *);
|
||||
|
||||
#if defined(VXMICRO_ARCH_x86)
|
||||
/*
|
||||
* Opcode for generating a software interrupt. The ISR associated with each
|
||||
* of these software interrupts will call either nano_isr_lifo_put() or
|
||||
* nano_isr_lifo_get(). The imm8 data in the opcode sequence will need to be
|
||||
* filled in after calling irq_connect().
|
||||
*/
|
||||
|
||||
static char sw_isr_trigger_0[] =
|
||||
{
|
||||
0xcd, /* OPCODE: INT imm8 */
|
||||
0x00, /* imm8 data (vector to trigger) filled in at runtime */
|
||||
0xc3 /* OPCODE: RET (near) */
|
||||
};
|
||||
|
||||
#if NUM_SW_IRQS >= 2
|
||||
static char sw_isr_trigger_1[] =
|
||||
{
|
||||
/* same as above */
|
||||
0xcd,
|
||||
0x00,
|
||||
0xc3
|
||||
};
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
|
||||
#elif defined(VXMICRO_ARCH_arm)
|
||||
#if defined(CONFIG_CPU_CORTEXM)
|
||||
#include <nanokernel.h>
|
||||
static inline void sw_isr_trigger_0(void)
|
||||
{
|
||||
_NvicSwInterruptTrigger(0);
|
||||
}
|
||||
|
||||
#if NUM_SW_IRQS >= 2
|
||||
static inline void sw_isr_trigger_1(void)
|
||||
{
|
||||
_NvicSwInterruptTrigger(1);
|
||||
}
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
#endif /* CONFIG_CPU_CORTEXM */
|
||||
#endif
|
||||
|
||||
/*! Defines the ISR initialization information. */
|
||||
struct isrInitInfo
|
||||
{
|
||||
/*! Declares the void-void function pointer for the ISR. */
|
||||
vvpfn isr[2];
|
||||
|
||||
/*! Declares a space for the information. */
|
||||
void *arg[2];
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* initIRQ - init interrupts
|
||||
*
|
||||
*/
|
||||
|
||||
static int initIRQ
|
||||
(
|
||||
struct isrInitInfo *i
|
||||
)
|
||||
{
|
||||
#if defined(VXMICRO_ARCH_x86)
|
||||
int vector; /* vector to which interrupt is connected */
|
||||
|
||||
if (i->isr[0])
|
||||
{
|
||||
vector = irq_connect (NANO_SOFT_IRQ, IRQ_PRIORITY, i->isr[0],
|
||||
i->arg[0], nanoIntStub1);
|
||||
if (-1 == vector)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
sw_isr_trigger_0[1] = vector;
|
||||
}
|
||||
|
||||
#if NUM_SW_IRQS >= 2
|
||||
if (i->isr[1])
|
||||
{
|
||||
vector = irq_connect (NANO_SOFT_IRQ, IRQ_PRIORITY, i->isr[1],
|
||||
i->arg[1], nanoIntStub2);
|
||||
if (-1 == vector)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
sw_isr_trigger_1[1] = vector;
|
||||
}
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
#elif defined(VXMICRO_ARCH_arm)
|
||||
#if defined(CONFIG_CPU_CORTEXM)
|
||||
if (i->isr[0])
|
||||
{
|
||||
(void) irq_connect (0, IRQ_PRIORITY, i->isr[0], i->arg[0]);
|
||||
irq_enable (0);
|
||||
}
|
||||
if (i->isr[1])
|
||||
{
|
||||
(void) irq_connect (1, IRQ_PRIORITY, i->isr[1], i->arg[1]);
|
||||
irq_enable (1);
|
||||
}
|
||||
#endif /* CONFIG_CPU_CORTEXM */
|
||||
#endif /* VXMICRO_ARCH_x86 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _IRQ_TEST_COMMON__H_ */
|
60
doc/doxygen/phil_commented.h
Normal file
60
doc/doxygen/phil_commented.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*! @file
|
||||
* @brief Dining philosophers header file.
|
||||
*
|
||||
* Collects the includes and defines needed to implement the dining philosophers
|
||||
* example.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Needed includes. */
|
||||
|
||||
#if defined(CONFIG_STDOUT_CONSOLE)
|
||||
#include <stdio.h>
|
||||
#else
|
||||
#include <misc/printk.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@def N_PHILOSOPHERS
|
||||
@brief Defines the number of philosophers.
|
||||
|
||||
@details Multiple tasks do printfs and they may conflict.
|
||||
Uses puts() instead of printf() to avoid conflicts.
|
||||
*/
|
||||
|
||||
#define N_PHILOSOPHERS 6
|
||||
|
||||
#if defined(CONFIG_STDOUT_CONSOLE)
|
||||
#define PRINTF(...) {char output[256]; sprintf(output, __VA_ARGS__); puts(output);}
|
||||
#else
|
||||
#define PRINTF(...) printk(__VA_ARGS__)
|
||||
#endif
|
166
doc/doxygen/phil_fiber_commented.c
Normal file
166
doc/doxygen/phil_fiber_commented.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*! @file
|
||||
* @brief Solution to the dining philosophers problem using fibers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
/* For the nanokernel. */
|
||||
#include <nanokernel.h>
|
||||
#include "phil.h"
|
||||
#else
|
||||
/* For the microkernel. */
|
||||
#include <vxmicro.h>
|
||||
#include "phil.h"
|
||||
#endif
|
||||
|
||||
#include <nanokernel/cpu.h> //!< Used to be know as: irq_lock/irq_unlock
|
||||
|
||||
/* defines */
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
/* For the nanokernel. */
|
||||
#define FORK(x) &forks[x]
|
||||
#define TAKE(x) nano_fiber_sem_take_wait(x)
|
||||
#define GIVE(x) nano_fiber_sem_give(x)
|
||||
#define RANDDELAY(x) myDelay(((nano_node_tick_get_32() * ((x) +1)) & 0x1f) + 1)
|
||||
#else
|
||||
/* For the microkernel. */
|
||||
#define FORK(x) forks[x]
|
||||
#define TAKE(x) task_mutex_lock_wait(x)
|
||||
#define GIVE(x) task_mutex_unlock(x)
|
||||
#define RANDDELAY(x) myDelay(((task_node_tick_get_32() * ((x) +1)) & 0x1f) + 1)
|
||||
#endif
|
||||
|
||||
#define PRINT(x,y) myPrint(x,y)
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
/* For the nanokernel. */
|
||||
extern struct nano_sem forks[N_PHILOSOPHERS];
|
||||
#else
|
||||
/* For the microkernel. */
|
||||
kmutex_t forks[] = { forkMutex0, forkMutex1, forkMutex2, forkMutex3, forkMutex4,
|
||||
forkMutex5 };
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Prints a philosopher's state.
|
||||
*
|
||||
* @param id A philosopher's ID.
|
||||
* @param str A string, either EATING or THINKING.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static void myPrint(int id,
|
||||
char *str
|
||||
) {
|
||||
PRINTF("\x1b[%d;%dHPhilosopher %d %s\n", id + 1, 1, id, str);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Waits for a number of ticks to elapse.
|
||||
*
|
||||
* @param ticks Number of ticks to delay.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static void myDelay(int ticks
|
||||
) {
|
||||
#ifdef CONFIG_MICROKERNEL
|
||||
task_sleep (ticks);
|
||||
#else
|
||||
struct nano_timer timer;
|
||||
|
||||
nano_timer_init(&timer, (void *) 0);
|
||||
nano_fiber_timer_start(&timer, ticks);
|
||||
nano_fiber_timer_wait(&timer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Entry point to a philosopher's thread.
|
||||
*
|
||||
* @details This routine runs as a task in the microkernel environment
|
||||
* and as a fiber in the nanokernel environment.
|
||||
*
|
||||
* Actions:
|
||||
* -# Always takes the lowest fork first.
|
||||
* -# Prints out either Eating or Thinking.
|
||||
*
|
||||
* @return Not applicable.
|
||||
*/
|
||||
void philEntry(void) {
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
/*! Declares a fork for the nanokernel. */
|
||||
struct nano_sem *f1;
|
||||
|
||||
/*! Declares a second fork for the nanokernel. */
|
||||
struct nano_sem *f2;
|
||||
#else
|
||||
/*! Declares a fork for the microkernel. */
|
||||
kmutex_t f1;
|
||||
kmutex_t f2;
|
||||
#endif
|
||||
/*! Declares the current philosopher's ID. */
|
||||
static int myId;
|
||||
|
||||
/*! Declares an interrupt lock level.*/
|
||||
int pri = irq_lock();
|
||||
|
||||
/*! Declares the next philosopher's ID. */
|
||||
int id = myId++;
|
||||
|
||||
irq_unlock(pri);
|
||||
|
||||
if ((id + 1) != N_PHILOSOPHERS) { /* A1 */
|
||||
f1 = FORK(id);
|
||||
f2 = FORK(id + 1);
|
||||
} else {
|
||||
f1 = FORK(0);
|
||||
f2 = FORK(id);
|
||||
}
|
||||
|
||||
while (1) { /* A2 */
|
||||
TAKE(f1);
|
||||
TAKE(f2);
|
||||
|
||||
PRINT(id, "EATING ");
|
||||
RANDDELAY(id);
|
||||
|
||||
GIVE(f2);
|
||||
GIVE(f1);
|
||||
|
||||
PRINT(id, "THINKING");
|
||||
RANDDELAY(id);
|
||||
}
|
||||
}
|
125
doc/doxygen/phil_task_commented.c
Normal file
125
doc/doxygen/phil_task_commented.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*! @file
|
||||
* @brief An implementation of a solution to the dining philosophers problem
|
||||
* for both the nano- and microkernel.
|
||||
*
|
||||
* This particular implementation uses 6 fibers or tasks of
|
||||
* different priority, semaphores and timers. The implementation demostrates
|
||||
* fibers and semaphores in the nanokernel and tasks and timers in the
|
||||
* microkernel.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
#include <nanokernel.h>
|
||||
#include "phil.h"
|
||||
#else
|
||||
#include <vxmicro.h>
|
||||
#include "phil.h"
|
||||
#endif
|
||||
|
||||
/* defines */
|
||||
|
||||
#define DEMO_DESCRIPTION \
|
||||
"\x1b[2J\x1b[15;1H" \
|
||||
"Demo Description\n" \
|
||||
"----------------\n" \
|
||||
"An implementation of a solution to the Dining Philosophers problem\n" \
|
||||
"(a classic multi-thread synchronization problem). This particular\n" \
|
||||
"implementation demonstrates the usage of multiple (6) %s\n" \
|
||||
"of differing priorities and the %s semaphores and timers."
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
|
||||
#define STSIZE 1024
|
||||
|
||||
extern void philEntry (void); //!< External function.
|
||||
|
||||
char philStack[N_PHILOSOPHERS][STSIZE];//!< Declares a global stack of size 1024.
|
||||
struct nano_sem forks[N_PHILOSOPHERS];//!< Declares global semaphore forks for the number of philosophers.
|
||||
#endif /* CONFIG_NANOKERNEL */
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
|
||||
/*!
|
||||
* @brief The nanokernel entry point.
|
||||
*
|
||||
* Actions:
|
||||
* -# Starts one fiber per philosopher.
|
||||
* -# Waits forever.
|
||||
* @return Does not return.
|
||||
*/
|
||||
int main (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
PRINTF (DEMO_DESCRIPTION, "fibers", "nanokernel");
|
||||
|
||||
for (i = 0; i < N_PHILOSOPHERS; i++)
|
||||
{
|
||||
nano_sem_init (&forks[i]);
|
||||
nano_task_sem_give (&forks[i]);
|
||||
}
|
||||
|
||||
/* A1 */
|
||||
for (i = 0; i < N_PHILOSOPHERS; i++)
|
||||
task_fiber_start (&philStack[i][0], STSIZE,
|
||||
(nano_fiber_entry_t) philEntry, 0, 0, 6, 0);
|
||||
|
||||
/* A2 */
|
||||
while (1)
|
||||
{
|
||||
extern void nano_cpu_idle (void);
|
||||
nano_cpu_idle ();
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*!
|
||||
* @brief Starts the dining philosophers demo of the microkernel.
|
||||
*
|
||||
* This function starts the dining philosophers demo and
|
||||
* then waits forever.
|
||||
* @return Does not return.
|
||||
*/
|
||||
void philDemo(void) {
|
||||
PRINTF(DEMO_DESCRIPTION, "tasks", "microkernel");
|
||||
|
||||
task_group_start(PHI);
|
||||
|
||||
while (1) {
|
||||
task_sleep(10000);
|
||||
}
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue