Code Contribution

Contribution Guide

We sincerely thank you for your contribution, and welcome to submit the code through GitHub's fork and Pull Request processes. RT-Thread 3.1.0 version and its earlier versions follow the GPL V2 open source license agreement. Versions from the 3.1.0 version onwards follow the Apache License 2.0 open source license agreement.

All the real-time operating system kernel and open source components can be used free of charge for commercial products, there is no potential commercial risk and you will not being request to publish application source.

RT-Thread Coding Style

This is an developing instruction for RT-Thread developers. As an open source software, RT-Thread is done by the cooperation of different people. This document is a guide for RT-Thread developers and please obey it if you are. RT-Thread users could also get to know some conventions in the code through it and thus easier to understand the implementations of RT-Thread.

1. Directory Naming

In normal conditions, please name directories in lower-case. Directories should have descriptive names. For example, the port of a chip should be composed of the name of the chip and the category of the chip. Directories under components/ should stand for what the component does.

2. File Naming

In normal conditions, please name files in lower-case. If the file is referencing other places, it can have the original name. To avoid naming collision, do not use general names or the names that are frequently used.

3. Header Files

To avoid include the same header file for multiple times, you need to define a symbol like this:

#ifndef __FILE_H__
#define __FILE_H__
/* header file content */
#endif

The symbol should begin and end with "__" to avoid naming collision. The words of the file name should be connected by "_".

4. Header File Comments

In every header file, there should be copyright information and Change Log record like this:

/*
  * File      : rtthread.h
  * This file is part of RT-Thread RTOS
  * COPYRIGHT (C) 2006, RT-Thread Development Team
  *
  * The license and distribution terms for this file may be
  * found in the file LICENSE in this distribution or at
  * http://www.rt-thread.org/license/LICENSE.
  *
  * Change Logs:
  * Date           Author       Notes
  * 2006-03-18     Bernard      the first version
  * 2006-04-26     Bernard      add semaphore APIs
  * ...
*/

5. Structure Defines

Please name structures in lower-case and connect words with "_". For example:

struct rt_list_node
{
    struct rt_list_node *next;
    struct rt_list_node *prev;
};

Braces should have their own lines and the members should be defines with indent.

The names of type defines such like structure types should be the structure name plus "_t". For example:

typedef struct rt_list_node rt_list_t;

In order to be easily referenced, the types of objects in kernel is pointer. For example:

typedef struct rt_timer* rt_timer_t;

6. Macros

In RT-Thread, please use upper-case names for macro definitions. Words are connected by "_". Like:

#define RT_TRUE  

7. Function Naming and Declaration

Please name functions in lower-case and separate words with "_". API provided to upper application should be declared in header files. If the function don't have parameters, it should be declared as void:

rt_thread_t rt_thread_self(void);

8. Commenting

Please use English to comment. There shouldn't be too much comments and the comments should describe what does the code do. And it should describe how the complicated algorithm works. Comments to statements should be placed before them or right of them. Anther places are illegal.

9. Indent

Please use TAB or 4 spaces to indent. It's preferred to use 4 spaces. If no other special meanings, the indent should begin right after "{":

if (condition)
{
    /* others */
}

The only one exception is switch. In switch-case statements, "case" should be aligned with "switch":

switch (value)
{
  case value1:
    break;
}

"case" is aligned with "switch", the following code block should be indented.

10. Braces and Spaces

For ease of reading, it is advised that braces should occupy the whole line instead of following other statements. Like:

if (condition)
{
    /* others */
}

When matching braces have their own lines, the reader would identify the code blocks easily.

There should be a space before parentheses when it's not a function call. For example:

if (x <= y)
{
    /* others */
}

for (index = 0; index < MAX_NUMBER; index ++)
{
    /* others */
}

In expressions, there should be a space between most binary and ternary operators and the strings. No spaces around(inside) parentheses, like:

if ( x <= y )
{
    /* other */
}

This is a bad practice.

11. trace, log Informations

In RT-Thread, rt_kprintf is a commonly used logging routine. In RT-Thread rt_kprintf is implemented as a polling, non-interrupting string output. It is suitable in "instant" situations such as interrupt context. The polling method would have influence to the timing sequence of the log output.

It is not recommended to use rt_kprintf frequently. Unless you are aware of that it's not a big deal to run slower.

Logging should be off by default and can be turned on by a switch(e.g. a variable or a macro). When logging, it should be easy to understand and easy to determine where the problem is.

12. Functions

Functions in kernel should be K.I.S.S. If the function is too long, you should split it into smaller ones and make each of them simplified and easy to understand.

13. Objects

The kernel of RT-Thread uses object-oriented tech in C. The naming convention is: structure names are the object names, object names + verb phrases are the method names of objects:

