mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-03 20:07:51 +00:00
Re-addig coding style guide for OCWare
This commit is contained in:
369
firmware/ec/coding_style_guide
Normal file
369
firmware/ec/coding_style_guide
Normal file
@@ -0,0 +1,369 @@
|
||||
|
||||
OpenCellular Coding Style
|
||||
=========================
|
||||
|
||||
We follow Linux Kernel coding style with following exceptions.
|
||||
|
||||
Exceptions:
|
||||
----------
|
||||
|
||||
o 4-space indentation
|
||||
o Typedef enums and structs
|
||||
o indent case labels
|
||||
switch (suffix) {
|
||||
case 'G':
|
||||
case 'g':
|
||||
mem <<= 30;
|
||||
break;
|
||||
case 'M':
|
||||
case 'm':
|
||||
mem <<= 20;
|
||||
break;
|
||||
case 'K':
|
||||
case 'k':
|
||||
mem <<= 10;
|
||||
/* fall through */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Additions:
|
||||
---------
|
||||
|
||||
o Non-public functions (functions not exported in header for use by other
|
||||
modules) should be static
|
||||
o Unless absolutely necessary, global variables within a module should be static
|
||||
o Avoid using forward declarations, just #include headers when possible
|
||||
o Static variables of the form s_variableName
|
||||
o Non-static functions of the form ModuleName_functionName()
|
||||
o File names
|
||||
o C and header files in same directory
|
||||
o ModuleName.c/h
|
||||
o All directory names should be lowercase, with underscores added as
|
||||
needed to improve readability (e.g. my_complex_directory/Foo.h)
|
||||
o Hex values are upper-case: 0xFB
|
||||
o Unless size doesn't matter, use fixed-width types defined in <stdint.h>
|
||||
(uint32_t, int8_t, etc.)
|
||||
o Enums
|
||||
o ALL_CAPS, start with enum name (within reason) for namespacing/readability
|
||||
typedef enum SbdFlowControl {
|
||||
SBD_FLOW_CONTROL_DISABLED = 0,
|
||||
SBD_FLOW_CONTROL_HW = 3,
|
||||
SBD_FLOW_CONTROL_SW = 4,
|
||||
SBD_FLOW_CONTROL_ALL = 6
|
||||
} SbdFlowControl;
|
||||
typedef enum AtLineType {
|
||||
AT_LINE_TYPE_RESPONSE = 0,
|
||||
AT_LINE_TYPE_CMD_ECHO,
|
||||
|
||||
COUNT_AT_LINE_TYPE
|
||||
} AtLineType;
|
||||
|
||||
o #includes should be in alphabetical order & logically separated:
|
||||
/* Module header[s] */
|
||||
…
|
||||
/* stdlib headers */
|
||||
…
|
||||
/* TI includes */
|
||||
…
|
||||
/* OC includes */
|
||||
o Wrap functions like this:
|
||||
ReturnType ReallyLongFunctionName(Type par_name1, Type par_name2,
|
||||
Type par_name3)
|
||||
{
|
||||
DoSomething();
|
||||
...
|
||||
}
|
||||
|
||||
ReturnType ReallyReallyReallyLongFunctionNameThatJustWillNotFit(
|
||||
Type par_name1, /* double indent */
|
||||
Type par_name2,
|
||||
Type par_name3)
|
||||
{
|
||||
DoSomething(); /* regular indent */
|
||||
...
|
||||
}
|
||||
|
||||
o No spaces after end of line
|
||||
o No blank lines at the end of file
|
||||
o Each file should have description of what it does, which function it contains
|
||||
etc.
|
||||
o Each function should describe what operation it execute on the parameters and
|
||||
what it returns. If there are any parameter overloaded, specify it clearly.
|
||||
o No dead code.
|
||||
o Function shouldn't be more than one page.
|
||||
o Central exiting of function
|
||||
o Use /* */ for comments. Multiple lines:
|
||||
/*
|
||||
*
|
||||
*/
|
||||
o MACROS are NOT to define functions. MACROS shouldn't effect control or effect
|
||||
registers or changes the system states.
|
||||
|
||||
|
||||
Sample Code:
|
||||
-----------
|
||||
|
||||
ExampleModule.h
|
||||
/*
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* See Canonical Style Documents at:
|
||||
*
|
||||
* TODO: reference style document
|
||||
*
|
||||
* Example header that demonstrates our current C style. The goal of this
|
||||
* code, while nonsensical, is to show a visual example of as many of our
|
||||
* style rules/guidelines as possible.
|
||||
*
|
||||
* Note the #include order: stdlib includes, TI includes, then OpenCellular
|
||||
* includes in quotes (""). Each group should be in alphabetical order.
|
||||
* Additionally, we only want to include the headers necessary for the
|
||||
* interfaces/structs/enums in the header, everything else should be in the
|
||||
* source file
|
||||
*/
|
||||
|
||||
/* TODO: what do we want to do for #include guards? #pragma once doesn't have
|
||||
* namespacing issues and is generally faster, but not guaranteed to be portable
|
||||
*/
|
||||
#ifndef EXAMPLEMODULE_H_
|
||||
#define EXAMPLEMODULE_H_
|
||||
|
||||
/* stdlib includes */
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* OC includes */
|
||||
#include "some_project_folder/SomeDependency.h"
|
||||
|
||||
/*
|
||||
* Initializes the module and stuff
|
||||
*/
|
||||
void ExampleModule_init(void);
|
||||
|
||||
/*
|
||||
* Takes lots of arguments, but doesn't do much that's useful with them.
|
||||
*
|
||||
* @param count an integer input (by value)
|
||||
* @param value an enum input (by value)
|
||||
* @param name a string input (by const-ref)
|
||||
* @param outVal output integer arg (by pointer)
|
||||
*
|
||||
* @return true if function succeeds, false otherwise
|
||||
*/
|
||||
bool ExampleModule_funcWithManyArgs(int64_t count,
|
||||
EnumType value,
|
||||
const char *name,
|
||||
uint32_t *outVal);
|
||||
|
||||
|
||||
/*
|
||||
* Another useless function
|
||||
*
|
||||
* @param param1 first example integer (by value)
|
||||
* @param param2 second example integer (by value)
|
||||
* @param param3 third example integer (by const-ref)
|
||||
*/
|
||||
void ExampleModule_methodThatHasAReallyLongNameOhCrapImRunningOutOfSpace(
|
||||
int param1,
|
||||
bool param2,
|
||||
const uint32_t *param3);
|
||||
|
||||
#endif /* EXAMPLEMODULE_H_ */
|
||||
ExampleModule.c
|
||||
/*
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* See additional comments in: ExampleModule.h
|
||||
*
|
||||
* Note the #include order: First our related .h file, then the same
|
||||
* order as we'd do elsewhere (see ExampleModule.h).
|
||||
*
|
||||
* This file is formatted with clang-format -i
|
||||
*/
|
||||
|
||||
#include "ExampleModule.h"
|
||||
|
||||
/* stdlib includes */
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* TI includes */
|
||||
#include <driverlib/I2C.h>
|
||||
#include <driverlib/UART.h>
|
||||
|
||||
/* OC includes */
|
||||
#include "drivers/Power.h"
|
||||
#include "drivers/Rf.h"
|
||||
#include "helpers/Memory.h"
|
||||
#include "helpers/Array.h"
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
typedef enum SampleState {
|
||||
SAMPLE_STATE_INIT,
|
||||
SAMPLE_STATE_RUN,
|
||||
SAMPLE_STATE_IDK,
|
||||
|
||||
COUNT_SAMPLE_STATE
|
||||
} SampleState;
|
||||
|
||||
typedef struct UselessConfig {
|
||||
uint32_t someInt; /*!< Sample comment on member */
|
||||
int8_t otherValue; /*!< This looks important */
|
||||
SampleState state; /*!< All your base are belong to us */
|
||||
struct UselessConfig *next; /*!< Pointer to next item in list */
|
||||
} UselessConfig;
|
||||
|
||||
static SampleState s_myUselessConfig = {
|
||||
.someInt = 5,
|
||||
.state = SAMPLE_STATE_INIT
|
||||
};
|
||||
|
||||
static SampleState s_simpleInitSample = { .otherValue = 2 };
|
||||
|
||||
static uint32_t s_someStaticVariable;
|
||||
|
||||
/* Array Initializer List Example */
|
||||
static const uint32_t sampleTable[COUNT_SAMPLE_STATE] = {
|
||||
[SAMPLE_STATE_INIT] = 6,
|
||||
[SAMPLE_STATE_RUN] = 42,
|
||||
[SAMPLE_STATE_IDK ] = 0xFACEB00C
|
||||
};
|
||||
|
||||
static const uint8_t anotherArray[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
|
||||
0x07, 0x08, 0x09, 0x0A, 0x0B };
|
||||
|
||||
/* TODO: How do we want to comment on functions? Having a full header block
|
||||
* might be a bit overkill since we're planning on doing doxygen comments in
|
||||
* the header. Some sort of comment to make it easier to see the beginning of
|
||||
* new functions might be nice though. Not sure how we want to document static
|
||||
* functions either - probably don't need to be as strict as for public
|
||||
* functions
|
||||
*/
|
||||
void ExampleModule_init(void)
|
||||
{
|
||||
s_myUselessConfig.state = SAMPLE_STATE_RUN;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This additional comment is not in the javadoc style, as it's supposed to
|
||||
* describe more concrete implementation details. Any comments that may be
|
||||
* useful to the class API "customer" (as opposed to someone who might modify
|
||||
* this class) should instead be in JavaDoc style in ExampleCode.h.
|
||||
******************************************************************************/
|
||||
/* TODO: should this be MapLookup instead? */
|
||||
static uint32_t mapLookup(SampleState state, bool uselessParam)
|
||||
{
|
||||
if (state < COUNT_SAMPLE_STATE) {
|
||||
return sampleTable[state];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uin32_t ExampleModule_methodThatHasALongNameOhCrapImRunningOutOfSpace(
|
||||
int param1,
|
||||
bool param2,
|
||||
const uint32_t *param3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: not sure for sure how we want to do wrapping parameters. I'm on the
|
||||
* fence between this style (FB & Google) vs. what I wrote above in the document
|
||||
*/
|
||||
bool ExampleModule_funcWithManyArgs(int64_t count,
|
||||
EnumType value,
|
||||
const char *name,
|
||||
uint32_t *outVal)
|
||||
{
|
||||
/*
|
||||
* The body of this function is used to demonstrate common code constructs
|
||||
* so that the indentation, braces, and spacing styles for them are
|
||||
* immediately apparent.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This section demonstrates different kinds of if() blocks, including
|
||||
* long/short if() blocks, complicated if() expressions, and validity
|
||||
* checks on pointer/handle variables.
|
||||
*/
|
||||
if (count < 0) {
|
||||
++count;
|
||||
} else if (count == 0) {
|
||||
--count;
|
||||
} else {
|
||||
count *= 2;
|
||||
}
|
||||
|
||||
if (strlen(name) < 20 &&
|
||||
!strcmp(name, "some string that I made up") &&
|
||||
(count < 0 || count > 5)) {
|
||||
*outVal += count;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
count += strlen(name);
|
||||
}
|
||||
|
||||
int64_t *realPtr = NULL;
|
||||
if (!realPtr) {
|
||||
realPtr = malloc(sizeof(*realPtr));
|
||||
}
|
||||
|
||||
/* This section demonstrates looping constructs. */
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
*outVal *= 2;
|
||||
}
|
||||
|
||||
int i = 10;
|
||||
while (i > 0) {
|
||||
--i;
|
||||
}
|
||||
|
||||
do {
|
||||
++i;
|
||||
} while (i <= 10);
|
||||
|
||||
/*
|
||||
* This section demonstrates formatting for switch statments
|
||||
*/
|
||||
switch (s_myUselessConfig.state) {
|
||||
case SAMPLE_STATE_INIT:
|
||||
s_myUselessConfig.state = SAMPLE_STATE_RUN;
|
||||
break;
|
||||
case SAMPLE_STATE_RUN: {
|
||||
uint32_t i = s_someStaticVariable - 1;
|
||||
printf("Doing stuff %d", i);
|
||||
break;
|
||||
}
|
||||
case SAMPLE_STATE_IDK:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* This section demonstrates formatting for basic expressions, operators,
|
||||
* and initializations.
|
||||
*/
|
||||
char s[] = "startValue";
|
||||
size_t someSize = sizeof(*realPtr);
|
||||
int val = count / 2;
|
||||
count = (count + val) & ((val << 3) + count * val);
|
||||
uint32_t *samplePtr = &s_someStaticVariable;
|
||||
SampleState zeroInitializedStruct = {};
|
||||
|
||||
/* Multiple variables of same type */
|
||||
/* TODO: allow multiple vars on one line? eg. int var1, var2, var3 */
|
||||
int var1;
|
||||
int *var2;
|
||||
int *var3;
|
||||
|
||||
var1 = 2;
|
||||
var2 = &var1;
|
||||
var3 = var2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user