In addition to the naming and positioning of headers and source files
(see directory structure), Tollos headers and code follow the conventions
Header files are not considered doumentation, although they do often
have useful constants. These constants should be documented in the
C source file to which they apply.
Each Tollos header file typically includes two sets of function signatures:
- those which form the application interface and which are implemented
in the .c file of the same name as the .h header file
- those which are deemed I/O functions – these are ‘glue’ functions
called by Tollos code to provide the interface between the generic
Tollos code and some peripheral or microcontroller hardware. The
names of these functions always end in ‘IO’, and the symbol TOLLOS_IO
must be defined before the header file is included in order to use
I/O functions are implemented in a different library associated with
a device or microcontroller; that library is selected at link time
so that application code can be used with multiple hardware options.
In general, I/O functions are considered a private internal Tollos
interface and are subject to change, whereas the intent is to keep
application interface functions stable.
Widely-used Tollos types include
- byte – an unsigned byte, not usually treated as a number
- flag – a byte which must be either 0 or 1
- int – asserted to be 32 bits
- uint – an unsigned 32 bits.
See tollos.h for more types and other details.
C source files
C source files (‘modules’) comprise functions and documentation,
following the rules listed below. The Tollos module documentation
is generated automatically from the block comments, via a MemoWiki.
- Block comments (/*...*/ starting in column 1) are considered
‘contractual’ – they define the behaviour of the module and its
functions and form its documentation. All other comments (indented
block comments or // line comments) are informational.
- The module starts with a block comment, divided into three sections
(by lines containing hyphens):
- the name of the module (file) and a one-line description
- the licence which applies to the module
- an overview of the module, which may contain general rules applying
to some or all of the functions below.
- Functions are in alphabetical order.
- All functions are preceded by a block comment that includes:
- the function name and one-line description
- (indented) the parameters (if any) and a brief description of
- (indented) the possible return values (unless the return type
- any additional information needed to complete the description
of the function and its semantics.
- Functions that are neither static nor utility functions (in
tollosUtil) are considered part of a Tollos application or I/O
interface and their names start with a (lowercase) prefix associated
with the module; the remainder of the name is ‘camel case’, starting
with a capital (with the exception of string formatting functions
such as drawf).
- Function return types are always either void or int (this
allows them to be used automatically in a scripting or shell environment).
- Functions always end with a right brace on a line by itself, followed
by a line comment with the name of the function.
- The indention style is such that each use of braces is indented
two spaces, with the first brace usually moved to the end of the
line above to reduce vertical white space. Braces at the end of
loops or large segments of code generally are commented to indicate
the start of the loop or segment.
- Only top-controlled loops (for and occasionally while)
are used. break and continue are used where useful to reduce
nesting, as may be early return statements. The goto statement
is not used.
- All variables (except function parameters and constants) are local;
static variables outside of functions must be declared as static
(that is, they are not accessible or alterable by other modules except
through a formal function interface) or const (read-only). Each
module is responsible for protecting against race conditions on access
to its static data (for example, if there is an interrupt handler
in the module which could be invoked while another function in the
module is changing or reading static data).
- Variable names are lower case, except that shared static variables
are highlighted by the use of a common prefix and camel case.
- Declarations are always at the start of compound statements (i.e.,
they always follow a left brace).
- Tollos modules are compiled with heavy checking; in particular
the following GCC flags are used: