Embedded Programming: Fast Context Switching Based on cpost with Code Link at the End

The demands of embedded development programming are ever-changing. To achieve system stability and code reusability, high cohesion and low coupling must be maintained.It is generally believed that time-consuming operations cannot be executed within interrupts, as this would affect system stability.

For programs with an operating system, interrupt handling can be divided into two parts through the operating system’s scheduling, allowing time-consuming operations to be executed in a thread. However, how should this be handled in the absence of an operating system?

One possible approach is to define some global variables as flags, continuously checking these flags in the main loop, modifying them in the interrupt, and finally executing the specific logic in the main loop. However, this undoubtedly increases coupling and raises the maintenance cost of the program.

cpost

cpost is a simple yet very convenient tool designed for such situations. It allows for easy context switching, reducing module coupling. Click “Read the Original” at the end to access the cpost code repository.

cpost draws inspiration from the Android handler mechanism by running a task in the main loop and allowing functions to be thrown from other places, whether from interrupts or module logic, to execute in the main loop, thus decoupling from the calling context. cpost also supports delayed processing, allowing you to specify how long after being thrown a function should execute.

Usage

The usage of cpost is very simple. Here, we will take its application in an embedded system without an operating system as an example, mainly for interrupt delay processing.

1 Configure System Tick

Configure the macro CPOST_GET_TICK() in cpost.h to retrieve the system tick. For example, using the STM32 HAL library:

#define     CPOST_GET_TICK()            HAL_GetTick()

2 Configure Processing Process

Call the cpostProcess function in the main loop.

int main(void){    ...    while (1)    {        cpostProcess();    }    return 0;}

3 Throw Task

Call the cpost interface in places where context switching is needed, such as in interrupts, to run it in the main loop.

cpost(intHandler);

Principle Analysis

The principle of cpost is actually quite simple, and its code is very minimal, totaling only a few dozen lines. cpost maintains a global array.

CpostHandler cposhHandlers[CPOST_MAX_HANDLER_SIZE] = {0};

Each element of the array represents a function and its parameters that need to be executed. When the cpost interface is called, the posted function and parameters are saved in this array. The cpostProcess function running in the main loop traverses this array and executes the corresponding function when conditions are met, thus achieving context switching.

void cpostProcess(void){    for (size_t i = 0; i < CPOST_MAX_HANDLER_SIZE; i++)    {        if (cposhHandlers[i].handler)        {            if (cposhHandlers[i].time == 0 || CPOST_GET_TICK() >= cposhHandlers[i].time)            {                cposhHandlers[i].handler(cposhHandlers[i].param);                cposhHandlers[i].handler = NULL;            }        }    }}

In fact, the method of cpost is quite similar to the initial approach of using global flags for context switching. However, cpost simplifies the process by maintaining an array and directly posting functions, eliminating the cost of managing flags and avoiding coupling the functions to the main loop, making it simple and easy to use.

NevermindZZT

https://blog.csdn.net/qq_34245464/article/details/111804661

Leave a Comment