doc: Remove contributor documentation moved to wiki
Contributor documents are moved to the wiki.zephyrproject.org site Three references in existing documents updated to point to the wiki. Change-Id: Ib902b9596020722cf8fec2fc064725f7406297ff Signed-off-by: David B. Kinder <david.b.kinder@intel.com>
|
@ -49,7 +49,9 @@ Understanding Naming Conventions
|
|||
================================
|
||||
|
||||
The kernel limits the use of some prefixes to internal use only. For
|
||||
more information, see :ref:`naming_conventions`.
|
||||
more information, see `naming conventions`_.
|
||||
|
||||
.. _naming conventions: https://wiki.zephyrproject.org/view/Coding_conventions#Naming_Conventions
|
||||
|
||||
.. _src_makefiles_reqs:
|
||||
|
||||
|
|
|
@ -40,10 +40,12 @@ Workflow
|
|||
|
||||
7. Develop source code and add source code files to the src directory.
|
||||
|
||||
* :ref:`naming_conventions`
|
||||
* `naming conventions`_
|
||||
* :ref:`src_makefiles_reqs`
|
||||
* :ref:`src_files_directories`
|
||||
|
||||
.. _naming conventions: https://wiki.zephyrproject.org/view/Coding_conventio ns#Naming_Conventions
|
||||
|
||||
8. Build an application image.
|
||||
|
||||
* :ref:`apps_build`
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
.. _changes:
|
||||
|
||||
Submitting a Change to Gerrit
|
||||
#############################
|
||||
|
||||
Refer to the Zephyr project wiki for information on submitting code
|
||||
changes to Gerrit.
|
||||
|
||||
* https://wiki.zephyrproject.org/view/Code_changes
|
|
@ -3,19 +3,9 @@
|
|||
Contributing Code
|
||||
#################
|
||||
|
||||
This section contains details regarding the coding style, the acceptable
|
||||
Details regarding the coding style, the acceptable
|
||||
licenses, the naming conventions, the code submission infrastructure, the
|
||||
review process and the code documentation.
|
||||
review process and the code documentation can be found on the
|
||||
Zephyr Project wiki.
|
||||
|
||||
Ensure that you have read and understood the information before submitting any
|
||||
code changes.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
gerrit_accounts
|
||||
gerrit
|
||||
gerrit_practices
|
||||
changes
|
||||
conventions
|
||||
doxygen/doxygen
|
||||
* https://wiki.zephyrproject.org/view/Collaboration_Guidelines
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
.. _naming_conventions:
|
||||
|
||||
Coding Style and Conventions
|
||||
#################################
|
||||
|
||||
Refer to the Zephyr project wiki to learn about Zephyr code conventions.
|
||||
|
||||
* https://wiki.zephyrproject.org/view/Coding_conventions
|
|
@ -1,74 +0,0 @@
|
|||
.. _defines:
|
||||
|
||||
Define Documentation
|
||||
####################
|
||||
|
||||
Defines and functions are documented similarly. Some noteworthy
|
||||
differences are:
|
||||
|
||||
* 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 syntax used in the simplified template should only be used if you are familiar with
|
||||
Doxygen. Use the full template if you are having problems
|
||||
generating the documentation properly.
|
||||
|
||||
Define Comment Templates
|
||||
************************
|
||||
|
||||
Full template:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/** @def name_of_define
|
||||
*
|
||||
* @brief Brief description of the define.
|
||||
*
|
||||
* @details Multiple lines describing in detail 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 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 best practices.
|
||||
|
||||
Correct:
|
||||
|
||||
.. literalinclude:: phil_commented.h
|
||||
:language: c
|
||||
:lines: 32-47
|
||||
:emphasize-lines: 2, 3, 5
|
||||
:linenos:
|
||||
|
||||
Observe how each piece of information is clearly marked. The @def on line 2
|
||||
ensures that the comment is appropriately linked to the code.
|
||||
|
||||
Incorrect:
|
||||
|
||||
.. literalinclude:: ../../../samples/philosophers/microkernel/src/phil.h
|
||||
:language: c
|
||||
:lines: 25-34
|
||||
: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.
|
|
@ -1,62 +0,0 @@
|
|||
.. _in-code:
|
||||
|
||||
In-Code Documentation
|
||||
#####################
|
||||
|
||||
Doxygen extracts the in-code documentation automatically from the code. Doxygen
|
||||
generates XML files that the :program:`Breathe` extension imports into Sphinx.
|
||||
|
||||
The Doxygen pass is independent from the Sphinx pass. Using Breathe to link
|
||||
them together, we can reference the code in the documentation and vice-versa.
|
||||
|
||||
.. _doxygen_guides:
|
||||
|
||||
In-Code Documentation Guides
|
||||
****************************
|
||||
|
||||
Follow these guides to document your code using comments. The Zephyr Project
|
||||
follows the Javadoc / Doxygen commenting style. 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 guides according to the object that is being
|
||||
documented. Read sections carefully, as each 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:`*/`
|
||||
|
||||
#. Start each line of the comment with :literal:`*`
|
||||
|
||||
#. Use \@ for all Doxygen special commands.
|
||||
|
||||
#. Files, functions, defines, structures, variables and type
|
||||
definitions must have a brief description.
|
||||
|
||||
#. All comments must be in sentence-form: begin with a capital letter and
|
||||
end in a period, even when the comment is a sentence fragment.
|
||||
|
||||
.. note::
|
||||
Always use this syntax when your intention is to have that comment
|
||||
become part of the documentation.
|
||||
:literal:`/** This comment style will show up in docs. */`
|
||||
Alternatively, use the single-asterisk syntax when your intention
|
||||
is for that comment to appear in the code, but not in the documentation.
|
||||
:literal:`/* This style of comment won't appear in the docs */`
|
||||
|
||||
.. _Javadoc / Doxygen:
|
||||
http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
files
|
||||
functions
|
||||
variables
|
||||
defines
|
||||
structs
|
||||
typedefs
|
||||
groups
|
||||
troubleshooting
|
|
@ -1,11 +0,0 @@
|
|||
/** @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;
|
||||
};
|
|
@ -1,57 +0,0 @@
|
|||
.. _files:
|
||||
|
||||
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 file contents.
|
||||
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. Refer to the
|
||||
`Doxygen documentation`_ for 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:
|
|
@ -1,227 +0,0 @@
|
|||
.. _functions:
|
||||
|
||||
Function Documentation
|
||||
######################
|
||||
|
||||
Doxygen recognizes a wide variety of syntaxes and structures for the
|
||||
function comments. The syntax described here is one of many that are possible.
|
||||
If your development requires an option that is not described here, use it.
|
||||
However, you may use the following syntax for everything else.
|
||||
|
||||
.. note::
|
||||
|
||||
When linking functions within a ReST file, two possible markups are:
|
||||
``:cpp:`` or ``:c:``. Use ``:cpp:`` for functions defined using an
|
||||
:code:`extern`. Use ``:c:`` for functions defined using a
|
||||
:code:`#define`.
|
||||
|
||||
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 you have **no** blank lines between the comment block
|
||||
and the function's signature. This ensures that Doxygen can link the comment
|
||||
to the function.
|
||||
|
||||
Workarounds
|
||||
***********
|
||||
|
||||
When adding qualifiers to a function declaration, like *__deprecated*
|
||||
(or *ALWAYS_INLINE*, or any others), for example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/**
|
||||
* @brief Register a task IRQ object.
|
||||
*
|
||||
* This routine connects a task IRQ object to a system interrupt based
|
||||
* upon the specified IRQ and priority values.
|
||||
*
|
||||
* IRQ allocation is done via the microkernel server fiber, making simultaneous
|
||||
* allocation requests single-threaded.
|
||||
*
|
||||
* @param irq_obj IRQ object identifier.
|
||||
* @param irq Request IRQ.
|
||||
* @param priority Requested interrupt priority.
|
||||
* @param flags IRQ flags.
|
||||
*
|
||||
* @return assigned interrupt vector if successful, INVALID_VECTOR if not
|
||||
*/
|
||||
uint32_t __deprecated task_irq_alloc(kirq_t irq_obj, uint32_t irq,
|
||||
uint32_t priority, uint32_t flags);
|
||||
|
||||
the *Sphinx* parser can get confused with errors such as::
|
||||
|
||||
doc/api/microkernel_api.rst:35: WARNING: Error when parsing function declaration.
|
||||
If the function has no return type:
|
||||
Error in declarator or parameters and qualifiers
|
||||
Invalid definition: Expecting "(" in parameters_and_qualifiers. [error at 9]
|
||||
uint32_t __deprecated task_irq_alloc(kirq_t irq_obj, uint32_t irq, uint32_t priority, uint32_t flags)
|
||||
---------^
|
||||
If the function has a return type:
|
||||
Error in declarator or parameters and qualifiers
|
||||
If pointer to member declarator:
|
||||
Invalid definition: Expected '::' in pointer to member (function). [error at 22]
|
||||
uint32_t __deprecated task_irq_alloc(kirq_t irq_obj, uint32_t irq, uint32_t priority, uint32_t flags)
|
||||
----------------------^
|
||||
If declarator-id:
|
||||
Invalid definition: Expecting "(" in parameters_and_qualifiers. [error at 22]
|
||||
uint32_t __deprecated task_irq_alloc(kirq_t irq_obj, uint32_t irq, uint32_t priority, uint32_t flags)
|
||||
----------------------^
|
||||
... <etc etc>...
|
||||
|
||||
a workaround is to name with *@fn* the function:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/**
|
||||
* @fn uint32_t task_irq_alloc(kirq_t irq_obj, uint32_t irq,
|
||||
* uint32_t priority, uint32_t flags)
|
||||
* @brief Register a task IRQ object.
|
||||
*
|
||||
* This routine connects a task IRQ object to a system interrupt based
|
||||
* upon the specified IRQ and priority values.
|
||||
*
|
||||
* IRQ allocation is done via the microkernel server fiber, making simultaneous
|
||||
* allocation requests single-threaded.
|
||||
*
|
||||
* @param irq_obj IRQ object identifier.
|
||||
* @param irq Request IRQ.
|
||||
* @param priority Requested interrupt priority.
|
||||
* @param flags IRQ flags.
|
||||
*
|
||||
* @return assigned interrupt vector if successful, INVALID_VECTOR if not
|
||||
*/
|
||||
|
||||
This has been reported to the Sphinx developers
|
||||
(https://github.com/sphinx-doc/sphinx/issues/2682).
|
||||
|
||||
Function Documentation Examples
|
||||
*******************************
|
||||
|
||||
Example 1
|
||||
=========
|
||||
|
||||
Take the very simple function :c:func:`taskA()`:
|
||||
|
||||
.. literalinclude:: hello_wrong.c
|
||||
:language: c
|
||||
:lines: 1-12
|
||||
:emphasize-lines: 4-6, 10, 12
|
||||
:linenos:
|
||||
|
||||
The highlighted lines contain comments that will be missing from the generated
|
||||
documentation. To avoid this, pay careful attention to your commenting syntax.
|
||||
This example shows good commenting syntax.
|
||||
:c:func:`taskA()` is:
|
||||
|
||||
.. literalinclude:: hello_commented.c
|
||||
:language: c
|
||||
:lines: 83-96
|
||||
: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 character line length.
|
||||
|
||||
Example 2
|
||||
=========
|
||||
Take the more complex function hello_loop():
|
||||
|
||||
.. literalinclude:: hello_wrong.c
|
||||
:language: c
|
||||
:lines: 14-31
|
||||
:emphasize-lines: 1, 3-5, 7-9,13-16
|
||||
:linenos:
|
||||
|
||||
The function parameters have been documented using the correct Doxygen
|
||||
command, yet notice line 1. The comment block was not started with
|
||||
:literal:`/**` so, Doxygen will not 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.
|
||||
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-16 contain comments that will not be included by Doxygen
|
||||
in the documentation. To include that information, use the brief description
|
||||
or the detailed description inside the comment block.
|
||||
Remember that variables must be documented separately. See
|
||||
:ref:`variables` for more details.
|
||||
|
||||
.. literalinclude:: hello_commented.c
|
||||
:language: c
|
||||
:lines: 58-81
|
||||
: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.
|
|
@ -1,57 +0,0 @@
|
|||
.. _groups:
|
||||
|
||||
Doxygen Groups
|
||||
##############
|
||||
|
||||
The Zephyr Kernel's in-code documentation implements Doxygen groups.
|
||||
The comments regarding the various services are contained in their respective groups.
|
||||
The services groups are then contained in one of two main groups: either microkernel or nanokernel.
|
||||
Each group can contain other groups, functions, variables, enums, typedefs and defines.
|
||||
|
||||
.. note:: Compound entities such as: clases, files and namespaces can be put into multiple groups;
|
||||
however, variables, functions, typedefs and enums can only be member of one group.
|
||||
|
||||
Defining Groups
|
||||
***************
|
||||
|
||||
There are different ways to define groups and members.
|
||||
You must define a group using the directive :literal:`@defgroup <GroupLabel>`,
|
||||
where :literal:`<GroupLabel>` is replaced with the name of the specific group.
|
||||
This label serves as reference when adding or pulling information to that group.
|
||||
Keep in mind that the label must be a single word.
|
||||
The desired entities must be inside the comment block that uses the syntax :literal:`@{` &
|
||||
:literal:`@}`
|
||||
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
/** @defgroup <GroupLabel> Group Name
|
||||
* Detailed Description of the Group
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* @brief Brief description of the entity*/
|
||||
ENTITY1;
|
||||
|
||||
/* @brief Brief description of the entity*/
|
||||
ENTITY2;
|
||||
|
||||
/** @} */ // End of GroupLabel
|
||||
|
||||
If you need to add more information that is not listed inside the group block,
|
||||
you must use :literal:`@addtogroup <GroupLabel>`.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
/** @addtogroup <GroupLabel>
|
||||
* Optional: This line adds information to the GroupLabel Detailed Description of the Group
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* The entities you want to add must be inserted inside before the close block*/
|
||||
|
||||
/** @} // End of addtogroup GroupLabel */
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
/** @file
|
||||
@brief Hello World Demo
|
||||
|
||||
A Hello World demo for the Nanokernel and the Microkernel.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 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 <zephyr.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 (mySem, TICKS_UNLIMITED);
|
||||
|
||||
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(&nanoSemFiber, TICKS_UNLIMITED); /* Action 3 */
|
||||
|
||||
PRINT("%s: Hello World!\n", __FUNCTION__); /* Action 4 */
|
||||
|
||||
nano_fiber_timer_start(&timer, SLEEPTICKS); /* Action 5 */
|
||||
nano_fiber_timer_test(&timer, TICKS_UNLIMITED);
|
||||
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_test(&timer, TICKS_UNLIMITED);
|
||||
nano_task_sem_give(&nanoSemFiber);
|
||||
|
||||
nano_task_sem_take(&nanoSemTask, TICKS_UNLIMITED); /* Action 3 */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||
/*This is a hello world example*/
|
||||
/*taskA exchanges hello messages with taskB*/
|
||||
/*
|
||||
* @brief Does Hello message.
|
||||
* -Calls function helloLoop.
|
||||
*/
|
||||
void taskA(void)
|
||||
{
|
||||
helloLoop(__func__, TASKBSEM, TASKASEM);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* @brief A loop saying hello.
|
||||
*
|
||||
\param taskname The task's identification string.
|
||||
\param mySem The task's semaphore.
|
||||
\param otherSem The other task's semaphore.
|
||||
*
|
||||
*/
|
||||
void taskA(void)
|
||||
{
|
||||
helloLoop(__func__, TASKBSEM, TASKASEM);
|
||||
}
|
||||
#else
|
||||
/* Actions:
|
||||
*
|
||||
* -# Ouputs "Hello World!".
|
||||
* -# Waits, then lets another task run.
|
||||
*/
|
|
@ -1,167 +0,0 @@
|
|||
/* irq-test-common.h - IRQ utilities for tests */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
||||
Interrupt stuff, abstracted across CPU architectures.
|
||||
*/
|
||||
|
||||
#ifndef _IRQ_TEST_COMMON__H_
|
||||
#define _IRQ_TEST_COMMON__H_
|
||||
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
#define IRQ_PRIORITY 3
|
||||
#elif defined(CONFIG_ARM)
|
||||
#if defined(CONFIG_CPU_CORTEX_M)
|
||||
#define IRQ_PRIORITY _EXC_PRIO(3)
|
||||
#endif /* CONFIG_CPU_CORTEX_M */
|
||||
#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(CONFIG_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(CONFIG_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(CONFIG_ARM)
|
||||
#if defined(CONFIG_CPU_CORTEX_M)
|
||||
#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_CORTEX_M */
|
||||
#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(CONFIG_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, 0);
|
||||
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, 0);
|
||||
if (-1 == vector)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
sw_isr_trigger_1[1] = vector;
|
||||
}
|
||||
#endif /* NUM_SW_IRQS >= 2 */
|
||||
#elif defined(CONFIG_ARM)
|
||||
#if defined(CONFIG_CPU_CORTEX_M)
|
||||
if (i->isr[0])
|
||||
{
|
||||
(void) IRQ_CONNECT(0, IRQ_PRIORITY, i->isr[0], i->arg[0], 0);
|
||||
irq_enable (0);
|
||||
}
|
||||
if (i->isr[1])
|
||||
{
|
||||
(void) IRQ_CONNECT(1, IRQ_PRIORITY, i->isr[1], i->arg[1], 0);
|
||||
irq_enable (1);
|
||||
}
|
||||
#endif /* CONFIG_CPU_CORTEX_M */
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _IRQ_TEST_COMMON__H_ */
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
struct isrInitInfo {
|
||||
vvpfn isr[2];
|
||||
void *arg[2];
|
||||
};
|
|
@ -1,46 +0,0 @@
|
|||
/** @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.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* 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
|
|
@ -1,148 +0,0 @@
|
|||
/** @file
|
||||
* @brief Solution to the dining philosophers problem using fibers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
/* For the nanokernel. */
|
||||
#include <nanokernel.h>
|
||||
#include "phil.h"
|
||||
#else
|
||||
/* For the microkernel. */
|
||||
#include <zephyr.h>
|
||||
#include "phil.h"
|
||||
#endif
|
||||
|
||||
#include <nanokernel/cpu.h> //!< Used to be know as: irq_lock/irq_unlock
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
/* For the nanokernel. */
|
||||
#define FORK(x) &forks[x]
|
||||
#define TAKE(x) nano_fiber_sem_take(x, TICKS_UNLIMITED)
|
||||
#define GIVE(x) nano_fiber_sem_give(x)
|
||||
#define RANDDELAY(x) myDelay(((sys_tick_get_32() * ((x) + 1)) & 0x1f) + 1)
|
||||
#else
|
||||
/* For the microkernel. */
|
||||
#define FORK(x) forks[x]
|
||||
#define TAKE(x) task_mutex_lock(x, TICKS_UNLIMITED)
|
||||
#define GIVE(x) task_mutex_unlock(x)
|
||||
#define RANDDELAY(x) myDelay(((task_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_test(&timer, TICKS_UNLIMITED);
|
||||
#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);
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/** @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.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NANOKERNEL
|
||||
#include <nanokernel.h>
|
||||
#include "phil.h"
|
||||
#else
|
||||
#include <zephyr.h>
|
||||
#include "phil.h"
|
||||
#endif
|
||||
|
||||
#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
|
|
@ -1,167 +0,0 @@
|
|||
.. _structs:
|
||||
|
||||
Structure Documentation
|
||||
#######################
|
||||
|
||||
Structures, or structs for short, require very little documentation,
|
||||
and it's best to document them wherever they are defined.
|
||||
Structs require only a brief description detailing why they are needed.
|
||||
Each variable that composes a struct needs a comment contained within
|
||||
the correct syntax. A fully simplified syntax is therefore appropriate.
|
||||
|
||||
.. note::
|
||||
|
||||
Follow the same rules as struct when documenting an enum.
|
||||
Use the simplified syntax to add the brief description.
|
||||
|
||||
Structure Comments Template
|
||||
***************************
|
||||
Structs 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, however, require that line 8 be left blank.
|
||||
|
||||
.. _unnamed_structs:
|
||||
|
||||
Unnamed structures or unions
|
||||
****************************
|
||||
|
||||
The *Sphinx* parser seems to get confused by unnamed structures, used
|
||||
specially in nested unions / structs:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct sensor_value {
|
||||
enum sensor_value_type type;
|
||||
union {
|
||||
struct {
|
||||
int32_t val1;
|
||||
int32_t val2;
|
||||
};
|
||||
double dval;
|
||||
};
|
||||
};
|
||||
|
||||
This will likely generate an error such as::
|
||||
|
||||
doc/api/io_interfaces.rst:14: WARNING: Invalid definition: Expected identifier in nested name. [error at 0]
|
||||
|
||||
^
|
||||
doc/api/io_interfaces.rst:14: WARNING: Invalid definition: Expected identifier in nested name. [error at 0]
|
||||
|
||||
^
|
||||
doc/api/io_interfaces.rst:14: WARNING: Invalid definition: Expected end of definition. [error at 12]
|
||||
sensor_value.__unnamed__
|
||||
------------^
|
||||
|
||||
There is no really good workaround we can use, other than live with
|
||||
the warning and ignore it. As well, because of this, the documentation
|
||||
of the members doesn't really work yet.
|
||||
|
||||
The issue reported to developers in
|
||||
https://github.com/sphinx-doc/sphinx/issues/2683.
|
||||
|
||||
When running into this issue, the member documentation has to be done
|
||||
with *@param* indicators, otherwise they won't be extracted:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/**
|
||||
* @brief UART device configuration.
|
||||
*
|
||||
* @param port Base port number
|
||||
* @param base Memory mapped base address
|
||||
* @param regs Register address
|
||||
* @param sys_clk_freq System clock frequency in Hz
|
||||
*/
|
||||
struct uart_device_config {
|
||||
union {
|
||||
uint32_t port;
|
||||
uint8_t *base;
|
||||
uint32_t regs;
|
||||
};
|
||||
|
||||
uint32_t sys_clk_freq;
|
||||
...
|
||||
|
||||
.. _unnamed_structs_var:
|
||||
|
||||
Unnamed structures or unions which declare a variable
|
||||
-----------------------------------------------------
|
||||
|
||||
A special case of this is non-anynoymous unnamed structs/unions, where
|
||||
a variable is defined. In this case, the workaround is much more
|
||||
simple. Consider:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
union dev_config {
|
||||
uint32_t raw;
|
||||
struct {
|
||||
uint32_t use_10_bit_addr : 1;
|
||||
uint32_t speed : 3;
|
||||
uint32_t is_master_device : 1;
|
||||
uint32_t is_slave_read : 1;
|
||||
uint32_t reserved : 26;
|
||||
} bits;
|
||||
};
|
||||
|
||||
This will likely generate an error such as::
|
||||
|
||||
doc/api/io_interfaces.rst:28: WARNING: Invalid definition: Expected identifier in nested name. [error at 19]
|
||||
struct dev_config::@61 dev_config::bits
|
||||
-------------------^
|
||||
|
||||
The simple solution is to name that unnamed struct, with an internal
|
||||
name (such as *__bits*):
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
union dev_config {
|
||||
uint32_t raw;
|
||||
struct __bits {
|
||||
uint32_t use_10_bit_addr : 1;
|
||||
uint32_t speed : 3;
|
||||
uint32_t is_master_device : 1;
|
||||
uint32_t is_slave_read : 1;
|
||||
uint32_t reserved : 26;
|
||||
} bits;
|
||||
};
|
||||
|
||||
|
||||
Structure Documentation Example
|
||||
*******************************
|
||||
|
||||
Correct:
|
||||
|
||||
.. literalinclude:: irq_test_common_commented.h
|
||||
:language: c
|
||||
:lines: 102-110
|
||||
: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:: irq_test_common_wrong.h
|
||||
:language: c
|
||||
:lines: 1-7
|
||||
:emphasize-lines: 2
|
||||
: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.
|
|
@ -1,197 +0,0 @@
|
|||
.. _troubleshooting:
|
||||
|
||||
Troubleshooting obscure warnings from Doxygen / Sphinx
|
||||
######################################################
|
||||
|
||||
Some code construct are problematic and
|
||||
push the limits of the documentation scanners. Here are some common
|
||||
issues and the solutions to them:
|
||||
|
||||
WARNING: Error when parsing function declaration.
|
||||
*************************************************
|
||||
|
||||
See :ref:`functions <functions>` and :ref:`function
|
||||
typedefs <function_definitions>`.
|
||||
|
||||
WARNING: Invalid definition: Expected end of definition. [error at 12] ... SOMETYPE.__unnamed__
|
||||
***************************************************************************************************
|
||||
|
||||
This might be one of:
|
||||
|
||||
- :ref:`Unnamed structs <unnamed_structs>`
|
||||
|
||||
- :ref:`Non-anonymous unnamed structs <unnamed_structs_var>`
|
||||
|
||||
We are waiting for a proper solution from the developers of
|
||||
sphinx/build. In the meantime, the workaround is to document the
|
||||
members with `@param` and ignore the warning adding a configuration
|
||||
item to :file:`.known-issues/doc/NAME.conf`.
|
||||
|
||||
Choose ``NAME`` wisely (eg: :file:`doc/bluetooth_xyz.conf`) for
|
||||
something related to documentation of the bluetooth subsystem.
|
||||
|
||||
WARNING: documented symbol `XYZ` was not declared or defined
|
||||
************************************************************
|
||||
|
||||
This happens when there is a documentation block for a function with
|
||||
*@fn* (or *@struct*, *@var*, etc ... ) but then the parser can't find
|
||||
the actual C definition/declaration of that function.
|
||||
|
||||
Check for mispellings in the documentation block vs the defines, and
|
||||
if the parser is being told to look for the C code where the
|
||||
definition/declaration is supposed to be (:file:`doc/doxygen.config`).
|
||||
|
||||
|
||||
|
||||
WARNING: unknown option: SOMECONFIGOPTION (or something else in caps)
|
||||
*********************************************************************
|
||||
|
||||
This comes when using:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
... when you enable :option:`SOMECONFIGOPTION`, the system...
|
||||
|
||||
to document a config option that is declared with:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
.. option:: CONFIG_SOMECONFIGOPTION
|
||||
|
||||
The fix is to refer to ``CONFIG_SOMECONFIGOPTION``:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
... when you enable :option:`CONFIG_SOMECONFIGOPTION`, the system...
|
||||
|
||||
|
||||
If you want to document a configuration parameter, you have to declare
|
||||
it first :literal:`.. config: NAME` and then refer to it. But if you
|
||||
won't declare it, just name it as:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
... when you enable ``NAME``, the system ...
|
||||
|
||||
WARNING: unknown option: SOMETHING=y
|
||||
====================================
|
||||
|
||||
Someone is trying to document a config option when set to *yes* versus
|
||||
*no* or similar. Usually looks like:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
... when :option:`CONFIG_SOMETHING=y`, then the system will bla...
|
||||
|
||||
change to:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
... when :option:`CONFIG_SOMETHING`\=y, then the system will bla...
|
||||
|
||||
|
||||
WARNING: undefined label: config_something (if the link has no caption the label must precede a section header)
|
||||
***************************************************************************************************************
|
||||
|
||||
``CONFIG_SOMETHING`` is not defined in any :literal:`.. option::
|
||||
CONFIG_SOMETHING` block, which means it probably doesn't exist in any
|
||||
``KConfig`` file. Verify if it is a valid config option.
|
||||
|
||||
...doc/reference/kconfig/CONFIG_SOMETHING.rst:NN: WARNING: Definition list ends without a blank line; unexpected unindent
|
||||
*************************************************************************************************************************
|
||||
|
||||
This usually originates from the help text in a Kconfig option which
|
||||
is not laid out properly.
|
||||
|
||||
For example::
|
||||
|
||||
config FAULT_DUMP
|
||||
int
|
||||
prompt "Fault dump level"
|
||||
default 2
|
||||
range 0 2
|
||||
help
|
||||
Different levels for display information when a fault occurs.
|
||||
|
||||
2: The default. Display specific and verbose information. Consumes
|
||||
the most memory (long strings).
|
||||
1: Display general and short information. Consumes less memory
|
||||
(short strings).
|
||||
0: Off.
|
||||
|
||||
The ReST parser will be confused by the lack of blank lines between
|
||||
the ``2``, ``1`` and ``0`` items, so help him by adding bullets and
|
||||
spacing the lines::
|
||||
|
||||
config FAULT_DUMP
|
||||
int
|
||||
prompt "Fault dump level"
|
||||
default 2
|
||||
range 0 2
|
||||
help
|
||||
Different levels for display information when a fault occurs.
|
||||
|
||||
- 2: The default. Display specific and verbose
|
||||
information. Consumes the most memory (long strings).
|
||||
|
||||
- 1: Display general and short information. Consumes less
|
||||
memory (short strings).
|
||||
|
||||
- 0: Off.
|
||||
|
||||
|
||||
WARNING: Unparseable C++ cross-reference: u'struct somestruct'
|
||||
**************************************************************
|
||||
|
||||
Usually followed by::
|
||||
|
||||
Invalid definition: Expected identifier in nested name, got keyword: struct [error at 6]
|
||||
struct somestruct
|
||||
------^
|
||||
|
||||
this probably means someone is trying to refer to a C symbol as C++;
|
||||
look for:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
...use the datatype :cpp:type:`struct somestruct` for doing...
|
||||
|
||||
and replace with:
|
||||
|
||||
.. code-block:: rest
|
||||
|
||||
...use the datatype :c:type:`struct somestruct` for doing...
|
||||
|
||||
FILE.rst:: WARNING: document isn't included in any toctree
|
||||
**********************************************************
|
||||
|
||||
This usually happens when you include a file inside another instead of
|
||||
sorting them with a TOC tree:
|
||||
|
||||
- double check: is this really necessary?
|
||||
- add :literal:`:orphan:` as the very first line of the file to get
|
||||
rid of this warning.
|
||||
|
||||
I have a set of functions with the same parameters and I am too lazy to type
|
||||
****************************************************************************
|
||||
|
||||
Use *@copydetails*:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/**
|
||||
* @copydetails FUNCTION_1
|
||||
*
|
||||
* This does the same as FUNCTION_1 but also sommersaults.
|
||||
*/
|
||||
|
||||
|
||||
The API documentation is missing a term or link to it when I use @ref term.
|
||||
****************************************************************************
|
||||
|
||||
When you use an :literal:`@ref term` in your doxygen comment, there must be
|
||||
a corresponding definition of :literal:`term` somewhere in the system. If
|
||||
there isn't, then there can't be a link to that term's defintion. Make sure
|
||||
you've spelled :literal:`term` correctly and there is whitespace after the
|
||||
term. Using :literal:`@ref term.` (at the end of a sentence for example) won't
|
||||
work so add a space like this: :literal:`@ref term .`
|
|
@ -1,104 +0,0 @@
|
|||
.. _typedefs:
|
||||
|
||||
Type Definition Documentation
|
||||
#############################
|
||||
|
||||
The documentation of type definitions, typedefs for short, is a simple
|
||||
yet 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 whereever it was defined.
|
||||
Doxygen connects the typedef and the complex type it uses automatically.
|
||||
|
||||
.. _function_definitions:
|
||||
|
||||
Workarounds for function definitions
|
||||
************************************
|
||||
|
||||
Some *typedefs* confuse the *Sphynx* / *breathe* parser; the construct:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/**
|
||||
* @brief Callback API upon firing of a trigger
|
||||
*
|
||||
* @param "struct device *dev" Pointer to the sensor device
|
||||
* @param "struct sensor_trigger *trigger" The trigger
|
||||
*/
|
||||
typedef void (*sensor_trigger_handler_t)(struct device *dev,
|
||||
struct sensor_trigger *trigger);
|
||||
|
||||
might generate a warning such as::
|
||||
|
||||
/home/e/inaky/z/kernel-oss.git/doc/api/io_interfaces.rst:70: WARNING: Error in type declaration.
|
||||
If typedef-like declaration:
|
||||
Type must be either just a name or a typedef-like declaration.
|
||||
If just a name:
|
||||
Error in declarator or parameters and qualifiers
|
||||
Invalid definition: Expected identifier in nested name, got keyword: int [error at 3]
|
||||
int(* sensor_trigger_set_t) (struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler)
|
||||
---^
|
||||
If typedef-like declaration:
|
||||
...
|
||||
|
||||
A workaround is to force the name of the typedef with the *@typedef*
|
||||
construct:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/**
|
||||
* @typedef sensor_trigger_handler_t
|
||||
* @brief Callback API upon firing of a trigger
|
||||
*
|
||||
* @param "struct device *dev" Pointer to the sensor device
|
||||
* @param "struct sensor_trigger *trigger" The trigger
|
||||
*/
|
||||
typedef void (*sensor_trigger_handler_t)(struct device *dev,
|
||||
struct sensor_trigger *trigger);
|
||||
|
||||
This issue has been reported and is awaiting a final fix
|
||||
(https://github.com/michaeljones/breathe/issues/267).
|
||||
|
||||
Type Definition Documentation Example
|
||||
*************************************
|
||||
|
||||
Correct:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/** 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 *);
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef void (*vvfn)(void); /* void-void function pointer */
|
||||
typedef void (*vvpfn)(void *); /* void-void_pointer function pointer */
|
||||
|
||||
The comments 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.
|
|
@ -1,70 +0,0 @@
|
|||
.. _variables:
|
||||
|
||||
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: 92-160
|
||||
:emphasize-lines: 15, 18, 21-23, 25, 31
|
||||
:linenos:
|
||||
|
||||
Lines 15 and 18 show the documentation for two variables.
|
||||
The blank line 17 is necessary to increase the clarity
|
||||
of the code and also so Doxygen can determine properly where
|
||||
the comment belongs.
|
||||
|
||||
Lines 21-23 show another acceptable way to document two variables with a
|
||||
similar function. Notice that only the first variable is documented.
|
||||
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 must be documented and the difference between them
|
||||
must be noted.
|
||||
|
||||
Example 2
|
||||
=========
|
||||
Variables outside of functions must be documented as well.
|
||||
|
||||
.. literalinclude:: ./hello_commented.c
|
||||
:lines: 119-127
|
||||
: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:`structs` and
|
||||
:ref:`typedefs` for further details.
|
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 12 KiB |
|
@ -1,336 +0,0 @@
|
|||
.. _gerrit:
|
||||
|
||||
Working with Gerrit
|
||||
###################
|
||||
|
||||
|
||||
Follow these instructions to collaborate on the Zephyr Project through the
|
||||
Gerrit review system.
|
||||
|
||||
Make sure to subscribe to the `mailing list`_ by filling out the
|
||||
`registration form`_.
|
||||
|
||||
Follow the steps available at :ref:`code_check_out` for information about how
|
||||
to access the source code using Git and Gerrit.
|
||||
|
||||
Gerrit assigns the following roles to users:
|
||||
|
||||
* **Submitters**: May submit changes for consideration, review other code
|
||||
changes, and make recommendations for acceptance or rejection by voting
|
||||
+1 or -1, respectively.
|
||||
* **Maintainers**: May approve or reject changes based upon feedback from
|
||||
reviewers voting +2 or -2, respectively.
|
||||
* **Builders**: May use the build automation infrastructure to verify the
|
||||
change.
|
||||
|
||||
A comprehensive walk-through of Gerrit is beyond the scope of this
|
||||
document. There are plenty of resources available on the Internet. Good
|
||||
summaries can be found here:
|
||||
|
||||
* `How to use Gerrit`_
|
||||
* `Gerrit User Guide`_
|
||||
|
||||
Commit Message Formatting
|
||||
*************************
|
||||
|
||||
When preparing to submit a change, each patch set will contain multiple edits
|
||||
or modifications to files. The patch set prefixed by a commit message detailing
|
||||
all the changes. The Zephyr Project has a few best practices for creating
|
||||
commit messages to ease the acceptance of the change.
|
||||
|
||||
* Don't reference the patch itself. For example, no "This patch..."
|
||||
|
||||
* The first line shall begin with the component being altered followed by a
|
||||
colon. For example, doc:, i2c:, spi:, microkernel: , etc. After the
|
||||
colon, a short (less than 70 characters) shall be provided after, detailing
|
||||
the brief basics of the change. As an example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
doc: Updating gerrit commit details
|
||||
|
||||
* When adding a new file to the tree, it is important to detail the source of
|
||||
origin on the file, provide attributions, and detail the intended usage. In
|
||||
cases where the file is an original to Zephyr, the commit message shall
|
||||
include the following:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Origin: Original
|
||||
|
||||
In cases where the file is imported from an external project, the commit
|
||||
message shall contain details regarding the original project, the location
|
||||
of the project, the SHA-id of the origin commit the file, the intended
|
||||
purpose, and if the file will be maintained by the Zephyr project, in other
|
||||
words, whether or not the Zephyr project will contain a localized branch or
|
||||
if it is a downstream copy.
|
||||
|
||||
For example a copy of a locally maintained import:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Origin: Contiki OS
|
||||
URL: http://www.contiki-os.org/
|
||||
commit: 853207acfdc6549b10eb3e44504b1a75ae1ad63a
|
||||
Purpose: Introduction of networking stack.
|
||||
Maintained-by: Zephyr
|
||||
|
||||
For example a copy of an externally maintained import:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
Origin: Tiny Crypt
|
||||
URL: https://github.com/01org/tinycrypt
|
||||
commit: 08ded7f21529c39e5133688ffb93a9d0c94e5c6e
|
||||
Purpose: Introduction of TinyCrypt
|
||||
Maintained-by: External
|
||||
|
||||
|
||||
Submitting a Change
|
||||
*******************
|
||||
|
||||
Currently, Gerrit is the only method to submit a change for review.
|
||||
|
||||
Before submitting, please ensure each commit follows :ref:`naming_conventions`
|
||||
guidelines. Directions for building the source code
|
||||
are beyond the scope of this document. Please see the :ref:`getting_started`
|
||||
for further detail.
|
||||
|
||||
When a change is ready for submission, Gerrit requires that the
|
||||
change be pushed to a special branch. The name of this special branch
|
||||
contains a reference to the final branch where the code should reside,
|
||||
once accepted.
|
||||
|
||||
For the Zephyr Project, the special branch is called :literal:`refs/for/master` .
|
||||
|
||||
1. Push the current local development branch to the gerrit server, type:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git push origin HEAD:refs/for/master
|
||||
|
||||
If the command executes correctly, the output should look similar to
|
||||
this:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
Counting objects: 3, done.
|
||||
Writing objects: 100% (3/3), 306 bytes | 0 bytes/s, done.
|
||||
Total 3 (delta 0), reused 0 (delta 0)
|
||||
remote: Processing changes: new: 1, refs: 1, done
|
||||
remote:
|
||||
remote: New Changes:
|
||||
remote: https://gerrit.zephyrproject.org/r/6 Test commit
|
||||
remote:
|
||||
To ssh://LFID@gerrit.zephyrproject.org:29418/zephyr
|
||||
* [new branch] HEAD -> refs/for/master
|
||||
|
||||
|
||||
The gerrit server generates a link where the change can be tracked.
|
||||
|
||||
2. Add reviewers to your change.
|
||||
|
||||
To specify a list of reviewers via the command line, add
|
||||
*%r=reviewer@project.org* to your push command. For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git push origin HEAD:refs/for/master%r=rev1@email.com,r=rev2@notemail.com
|
||||
|
||||
Alternatively, you can auto-configure GIT to add a set of reviewers if your commits will
|
||||
have the same reviewers all at the time.
|
||||
|
||||
To add a list of default reviewers, open the :file:`.git/config` file in the project
|
||||
directory and add the following line in the :literal:`[ branch “master” ]` section:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[branch "master"] #.... push =
|
||||
HEAD:refs/for/master%r=rev1@email.com,r=rev2@notemail.com`
|
||||
|
||||
|
||||
Make sure to use actual email addresses instead of the :literal:`@email.com and
|
||||
@notemail.com` addressses. Don't forget to replace :literal:`origin` with your git
|
||||
remote name.
|
||||
|
||||
Reviewing Using Gerrit
|
||||
**********************
|
||||
|
||||
An example of a gerrit change review page:
|
||||
|
||||
.. figure:: figures/gerrit01.png
|
||||
:scale: 75 %
|
||||
:alt: Gerrit Review Page
|
||||
|
||||
An example of a Gerrit change review page.
|
||||
|
||||
The fields highlighted in yellow are of interest and require a
|
||||
little more explanation.
|
||||
|
||||
|
||||
* **Add**: This button allows the change submitter to manually add names of
|
||||
people who should review a change; start typing a name and the system
|
||||
will auto-complete based on the list of people registered and with
|
||||
access to the system. They will be notified by email that you are
|
||||
requesting their input.
|
||||
|
||||
* **Abandon**: This button is available to the submitter only; it allows a
|
||||
committer to abandon a change and remove it from the merge queue.
|
||||
|
||||
* **Change-ID**: This ID is generated by Gerrit (or system). It becomes
|
||||
useful when the review process determines that your commit(s) have to
|
||||
be amended. You may submit a new version; and if the same Change-ID
|
||||
header (and value) are present, Gerrit will remember it and present
|
||||
it as another version of the same change.
|
||||
|
||||
* **Status**: Currently, the example change is in review status, as indicated
|
||||
by “Needs Verified” in the upper-left corner. The list of
|
||||
Reviewers will all emit their opinion, voting +1 if they agree to the
|
||||
merge, -1 if they disagree. Gerrit users with a Maintainer role can
|
||||
agree to the merge or refuse it by voting +2 or -2 respectively.
|
||||
|
||||
Notifications are sent to the email address in your commit message's
|
||||
Signed-off-by line. Visit your `gerrit dashboard`_, to check the progress
|
||||
of your requests.
|
||||
|
||||
Click on a change and see a history tab similar to the one below:
|
||||
|
||||
.. figure:: figures/gerrit02.png
|
||||
:scale: 75 %
|
||||
:alt: Gerrit Feedback Page
|
||||
|
||||
The history tab in Gerrit will show you the in-line comments and
|
||||
the author of the review.
|
||||
|
||||
Viewing Pending Changes
|
||||
***********************
|
||||
|
||||
- Find all pending changes by clicking on the
|
||||
:menuselection:`All --> Changes` link in the upper-left corner, or
|
||||
directly at: `<https://gerrit.zephyrproject.org/r/#/q/project:zephyr>`_
|
||||
|
||||
If you collaborate in multiple projects, you may wish to limit searching to
|
||||
the specific branch through the search bar in the upper-right side.
|
||||
|
||||
Add the filter *project:zephyr* to limit the visible changes to
|
||||
only those from the Zephyr Project.
|
||||
|
||||
.. figure:: figures/gerrit03.png
|
||||
:scale: 75 %
|
||||
:alt: Find pending changes for zephyr repo
|
||||
|
||||
This is an example of a search for all changes of *project:zephyr*.
|
||||
|
||||
- List all current changes you submitted, or list just those changes in need
|
||||
of your input by clicking on :menuselection:`My --> Changes` or going to:
|
||||
`gerrit dashboard`_
|
||||
|
||||
.. figure:: figures/gerrit04.png
|
||||
:scale: 75 %
|
||||
:alt: User gerrit dashboard
|
||||
|
||||
View of Gerrit dashboard.
|
||||
|
||||
Reviewing a Change
|
||||
******************
|
||||
|
||||
1. Click on a link for incoming or outgoing review, such as
|
||||
*“Add REAME file as test for submit”* shown in this figure:
|
||||
|
||||
.. figure:: figures/gerrit05.png
|
||||
:scale: 75 %
|
||||
:alt: Incoming and Outgoing Reviews
|
||||
|
||||
An example of incoming and outgoing items in review.
|
||||
|
||||
2. The details of the change and its current status are loaded:
|
||||
|
||||
.. figure:: figures/gerrit06.png
|
||||
:scale: 75 %
|
||||
:alt: Detailed View of a Change in Gerrit
|
||||
|
||||
An example of the detailed view of a change in Gerrit.
|
||||
|
||||
The highlighted items require further explanation.
|
||||
|
||||
From left to right:
|
||||
|
||||
* **Status:** Displays the current status of the change. In the
|
||||
example below, the status reads: Needs Verified.
|
||||
|
||||
* **Reply:** Click on this button after reviewing to add a final
|
||||
review message and a score, -1, 0 or +1.
|
||||
|
||||
* **Patch Sets:** If multiple revisions of a patch exist, this button
|
||||
enables navigation among revisions to see the changes. By default,
|
||||
the most recent revision is presented.
|
||||
|
||||
* **Download:** This button brings up another window with multiple
|
||||
options to download or checkout the current changeset. The button on
|
||||
the right copies the line to your clipboard. You can easily paste it
|
||||
into your git interface to work with the patch as you prefer.
|
||||
|
||||
Underneath the commit information, the files that have been changed by
|
||||
this patch are displayed.
|
||||
|
||||
3. Click on a filename to review it. Select the code base to differentiate
|
||||
against. The default is :guilabel:`Base` and it will generally be
|
||||
what is needed.
|
||||
|
||||
.. figure:: figures/gerrit07.png
|
||||
:scale: 50 %
|
||||
:alt: Code Base Location
|
||||
|
||||
Shows the list of changed files.
|
||||
|
||||
4. The review page presents the changes made to the file. At the top of
|
||||
the review, the presentation shows some general navigation options.
|
||||
Navigate through the patch set using the arrows on the top
|
||||
right corner. It is possible to go to the previous or next file in the
|
||||
set or to return to the main change screen. Click on the yellow sticky
|
||||
pad to add comments to the whole file.
|
||||
|
||||
.. figure:: figures/gerrit08.png
|
||||
:scale: 75 %
|
||||
:alt: Review Page Navigation
|
||||
|
||||
The focus of the page is on the comparison window. The changes made
|
||||
are presented in green on the right versus the base version on the left.
|
||||
Double click to highlight the text within the actual change to provide
|
||||
feedback on a specific section of the code. Press *c* once the code is
|
||||
highlighted to add comments to that section.
|
||||
|
||||
5. After adding the comment, it is saved as a *Draft*.
|
||||
|
||||
.. figure:: figures/gerrit09.png
|
||||
:scale: 75 %
|
||||
:alt: Saved Comment as Draft
|
||||
|
||||
Shows a comment saved as a draft.
|
||||
|
||||
6. Once you have reviewed all files and provided feedback, click the
|
||||
*green up arrow* at the top right to return to the main change page. Click
|
||||
the :guilabel:`Reply` button, write some final comments, and submit your score for
|
||||
the patch set. Click :guilabel:`Post` to submit the review of each reviewed file, as
|
||||
well as your final comment and score. Gerrit sends an email to the
|
||||
change-submitter and all listed reviewers. Finally, it logs the review
|
||||
for future reference. All individual comments are saved as *Draft* until
|
||||
the :guilabel:`Post` button is clicked.
|
||||
|
||||
.. figure:: figures/gerrit10.png
|
||||
:scale: 75 %
|
||||
:alt: Submitting the Final Comment and Review
|
||||
|
||||
Shows the dialog box for submitting the final comment and the review
|
||||
score of a change.
|
||||
|
||||
|
||||
.. _registration form: https://lists.zephyrproject.org/mailman3/lists/users.lists.zephyrproject.org/
|
||||
|
||||
.. _mailing list: users@lists.zephyrproject.org
|
||||
|
||||
.. _How to use Gerrit: https://wiki.iotivity.org/how_to_use_gerrit
|
||||
|
||||
.. _Gerrit User Guide: https://gerrit-review.googlesource.com/Documentation/intro-user.html
|
||||
|
||||
.. _gerrit dashboard: https://gerrit.zephyrproject.org/r/#/dashboard/self
|
|
@ -1,134 +0,0 @@
|
|||
.. _gerrit_accounts:
|
||||
|
||||
Requesting a Linux Foundation Account
|
||||
#####################################
|
||||
|
||||
Contributions to the Zephyr kernel code base require a Linux Foundation account.
|
||||
Follow the steps below to create a Linux Foundation account.
|
||||
|
||||
Creating a Linux Foundation ID
|
||||
******************************
|
||||
|
||||
#. Go to the `Linux Foundation ID website`_.
|
||||
|
||||
#. Select the option :guilabel:`I need to create a Linux Foundation ID`.
|
||||
|
||||
.. figure:: figures/setting_up01.png
|
||||
:scale: 75 %
|
||||
:alt: linuxfoundation.org identity page
|
||||
|
||||
#. Fill out the form that appears:
|
||||
|
||||
.. figure:: figures/setting_up02.png
|
||||
:scale: 75 %
|
||||
:alt: New account form
|
||||
|
||||
#. Open your email account and look for a message with the subject line:
|
||||
"Validate your Linux Foundation ID email".
|
||||
|
||||
#. Open the received URL to validate your email address.
|
||||
|
||||
#. Verify the browser displays the message :guilabel:`You have successfully
|
||||
validated your e-mail address`.
|
||||
|
||||
#. Access `Gerrit`_ by selecting :guilabel:`Sign In`:
|
||||
|
||||
.. figure:: figures/setting_up03.png
|
||||
:scale: 75 %
|
||||
:alt: Gerrit without being signed in
|
||||
|
||||
#. Use your Linux Foundation ID to Sign In:
|
||||
|
||||
.. figure:: figures/setting_up04.png
|
||||
:scale: 75 %
|
||||
:alt: Gerrit sign in screen
|
||||
|
||||
Configuring Gerrit to Use SSH
|
||||
*****************************
|
||||
|
||||
Gerrit uses SSH to interact with your Git client. A SSH private key
|
||||
needs to be generated on the development machine with a matching public
|
||||
key on the Gerrit server.
|
||||
|
||||
If you already have a SSH key-pair, skip this section.
|
||||
|
||||
As an example, we provide the steps to generate the SSH key-pair on a Linux
|
||||
environment. Follow the equivalent steps on your OS.
|
||||
|
||||
#. Create a key-pair, enter:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ ssh-keygen -t rsa -C "John Doe john.doe@example.com"
|
||||
|
||||
.. note::
|
||||
This will ask you for a password to protect the private key as it
|
||||
generates a unique key. Please keep this password private, and DO NOT
|
||||
enter a blank password.
|
||||
|
||||
The generated key-pair is found in:
|
||||
:file:`~/.ssh/id_rsa` and :file:`~/.ssh/id_rsa.pub`.
|
||||
|
||||
#. Add the private key in the :file:`id_rsa` file in your key ring:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ ssh-add ~/.ssh/id_rsa
|
||||
|
||||
Once the key-pair has been generated, the public key must be added to Gerrit.
|
||||
|
||||
Follow these steps to add your public key :file:`id_rsa.pub` to the Gerrit
|
||||
account:
|
||||
|
||||
1. Go to `Gerrit`_.
|
||||
|
||||
2. Click on your account name in the upper right corner.
|
||||
|
||||
3. From the pop-up menu, select :guilabel:`Settings`.
|
||||
|
||||
4. On the left side menu, click on :guilabel:`SSH Public Keys`.
|
||||
|
||||
5. Paste the contents of your public key :file:`~/.ssh/id_rsa.pub` and click
|
||||
:guilabel:`Add key`.
|
||||
|
||||
.. note::
|
||||
The :file:`id_rsa.pub` file can be opened with any text editor. Ensure
|
||||
that all the contents of the file are selected, copied and pasted into the
|
||||
:guilabel:`Add SSH key` window in Gerrit.
|
||||
|
||||
.. warning::
|
||||
Potential Security Risk! Do not copy your private key
|
||||
:file:`~/.ssh/id_rsa` Use only the public :file:`~/.ssh/id_rsa.pub`.
|
||||
|
||||
.. _code_check_out:
|
||||
|
||||
Checking Out the Source Code
|
||||
****************************
|
||||
|
||||
#. Ensure that SSH has been set up properly. See
|
||||
`Configuring Gerrit to Use SSH`_ for details.
|
||||
|
||||
#. Clone the repository with your Linux Foundation ID (<LFID>):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git clone ssh://<LFID>@gerrit.zephyrproject.org:29418/zephyr zephyr-project
|
||||
|
||||
You have successfully checked out a copy of the source code to your local
|
||||
machine.
|
||||
|
||||
.. important::
|
||||
Linux users need to download the Zephyr SDK even after successfully
|
||||
cloning the source code. The SDK contains packages that are not part of
|
||||
the Zephyr Project. See :ref:`zephyr_sdk` for details.
|
||||
|
||||
Gerrit Commit Message Hook
|
||||
**************************
|
||||
|
||||
.. include:: gerrit_practices.rst
|
||||
:start-line: 42
|
||||
:end-line: 49
|
||||
|
||||
.. _Linux Foundation ID website: https://identity.linuxfoundation.org
|
||||
|
||||
.. _Gerrit: https://gerrit.zephyrproject.org/
|
|
@ -1,426 +0,0 @@
|
|||
.. _gerrit_practices:
|
||||
|
||||
Gerrit Recommended Practices
|
||||
############################
|
||||
|
||||
This document presents some best practices to help you use Gerrit more
|
||||
effectively. The intent is to show how content can be submitted easily. Use the
|
||||
recommended practices to reduce your troubleshooting time and improve
|
||||
participation in the community.
|
||||
|
||||
Browsing the Git Tree
|
||||
*********************
|
||||
|
||||
Visit `Gerrit`_, then select
|
||||
:menuselection:`Projects --> List --> SELECT-PROJECT --> Branches`. Select
|
||||
the branch that interests you, click on :guilabel:`gitweb` located on the
|
||||
right-hand side. Now, :program:`gitweb` loads your selection on the Git web
|
||||
interface and redirects appropriately.
|
||||
|
||||
Watching a Project
|
||||
******************
|
||||
|
||||
Visit `Gerrit`_, select :guilabel:`Settings`, located on the top right corner.
|
||||
Select :guilabel:`Watched Projects` and then add any projects that interest you.
|
||||
|
||||
|
||||
Commit Messages
|
||||
***************
|
||||
|
||||
Gerrit follows the Git commit message format. Ensure the headers are at the
|
||||
bottom and don't contain blank lines between one another. The following example
|
||||
shows the format and content expected in a commit message:::
|
||||
|
||||
Subsystem: Brief one line description.
|
||||
|
||||
Summary of the changes made referencing why, what and how.
|
||||
For documented code reference what part of the code the change is applied.
|
||||
|
||||
Jira: ZEP-100
|
||||
Change-Id: LONGHEXHASH
|
||||
Signed-off-by: Your Name your.email@example.org
|
||||
AnotherExampleHeader: An Example of another Value
|
||||
|
||||
The Gerrit server provides a precommit hook to autogenerate the Change-Id which
|
||||
is one time use. Use the following command as an example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ scp -p -P 29418 <LFID>@gerrit.zephyrproject.org:hooks/commit-msg LOCALREPODIR/.git/hooks/
|
||||
|
||||
.. note::
|
||||
|
||||
replace <LFID> with your Linux Foundation ID.
|
||||
replace LOCALREPODIR with the directory where you cloned the project.
|
||||
|
||||
The command above needs to be entered only once.
|
||||
|
||||
|
||||
Avoid Pushing Untested Work to a Gerrit Server
|
||||
**********************************************
|
||||
|
||||
To avoid pushing untested work to Gerrit, we recommend you follow these steps:
|
||||
|
||||
1. Rename your tree:
|
||||
|
||||
- Change the name of the remote Git tree from *origin* to *another name*.
|
||||
This prevents complications when work is unintentionally pushed to Gerrit.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git remote rename origin another-name
|
||||
|
||||
- Use `precommit hooks`_ to scan for problematic words in your commit.
|
||||
Follow the installation instructions in the :file:`README.rst` for
|
||||
checkpatch.
|
||||
Update the :literal:`checkarray` with keywords that might signal danger in
|
||||
your commits.
|
||||
|
||||
.. _precommit hooks: https://github.com/niden/Git-Pre-Commit-Hook-for-certain-words
|
||||
|
||||
2. Think before you act:
|
||||
|
||||
- Check your work at least three times before pushing your change to Gerrit.
|
||||
Be mindful of what information you are publishing.
|
||||
|
||||
Keeping Track of Changes
|
||||
************************
|
||||
|
||||
* Set Gerrit to send you emails:
|
||||
|
||||
- Gerrit will add you to the email distribution list for a change if a
|
||||
developer adds you as a reviewer, or if you comment on a specific Patch
|
||||
Set.
|
||||
|
||||
* Opening a change in Gerrit's review interface is a quick way to follow that
|
||||
change.
|
||||
|
||||
* Watch projects in the Gerrit projects section at `Gerrit`_, select at least
|
||||
*New Changes, New Patch Sets, All Comments* and *Submitted Changes*.
|
||||
|
||||
|
||||
Emails contain some helpful headers for filtering:
|
||||
|
||||
* **In-Reply-To:** used for threading.
|
||||
The following platforms may or may not use this header for filtering:
|
||||
|
||||
- iPhone - OK.
|
||||
- Evolution - OK.
|
||||
- Thunderbird - OK.
|
||||
- Outlook - Not supported.
|
||||
|
||||
* **X-Gerrit-MessageType:** comment, newpatchset, etc.
|
||||
* **Reply-To:** Replies to whom actions caused the email to be sent.
|
||||
|
||||
- Autobuilders usually look like ``sys_EXAMPLE@intel.com``
|
||||
|
||||
Always track the projects you are working on; also see the feedback/comments
|
||||
mailing list to learn and help others ramp up.
|
||||
|
||||
|
||||
Topic branches
|
||||
**************
|
||||
|
||||
Topic branches are temporary branches that you push to commit a set of
|
||||
logically-grouped dependent commits:
|
||||
|
||||
To push changes from :file:`REMOTE/master` tree to Gerrit for being reviewed as
|
||||
a topic in **TopicName** use the following command as an example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git push REMOTE HEAD:refs/for/master/TopicName
|
||||
|
||||
The topic will show up in the review :abbr:`UI` and in the
|
||||
:guilabel:`Open Changes List`. Topic branches will disappear from the master
|
||||
tree when its content is merged.
|
||||
|
||||
|
||||
Creating a Cover Letter for a Topic
|
||||
===================================
|
||||
|
||||
You may decide whether or not you'd like the cover letter to appear in the
|
||||
history.
|
||||
|
||||
1. To make a cover letter that appears in the history, use this command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git commit --allow-empty
|
||||
|
||||
Edit the commit message, this message then becomes the cover letter.
|
||||
The command used doesn't change any files in the source tree.
|
||||
|
||||
2. To make a cover letter that doesn't appear in the history follow these steps:
|
||||
|
||||
* Put the empty commit at the end of your commits list so it can be ignored without having to rebase.
|
||||
|
||||
* Now add your commits
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git commit ...
|
||||
$ git commit ...
|
||||
$ git commit ...
|
||||
|
||||
* Finally, push the commits to a topic branch. The following command is an
|
||||
example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git push REMOTE HEAD:refs/for/master/TopicName
|
||||
|
||||
If you already have commits but you want to set a cover letter, create an empty
|
||||
commit for the cover letter and move the commit so it becomes the last commit
|
||||
on the list. Use the following command as an example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git rebase -i HEAD~#Commits
|
||||
|
||||
Be careful to uncomment the commit before moving it.
|
||||
:makevar:`#Commits` is the sum of the commits plus your new cover letter.
|
||||
|
||||
|
||||
Finding Available Topics
|
||||
========================
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ ssh -p 29418 gerrit.zephyrproject.org gerrit query \ status:open project:zephyr branch:master \
|
||||
| grep topic: | sort -u
|
||||
|
||||
* *gerrit.zephyrproject.org* Is the current URL where the project is hosted.
|
||||
* *status* Indicates the topic's current status: open , merged, abandoned, draft, merge conflict.
|
||||
* *project* Refers to the current name of the project, in this case zephyr.
|
||||
* *branch* The topic is searched at this branch.
|
||||
* *topic* The name of an specific topic, leave it blank to include them all.
|
||||
* *sort* Sorts the found topics, in this case by update (-u).
|
||||
|
||||
Downloading or Checking Out a Change
|
||||
************************************
|
||||
|
||||
In the review UI, on the top right corner, the **Download** link provides a
|
||||
list of commands and hyperlinks to checkout or download diffs or files.
|
||||
|
||||
We recommend the use of the *git review* plugin.
|
||||
The steps to install git review are beyond the scope of this document.
|
||||
Refer to the `git review documentation`_ for the installation process.
|
||||
|
||||
.. _git review documentation: https://wiki.openstack.org/wiki/Documentation/HowTo/FirstTimers
|
||||
|
||||
To check out a specific change using Git, the following command usually works:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git review -d CHANGEID
|
||||
|
||||
If you don't have Git-review installed, the following commands will do the same
|
||||
thing:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git fetch REMOTE refs/changes/NN/CHANGEIDNN/VERSION \ && git checkout FETCH_HEAD
|
||||
|
||||
For example, for the 4th version of change 2464, NN is the first two digits
|
||||
(24):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git fetch REMOTE refs/changes/24/2464/4 \ && git checkout FETCH_HEAD
|
||||
|
||||
|
||||
Using Draft Branches
|
||||
********************
|
||||
|
||||
You can use draft branches to add specific reviewers before you publishing your
|
||||
change. The Draft Branches are pushed to :file:`refs/drafts/master/TopicName`
|
||||
|
||||
The next command ensures a local branch is created:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git checkout -b BRANCHNAME
|
||||
|
||||
|
||||
The next command pushes your change to the drafts branch under **TopicName**:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git push REMOTE HEAD:refs/drafts/master/TopicName
|
||||
|
||||
|
||||
|
||||
Using Sandbox Branches
|
||||
**********************
|
||||
|
||||
You can create your own branches to develop features. The branches are pushed to
|
||||
the :file:`refs/sandbox/USERNAME/BRANCHNAME` location.
|
||||
|
||||
These commands ensure the branch is created in Gerrit's server.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git checkout -b sandbox/USERNAME/BRANCHNAME
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git push --set-upstream REMOTE HEAD:refs/heads/sandbox/USERNAME/BRANCHNAME
|
||||
|
||||
Usually, the process to create content is:
|
||||
|
||||
* develop the code,
|
||||
* break the information into small commits,
|
||||
* submit changes,
|
||||
* apply feedback,
|
||||
* rebase.
|
||||
|
||||
The next command pushes forcibly without review
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git push REMOTE sandbox/USERNAME/BRANCHNAME
|
||||
|
||||
You can also push forcibly with review
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git push REMOTE HEAD:ref/for/sandbox/USERNAME/BRANCHNAME
|
||||
|
||||
|
||||
Updating the Version of a Change
|
||||
********************************
|
||||
|
||||
During the review process, you might be asked to update your change. It is
|
||||
possible to submit multiple versions of the same change. Each version of the
|
||||
change is called a patch set.
|
||||
|
||||
Always maintain the **Change-Id** that was assigned.
|
||||
For example, there is a list of commits, **c0...c7**, which were submitted as a
|
||||
topic branch:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git log REMOTE/master..master
|
||||
|
||||
c0
|
||||
...
|
||||
c7
|
||||
|
||||
$ git push REMOTE HEAD:refs/for/master/SOMETOPIC
|
||||
|
||||
After you get reviewers' feedback, there are changes in **c3** and **c4** that
|
||||
must be fixed. If the fix requires rebasing, rebasing changes the commit Ids,
|
||||
see the :ref:`rebasing` section for more information. However, you must keep
|
||||
the same Change-Id and push the changes again:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git push REMOTE HEAD:refs/for/master/SOMETOPIC
|
||||
|
||||
This new push creates a patches revision, your local history is then cleared.
|
||||
However you can still access the history of your changes in Gerrit on the
|
||||
:guilabel:`review UI` section, for each change.
|
||||
|
||||
It is also permitted to add more commits when pushing new versions.
|
||||
|
||||
.. _rebasing:
|
||||
|
||||
Rebasing
|
||||
********
|
||||
|
||||
Rebasing is usually the last step before pushing changes to Gerrit; this allows
|
||||
you to make the necessary *Change-Ids*. The *Change-Ids* must be kept the same.
|
||||
|
||||
* **squash:** mixes two or more commits into a single one.
|
||||
* **reword:** changes the commit message.
|
||||
* **edit:** changes the commit content.
|
||||
* **reorder:** allows you to interchange the order of the commits.
|
||||
* **rebase:** stacks the commits on top of the master.
|
||||
|
||||
For more information you can visit `Atlasian`_ , `git book`_ and `git rebase`_.
|
||||
|
||||
.. _Atlasian: https://www.atlassian.com/git/tutorials/rewriting-history/
|
||||
.. _git book: http://git-scm.com/book/en/v2/Git-Branching-Rebasing
|
||||
.. _git rebase: http://www.slideshare.net/forvaidya/git-rebase-howto
|
||||
|
||||
Rebasing During a Pull
|
||||
**********************
|
||||
|
||||
Before pushing a rebase to your master, ensure that the history has a
|
||||
consecutive order.
|
||||
|
||||
For example, your :file:`REMOTE/master` has the list of commits from **a0** to
|
||||
**a4**; Then, your changes **c0...c7** are on top of **a4**; thus:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git log --oneline REMOTE/master..master
|
||||
|
||||
a0
|
||||
a1
|
||||
a2
|
||||
a3
|
||||
a4
|
||||
c0
|
||||
c1
|
||||
...
|
||||
c7
|
||||
|
||||
If :file:`REMOTE/master` receives commits **a5**, **a6** and **a7**. Pull with a
|
||||
rebase as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git pull --rebase REMOTE master
|
||||
|
||||
This pulls **a5-a7** and re-apply **c0-c7** on top of them:
|
||||
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git log --oneline REMOTE/master..master
|
||||
a0
|
||||
...
|
||||
a7
|
||||
c0
|
||||
c1
|
||||
...
|
||||
c7
|
||||
|
||||
Getting Better Logs from Git
|
||||
****************************
|
||||
|
||||
Use these commands to change the configuration of Git in order to produce better
|
||||
logs:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git config log.abbrevCommit true
|
||||
|
||||
The command above sets the log to abbreviate the commits' hash.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git config log.abbrev 5
|
||||
|
||||
The command above sets the abbreviation length to the last 5 characters of the
|
||||
hash.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git config format.pretty oneline
|
||||
|
||||
The command above avoids the insertion of an unnecessary line before the Author
|
||||
line.
|
||||
|
||||
To make these configuration changes specifically for the current Git user,
|
||||
you must add the path option :``--global`` to :command:`config` as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ git config –-global log.abbrevCommit true
|
||||
$ git config –-global log.abbrev 5
|
||||
$ git config –-global format.pretty oneline
|
||||
|
||||
.. _Gerrit: http://gerrit.zephyrproject.org
|
|
@ -1,13 +0,0 @@
|
|||
:orphan:
|
||||
|
||||
.. _maintainers:
|
||||
|
||||
Information Regarding Maintainers
|
||||
#################################
|
||||
|
||||
Read this information to learn how maintainers review changes using Gerrit.
|
||||
|
||||
Once a change is sent to Gerrit for review the maintainers
|
||||
receive an email requesting them to review the change. The master
|
||||
branch should never be rebased. Code can be reverted as necessary,
|
||||
instead of rewriting the history.
|
|
@ -41,7 +41,9 @@ You have successfully checked out a copy of the source code to your local
|
|||
machine.
|
||||
|
||||
Once you're ready to start contributing, follow the steps to make yourself
|
||||
a Linux Foundation account at :ref:`gerrit_accounts`.
|
||||
a Linux Foundation account at `Gerrit Accounts`_.
|
||||
|
||||
.. _Gerrit Accounts: https://wiki.zephyrproject.org/view/Gerrit_accounts
|
||||
|
||||
Building and Running an Application
|
||||
***********************************
|
||||
|
|