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