Linux Desktop Inside of a browser? Yes with Webtops.
- Информация о материале
- Автор: Super User
- Родительская категория: Заметки
- Категория: Компьютерная повседневность
- Просмотров: 752
EasyEDA: How to resolve the "Component properties does not match the supplier part" error?
- Информация о материале
- Автор: Super User
- Родительская категория: Заметки
- Категория: Электроника / cхемотехника
- Просмотров: 752
Free online Linux emulators
- Информация о материале
- Автор: Super User
- Родительская категория: Заметки
- Категория: Компьютерная повседневность
- Просмотров: 642
Godbolt - online C compiler and preprocessor
- Информация о материале
- Автор: Super User
- Родительская категория: Заметки
- Категория: Программирование микроконтроллеров
- Просмотров: 658
Understanding Function Queues in C
- Информация о материале
- Автор: Super User
- Родительская категория: Заметки
- Категория: Программирование микроконтроллеров
- Просмотров: 610
Understanding Function Queues in C
Function queues are a powerful programming construct, particularly useful in embedded systems and real-time applications. This article explains a set of macros implemented in C to handle various types of function queues, including standard queues, delayed queues, and parameterized queues.
1. Standard Function Queue
The fQ macro defines a basic circular queue to store and execute function pointers. It includes:
- q##_last and q##_first for managing queue indices.
- q##_Queue, an array of function pointers.
- q##_Push, which adds a function pointer to the queue.
- q##_Pull, which retrieves and executes a function from the queue.
#define fQ(q, Q_SIZE) \
volatile int q##_last = 0; \
int q##_first = 0; \
void (*q##_Queue[Q_SIZE])(void); \
int q##_Push(void (*pointerQ)(void)) { \
if ((q##_last + 1) % Q_SIZE == q##_first)\
return 1; /* Queue is full */ \
q##_Queue[q##_last++] = pointerQ; \
q##_last %= Q_SIZE; \
return 0; /* Success */ \
} \
int (*q##_Pull(void))(void) { \
if (q##_last == q##_first) \
return 1; /* Queue is empty */ \
q##_Queue[q##_first++](); \
q##_first %= Q_SIZE; \
return 0; /* Success */ \
}
2. Delayed Function Queue
The del_fQ macro extends the standard queue to support delayed execution:
- q##_del_fQueue stores delayed function pointers.
- q##_execTime and q##_time track execution times.
- q##_Push_delayed schedules a function for future execution.
- q##_Tick processes delayed functions when their time arrives.
- q##_Revoke cancels a scheduled function.
#define del_fQ(q, Q_SIZE) \
int q##_time = 0; \
void (*q##_del_fQueue[Q_SIZE])(void); \
int q##_execArr[Q_SIZE] = { 0 }; \
int q##_execTime[Q_SIZE]; \
fQ(q, Q_SIZE) \
int q##_Push_delayed(void (*pointerF)(void), int delayTime){ \
int q##_fullQ = 1; \
for (int i = 0; i < Q_SIZE; i++) { \
if (!q##_execArr[i]) { \
q##_del_fQueue[i] = pointerF; \
q##_execArr[i] = 1; \
q##_execTime[i] = q##_time + delayTime; \
q##_fullQ = 0; \
break; \
} \
} \
return q##_fullQ; \
} \
void q##_Tick(void){ \
for (int i = 0; i < Q_SIZE; i++) { \
if (q##_execTime[i] == q##_time) { \
if (q##_execArr[i]) { \
q##_Push(q##_del_fQueue[i]); \
q##_execArr[i] = 0; \
} \
} \
} \
q##_time++; /* Increment time */ \
} \
int q##_Revoke(void (*pointerF)(void)){ \
int result = 1; \
for (int i = 0; i < Q_SIZE; i++) { \
if (q##_del_fQueue[i] == pointerF) { \
q##_execArr[i] = 0; \
result = 0; \
} \
} \
return result; \
}
3. Parameterized Function Queue
The fQP macro allows parameterized function execution:
- q##_funcs stores function pointers.
- q##_params stores associated parameters.
- q##_Push and q##_Pull handle adding and executing functions with parameters.
#define fQP(q, Q_SIZE, param_type) \
void (*q##_funcs[Q_SIZE])(param_type); \
param_type q##_params[Q_SIZE]; \
volatile int q##_last = 0; \
int q##_first = 0; \
int q##_Push(void (*func)(param_type), param_type params) { \
if ((q##_last + 1) % Q_SIZE == q##_first) \
return 1; /* Queue is full */ \
q##_funcs[q##_last] = func; \
q##_params[q##_last++] = params; \
q##_last %= Q_SIZE; \
return 0; /* Success */ \
} \
int q##_Pull(void) { \
if (q##_last == q##_first) \
return 1; /* Queue is empty */ \
q##_funcs[q##_first](q##_params[q##_first++]); \
q##_first %= Q_SIZE; \
return 0; /* Success */ \
}
Key Features
These macros provide:
- Circular Buffers: Efficient storage and retrieval with wrap-around indices.
- Delayed Execution: Schedule functions to execute after a delay.
- Parameterized Queues: Pass parameters to queued functions.
Use Cases
Function queues are particularly useful in:
- Task scheduling in embedded systems or real-time applications.
- Managing callbacks or event-driven programming workflows.
- Efficient queuing and delayed execution in constrained environments.
find more here:
Conclusion
The macros presented here demonstrate a flexible and efficient way to manage function queues in C. By integrating these techniques into your projects, you can streamline task scheduling, improve resource management, and enhance the overall functionality of your software.
Страница 13 из 196
