The demand for embedded development programming is ever-changing. To achieve system stability and code reusability, one must aim for high cohesion and low coupling. It is generally believed that time-consuming operations cannot be executed during 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 might define some global variables as flags, continuously checking these flags in the main loop and modifying them in the interrupt, ultimately executing specific logic in the main loop. However, this undoubtedly increases coupling and 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 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 invoked from other places, such as interrupts or module logic, detaching them from the calling context and running them in the main loop. Cpost also supports delayed processing, allowing you to specify how long after being invoked the function should execute.
Usage Method
Using Cpost is quite simple. Here, we take the example of using it in an embedded system without an operating system, mainly for interrupt delay handling.
1 Configure System Tick
Configure the macro CPOST_GET_TICK() in cpost.h to obtain 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 Post Task
Call the Cpost interface in places that require context switching, such as interrupts, to run it in the main loop.
cpost(intHandler);
Principle Analysis
The principle of Cpost is 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 stored in this array. The cpostProcess function running in the main loop traverses this array and executes the corresponding function when conditions are met, 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 eliminates the cost of maintaining flags and does not require the functions to be executed to be coupled with the main loop, making it simpler and easier to use.
NevermindZZT
https://blog.csdn.net/qq_34245464/article/details/111804661