Skip to main content.

U-Boot Coding Style

The following Coding Style requirements shall be mandatory for all code contributed to the U-Boot project.

Exceptions are only allowed if code from other projects is integrated with no or only minimal changes.

The following rules apply:

Submissions of new code or patches that do not conform to these requirements shall be rejected with a request to reformat the changes.

U-Boot Code Documentation

U-Boot adopted the kernel-doc annotation style, this is the only exception from multi-line comment rule of Coding Style. While not mandatory, adding documentation is strongly advised. The Linux kernel kernel-doc document applies with no changes.

Use structures for I/O access

U-Boot typically uses a C structure to map out the registers in an I/O region, rather than offsets. The reasons for this are:

Some reasons why you might not use C structures:

Please use check_member() to verify that your structure is the expected size, or that particular members appear at the right offset.

Include files

You should follow this ordering in U-Boot:

   <common.h>
   <others.h>
   <asm/...>
   <arch/arm/...>
   <linux/...>
   "local.h"

Within that order, sort your includes.

It is important to include common.h first since it provides basic features used by most files, e.g. CONFIG options.

For files that need to be compiled for the host (e.g. tools), you need to use '#ifndef USE_HOSTCC' to avoid including common.h since it includes a lot of internal U-Boot things. See common/image.c for an example.

If your file uses driver model, include in the C file. Do not include dm.h in a header file. Try to use forward declarations (e.g. 'struct udevice') instead.

Filenames

For .c and .h files try to use underscore rather than hyphen unless you want the file to stand out (e.g. driver-model uclasses should be named xxx-uclass.h. Avoid upper case and keep the names fairly short.

Function and struct comments

Non-trivial functions should have a comment which describes what they do. If it is an exported function, put the comment in the header file so the API is in one place. If it is a static function, put it in the C file.

If the function returns errors, mention that and list the different errors that are returned. If it is merely passing errors back from a function it calls, then you can skip that.

See here for style:

https://www.kernel.org/doc/html/v4.10/doc-guide/kernel-doc.html#function-documentation

Driver model

When declaring a device, try to use 'struct udevice *dev', i.e. 'dev' as the name.

   struct udevice *dev;

Use 'ret' as the return value:

struct udevice *dev;
int ret;

ret = uclass_first_device_err(UCLASS_ACPI_PMC, &dev);
if (ret)
        return log_msg_ret("pmc", dev);

Consider using log_reg() or log_msg_ret() to return a value (see above)

Add a 'p' suffix on return arguments:

int dm_pci_find_class(uint find_class, int index, struct udevice **devp)
{
...
        *devp = dev;

        return 0;
}

There are standard variable names that you should use in drivers:

struct simple_bus_plat {
   u32 base;
   u32 size;
   u32 target;
};

/* Davinci MMC board definitions */
struct davinci_mmc_priv {
   struct davinci_mmc_regs *reg_base;   /* Register base address */
   uint input_clk;      /* Input clock to MMC controller */
   struct gpio_desc cd_gpio;       /* Card Detect GPIO */
   struct gpio_desc wp_gpio;       /* Write Protect GPIO */
};

   struct rcar_gpio_priv *priv = dev_get_priv(dev);

   struct pl01x_serial_platdata *plat = dev_get_platdata(dev);

Other

Some minor things:

struct udevice *pci_get_controller(struct udevice *dev)
{
   while (device_is_on_pci_bus(dev))
      dev = dev->parent;

   return dev;
}

Tests

Please add tests when you add code. Please change or expand tests when you change code.

Run the tests with:

   make check
   make qcheck   (skips some tests)

Python tests are in test/py/tests - see the docs in test/py for info.

Try to write your tests in C if you can. For example, tests to check a command will be much faster (10-100x or more) if they can directly call run_command() and ut_check_console_line() instead of using Python to send commands over a pipe to U-Boot.

Tests run all supported CI systems (gitlab, travis, azure) using scripts in the root of the U-Boot tree.