struct rt_timer
{
    struct rt_object parent;
    /* other fields */
};
typedef struct rt_timer* rt_timer_t;

The definition of structure rt_timer stands for the object definition of timer object.

rt_timer_t rt_timer_create(const char* name,
    void (*timeout)(void* parameter), void* parameter,
    rt_tick_t time, rt_uint8_t flag);
rt_err_t rt_timer_delete(rt_timer_t timer);
rt_err_t rt_timer_start(rt_timer_t timer);
rt_err_t rt_timer_stop(rt_timer_t timer);

rt_timer + verb phrase stands for the method that could be used on timer object.

When creating a new object, think twice on memory allocations: whether a static object could be created or it could only created dynamically on heap.

14. Use astyle to format the code automatically

parameters: --style=allman
            --indent=spaces=4
            --indent-preproc-block
            --pad-oper
            --pad-header
            --unpad-paren
            --suffix=none
            --align-pointer=name
            --lineend=linux
            --convert-tabs
            --verbose

Contribution Process

Preparation

Install Git: You need to add Git's directory to the system environment variable.

Contribution Process

Now take RT-Thread repository as an example to illustrate the process of contributing code:

Fork

Fork the RT-Thread/rt-thread repository into your git repository.

fork rt-thread repository

Clone

In your repository, copy the repository links after your fork:

clone rt-thread from your repo

You can use the git clone command to copy the repository to your PC:

git clone [url]

git clone

Create a New Branch

It is recommended that you create your own development branch based on the master branch, and use following commands to create a new branch:

git checkout -b YourBranchName

For example, create a branch named "dev": git checkout -b dev.

Developing

Modify bugs and submit new functional code. For example, suppose the developer adds a USB driver:

Add a USB driver

Temporarily Store Modified Files

Add all changes to the temporary area:

git add .

If you only want to add some specified files to the temporary area, use other commands of git add.

Commit

Submit this modification to the local repository:

git commit -m "Describe your submission here"

Note: If there are multiple commits in the local development branch, in order to ensure that the RT-Thread repository commit is clean, please tidy up the local commits. More than five commits are not accepted by Pull Request.。

Push to Your Remote Repository

Push the modified content to the branch of your remote repository. It is recommended that the branch name of the remote repository be consistent with the local branch name.Use the following command to push:

git push origin YourBranchName

Create a Pull Request

Enter the RT-Thread repository under your Github account and click New pull request -> Create pull request. Make sure you choose the right branch.

Create a Pull Request

Step 1: Fill in the title of this Pull Request

Step 2: Modify the description information of this Pull Request (modify it in Write and preview it with Preview):

  • Modify PR Description: Replace the content in the red box below with the description of this pull request according to the requirements in the red box below.

  • Check PR Options: Fill in [x] in the OK Options check box to confirm. Note that there are no spaces on both sides of [x].

Modify PR Description and Check PR Options

Step 3:Create pull request.

Sign CLA

The first contribution to RT-Thread requires signing the Contributor License Agreement.

Sign CLA

Make sure that CLA shows successful signing and CI compilation, as shown in the following figure:

CLA successful

Note: Do not submit commmit using a non-GitHub account, or commit using a different account, which can lead to CLA signing failure.

Review Pull Request

Once the request is successful, the RT-Thread maintainer can see the code you submitted. The code will be reviewed and comments will be filled in on GitHub. Please check the PR status in time and update the code according to the comments.

Merge Pull Request

If the Pull Request code is okay, the code will be merged into the RT-Thread repository. This time Pull Request succeeded.

So far, we have completed a code contribution process.

Keep in Sync with RT-Thread Repository

The content of the RT-Thread GitHub repository is always updated. To develop based on the latest RT-Thread code, you need to update the local repository.

After clone, the local master branch content is consistent with the master branch content of the RT-Thread repository. But when the RT-Thread repository is updated, your local code is different from the RT-Thread code.

The local master is synchronized with the RT-Thread repository of your own GitHub account. If there is no content modification for the master branch (please create a new branch for development), then you can keep the local code synchronized with the RT-Thread repository according to the following steps:

  • To view the existing remote repository, there is usually only one default origin, which is your own remote repository:
$ git remote -v
origin  https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch)
origin  https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)
  • Add the RT-Thread remote repository and name it rtt, or you can customize the name by yourself:
$ git remote add rtt https://github.com/RT-Thread/rt-thread.git
  • View all remote repositories tracked locally:
$ git remote -v
origin    https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch)
origin    https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)
rtt       https://github.com/RT-Thread/rt-thread.git (fetch)
rtt       https://github.com/RT-Thread/rt-thread.git (push)
  • Pull the code from the master branch of RT-Thread remote repository and merge it into the local master branch:
git pull rtt master