Skip to content

Instantly share code, notes, and snippets.

@peisenhower
Last active July 30, 2018 18:31
Show Gist options
  • Save peisenhower/32d4e25094e9e879d1cc to your computer and use it in GitHub Desktop.
Save peisenhower/32d4e25094e9e879d1cc to your computer and use it in GitHub Desktop.
My personal short coding standard for embedded c code

Coding Standard

General

  • lower underscore function names

    • void my_function_name(void)
  • Lower camel case variables

    • int myVariable = 10
  • Lower case underscore structs and enums custom types ending in _t

        typedef struct {
            int length;
            char* name;
        } my_struct_t;
  • Name macros and defines with all caps and underscores

    • #define MY_MACRO(x) ((x) + 1)
    • #define MY_DEFINE (10)
  • Surround defines with parens

    • #define MY_DEFINE (10)
  • Use of global variables should be reduced to minimum

    • Use accessors where global values are needed
  • Number with specific importance should be abstracted to named defines for clarity (no magic numbers)

  • Make as much as you can static, use a prefix of g for static variables

    • static int gMyStatic = 10
    • group common static values into a struct for easier debugging
  • Use standard int types when ever size is important, never imply a size

    • uint32_t | uint16_t | uint8_t ...
  • Use do while for multi-line macros

  • Name so that the begining of the name stays consistent

        /* WRONG */
        void tx_send(void);
        void rx_send(void);
    
        /* CORRECT */
        void send_tx(void);
        void send_rx(void);
  • Breakdown code into common logical files

    • if file breaks ~1k lines it should probably be refactored to more than one file
  • File names are lower case dashed

    • super-awesome-file.c
  • Use header and source templates

Types and Defines

  • All numbers with specific imporatance (magic numbers) should be defines

  • Defines use all caps and underscores

        #define THIS_IS_A_DEFINE  (12312)
  • typedef and enums are all lowercase with underscores and _t at the end

  • All enum values are all caps with underscores like defines

  • Explicitly define enum values for an externally used enums

        typedef enum
        {
            FOO_FIRST     = 1,
            FOO_SECOND    = 2,
            FOO_THIRD     = 3,
        } foot_enum_t;

Functions

  • Use common naming for externed functions of the same file
    /* in timer.c */
    void timer_start(void) ...
    void timer_stop(void) ...
  • Static functions should use the most descriptive name
    • Does not need to be prefixed with file name
  • Return as soon as possible
  • Do not use a space between function and parens
    • void my_function(void)
  • Function should always return a status code if there is a failure mode
  • Always use common error code enums over integers
  • Function parameters should use enums over booleans for readability with complete functions
    void timer_create(uint32_t period, enable_t enable);
    ...
    timer_create(1000, ENABLED);
  • Bracket starts on the next line after declaration

    /* BAD */
    int badFunction (bool shouldDo, int *pointer) {
        if (!shouldDo)
            return 0
    
        *pointer = value;
        return -1;
    }
    
    /* Good */
    int myFunction(do_t do, uint8_t *pointer)
    {
        if (pointer == NULL)
        {
            return ERR_PARAM;
        }
    
        if (do == DO_NOTHING)
        {
            return ERR_NONE;
        }
    
        *pointer = 0x123123;
        return ERR_NONE;
    }

Conditionals

  • Opening bracket at the start of the next line

  • Avoid !, use == false to be more explicit

  • Favor positive logic

  • Avoid double negatives

    • /* bad */ if (UNSECCESSFULL != true)...
  • if else statements must always have braces

  • Never use GOTO

  • Always use default in switch statements

  • Only use brackets in case statement if variables are introduced

  • Always comment fall through case statements

    if (something == true)
    {
        foo++;
        bar--;
    }
    if (another == false)
    {
        return ERR_PARAM;
    }
    
    switch (x)
    {
        case 1:
            puts("one was hit");
            break;
    
        case 2:
            puts("two was hit");
            /* intentional fall through */
    
        case 3:
            puts("two or three was hit");
            break;
    
        default:
            puts("default");
    }

Loops

  • Use c99 style definitions for loop variables
    for (int i = 0; i < 10 ; 1++)
    {
        prints("%02d-", i);
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment