Questo repository contiene un framework modulare per la gestione dei task progettato per il microcontrollore RP2040. Il progetto include componenti fondamentali per la gestione dei task, algoritmi di scheduling e meccanismi di inizializzazione del sistema. Lo scheduler supporta molteplici algoritmi, offrendo flessibilità e adattabilità per una vasta gamma di applicazioni, con un approccio didattico mirato.
- Algoritmi di Scheduling Multipli:
- Basato su priorità (PRIORITY)
- Round-robin
- Earliest-deadline-first
- Least-executed
- Longest-waiting
- Normalizzazione delle Priorità Dinamiche per prevenire starvation dei task.
- Metriche Dettagliate sui Task:
- Tempo di esecuzione
- Jitter
- Utilizzo della memoria
- Interfaccia Terminale VT100 per l'interazione con l'utente.
- Design Modulare per facilitare l'estensione e la personalizzazione.
- Concetti di Classe e Oggetti adattati al linguaggio C tramite strutture e puntatori a funzione.
main.c
: Punto di ingresso del programma. Gestisce l'inizializzazione dell'hardware, della configurazione e dello scheduler.scheduler.h
/scheduler_core.c
: Logica principale dello scheduler, gestione dei task e implementazione degli algoritmi.terminal.h
/terminal.c
: Interfaccia utente tramite terminale VT100.initcalls.h
/initcalls.c
: Meccanismo modulare di inizializzazione per i componenti del sistema.config.h
/config.c
: Gestione dei parametri di configurazione e memorizzazione.hardware_cfg.h
/hardware.c
: Layer di astrazione hardware (HAL) per configurazioni specifiche della scheda.debug.h
/debug.c
: Strumenti di debug per il logging specifico dei task.flash.h
/flash.c
: Utilità per la gestione della memoria flash e la persistenza dei parametri.
Il progetto utilizza principi di design modulare per:
- Migliorare la manutenibilità e la riusabilità del codice.
- Permettere il testing indipendente dei componenti.
- Supportare configurazioni hardware multiple.
Le funzioni contrassegnate come static
sono utilizzate esclusivamente all'interno del file in cui sono definite. Questa scelta:
- Migliora l'incapsulamento.
- Previene accessi non intenzionali da altre parti del codice.
- Riduce le dipendenze e aumenta la modularità.
Il file hardware_cfg.h
definisce configurazioni hardware astratte, consentendo:
- La separazione tra logica applicativa e configurazione hardware.
- La facilità di passaggio tra versioni hardware diverse (es.
hardware_v1
,hardware_v2
).
Il progetto utilizza strutture e puntatori a funzione per emulare il comportamento di classi e oggetti in linguaggi orientati agli oggetti:
- Le strutture (es.
DriverLed
) contengono sia i dati che i puntatori alle funzioni operative. - Questo approccio favorisce la modularità e la leggibilità del codice, pur sfruttando la semplicità del linguaggio C.
- Scheduler e Task:
scheduler_core.c
gestisce l'esecuzione dei task, mentrescheduler.h
espone l'API per aggiungere e gestire i task.- La logica specifica dei task risiede in moduli dedicati come
task_led.c
otask_terminal.c
.
- Terminale e Comandi:
- Il sistema terminale consente la configurazione e il monitoraggio runtime tramite comandi.
- I comandi sono registrati in
cmd.c
e gestiti dinamicamente in base all'input dell'utente.
- Inizializzazione:
- Il meccanismo di
initcalls
assicura un'ordinata inizializzazione dei componenti.
- Il meccanismo di
- Aggiunta dei Task: I task vengono aggiunti allo scheduler con nome, funzione, priorità e intervallo.
- Selezione dell'Algoritmo: Lo scheduler utilizza uno degli algoritmi predefiniti per selezionare il prossimo task da eseguire.
- Esecuzione del Task: Il task selezionato viene eseguito, aggiornando le metriche (es. tempo di esecuzione, jitter).
- Normalizzazione delle Priorità: Per lo scheduling basato su priorità, le priorità dinamiche vengono resettate periodicamente.
- Clona il repository.
- Configura l'hardware in
hardware_cfg.h
. - Registra le funzioni di inizializzazione nei tuoi moduli usando
initcalls
. - Aggiungi i task allo scheduler in
main.c
.
- Usa un emulatore di terminale compatibile VT100 per connetterti al microcontrollore.
- Esempi di comandi:
HELP
: Mostra l'elenco dei comandi disponibili.TASK
: Gestisce i task (es. visualizza, pausa, riprendi).LOGIN <password>
: Autenticati per azioni privilegiate.REBOOT
: Riavvia il sistema.
Di seguito un esempio completo per configurare ed eseguire lo scheduler:
#include "scheduler.h"
#include "config.h"
void my_task(void) {
// Logica del task
printf("Esecuzione di my_task\n");
}
int main() {
stdio_init_all();
select_hardware_config();
initcalls();
init_params();
scheduler_add_task("MyTask", my_task, 1, 1000000, TASK_RUNNING, 0);
scheduler_run();
return 0;
}
- HAL (Hardware Abstraction Layer):
- Consente la separazione tra hardware specifico e logica applicativa, migliorando la portabilità.
- Design Modulare:
- Ogni modulo ha responsabilità ben definite e interfacce chiare, facilitando la collaborazione e il debugging.
- Uso di Strutture come Oggetti:
- Favorisce la leggibilità e facilita l'estensione del codice, senza la complessità di un linguaggio OOP.
- Meccanismi di Scheduling:
- Introduzione a diversi algoritmi con esempi pratici di utilizzo nei sistemi embedded.
- Aggiungere un Nuovo Algoritmo:
- Implementa la logica di selezione in
scheduler_core.c
. - Aggiungi la funzione all'array
sched_algorithms
.
- Implementa la logica di selezione in
- Creare un Nuovo Task:
- Definisci la logica del task in un nuovo file
.c
. - Registra il task usando
scheduler_add_task
.
- Definisci la logica del task in un nuovo file
- Migliorare il Terminale:
- Registra nuovi comandi in
cmd.c
con descrizioni e gestori dedicati.
- Registra nuovi comandi in
- Utilizza
debug.c
per abilitare il logging specifico dei task. - Analizza le metriche fornite da
scheduler_print_task_list
per identificare colli di bottiglia e ottimizzare l'uso delle risorse. - Salva e carica configurazioni usando
flash.c
per mantenere parametri tra i riavvii.
Le contribuzioni sono benvenute! Non ci sono regole, fate una pull request !
Questo progetto è rilasciato sotto la licenza GNU v3. Consulta LICENSE
per i dettagli.