Exporting Functions in PSLab Firmware

Computer programs consist of several hundreds line of code. Smaller programs contain around few hundreds while larger programs like PSLab firmware contains lines of code expanding over 2000 lines. The major drawback with a code with lots of lines is the difficulty to debug and hardship for a new developer to understand the code. As a solution modularization techniques can be used to have the long code broken down to small set of codes. In C programming this can be achieved using different .c files and relevant .h(header) files.

The task is tricky as the main code contains a lot of interrelated functions and variables. Lots of errors were encountered when the large code in pslab-firmware being modularized into application specific files. In a scenario like this, global variables or static variables were a much of a help.

Global Variables in C

A global variable in C is a variable whose scope spans wide across the entire program. Updation to the variable will be reflected everywhere it is used.

extern TYPE VARIABLE = VALUE;

Static Variables in C

This type of variables preserve their content regardless of the scope they are in.

static TYPE VARIABLE = VALUE;

Both the variables preserve their values but the memory usage is different depending on the implementation. This can be explained using a simple example.

Suppose a variable is required in different C files and it is defined in one of the header files as a local variable. The header file is then added to several other c files. When the program is compiled the compiler will create several copies of the same variable which will throw a compilation error as variable is already declared. In PSLab firmware, a variable or a method from one library has a higher probability of it being used in another one or many libraries.

This issue can be addressed in two different ways. They are by using static variables or global variables. Depending on the selection, the implementation is different.

The first implementation is using static variables. This type of variables at the time of compilation, create different copies of himself in different c files. Due to the fact that C language treats every C file as a separate program, if we include a header file with static variables in two c files, it will create two copies of the same variable. This will avoid the error messages with variables redeclared. Even though this fixes the issue in firmware, the memory allocation will be of a wastage. This is the first implementation used in PSLab firmware. The memory usage was very high due to duplicate variables taking much memory than they should take. This lead to the second implementation.

first_header.h

#ifndef FIRST_HEADER_H 
#define FIRST_HEADER_H 

static int var_1;

#endif 

/* FIRST_HEADER_H */

second_header.h

#ifndef SECOND_HEADER_H
#define SECOND_HEADER_H

static int var_1;

#endif    

/* SECOND_HEADER_H */

first_header.c

#include <stdio.h>
#include "first_header.h"
#include "second_header.h"

int main() {
    var_1 = 10;
    printf("%d", var_1);
}

The next implementation uses global variables. This type of variables need to be declared only in one header file and can be reused by declaring the header file in other c files. The global variables must be declared in a header file with the keyword extern and defined in the relevant c file once. Then it will be available throughout the application and no errors of variable redeclaration will occur while compiling. This became the final implementation for the PSLab-firmware to fix the compilation issues modularizing application specific C and header files.

Resources: