- Muchas notas - Fran Acién

20240422 - CPP + FreeRTOS programming advices

Example:

Free RTOS project structure

main.cpp

#include "sensors.h"

int main() {
    sensors_init();
    // Other main functionality
    vTaskStartScheduler(); // Start FreeRTOS scheduler
    return 0;
}
#include "sensors.h"

int main() {
    sensors_init();
    // Other main functionality
    vTaskStartScheduler(); // Start FreeRTOS scheduler
    return 0;
}

sensor.h

#ifndef SENSORS_H
#define SENSORS_H

void sensors_init();

#endif // SENSORS_H

sensors.c

#include "sensors.h"
#include "FreeRTOS.h"
#include "task.h"

// Task function for sensor task
void sensor_task(void *pvParameters) {
    // Sensor task implementation
    while(1) {
        // Read sensor data and process
        vTaskDelay(pdMS_TO_TICKS(1000)); // Delay for 1 second
    }
}

// Function to initialize sensors
void sensors_init() {
    // Create sensor task
    xTaskCreate(sensor_task, "SensorTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
    // Create other resources like queues, timers, etc. if needed
}

Programming phylosofy

A FreeRTOS project must follow the next rules:

  • Each peripheral will have his own source and header file. In this library it will be define the methods to control the device, and the parameters to configure the hardware. The parameters like GPIO, registers, etc, are in the source file of the library.

  • To init the hardware is done in a separate state, that is state_init

  • All the objects should be defined as static objects in the main.src, and then crossed with the different classes. This is a problem with FSM becuase it is not OOP, needs to be improved.

  • Use the next implementation as the structure of the project 20240426 - FSM implementation with FreeRTOS

  • Create a FSM structure for the project, where the init state is to initialize the hardware

  • Each state of the system is going to react different to the events. Some information here 20240312 - FSM on Fauna and FreeRTOS.

Naming convention

C++ and C

  • It is possible, to convine C++ and C depending on the scenario. The only limitation is that they follow different naming convention, and different structure.
  • C++ is object oriented that uses classes
  • C don’t

If is C code then put this at the beginning and at the end:

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

// Code

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

But take into account that is easy to call C code from C++.… but it is not wasy to call C++ code from C.

Common guidelines

  • define and conts are in CAPITAL: RTD_PIN_0, RTD_PIN_1

  • structures are in minus: struct fsm

  • Follow this comments to generate the documentation with doxygen

  • PascalCase for class names: If your file contains class declarations or definitions, use PascalCase for the file name, which means capitalizing the first letter of each word in the name. For example, MyClass.h or DataProcessor.cpp.

  • Use lowercase for non-class files: For files that don’t contain class declarations or definitions, use lowercase letters and separate words with underscores (_). For example, file_reader.h or data_processing_utils.cpp.

  • Define you objects in the main.src as static. Like all the peripherals. And then set them as pointers to the classes you want to use.

  • Follow the next text 20240506 - FreeRTOS and OOP in CPP

C Code

  • variables are minus, with underscore as word separators
  • FreeRTOS tasks finish with _task_f
  • Private functions and variables start with _
  • All functions that are part of the public API should start with gmx_. Preferably, other functions should as well. Some parts of the code use a _gmx_ prefix for internal functions.

C++ Code

  • Use CamelCase for all names
  • Types (such as classes, structs, and typedefs) stars with a capital letter, other names (functions, variables) with a lowercase letter
  • Member variables are named with a trailing underscore
  • Global variables are named with a g_ prefix.
  • Static class variables are named with a s_ prefix.
  • Classes starts with Capital letter
  • Function and variables starts with lowercase letter
  • Structs follow

Some questions I still have in mind

  • How do you cross reference the objects?
  • Files in caps or minus?
  • When create a class and when create a function?
  • Where should be initialize the objects? Dinamycally in the FSM machine? Somewhere else?