Ora mi chiedo cosa comporta questa implementazione?
mi rispondo: nulla perchè non possiamo cambiare F_CPU a run-time, stessa cosa per starter.
Che ne dici, mi sfugge qualcosa?
Ciao.
Non ti sfugge nulla, ti rispondo dicendoti solo che... ci sono già passato

L'altro giorno stavo studiando il codice del leOS per vedere se riuscivo ad ottimizzarlo un po' ed anch'io ho notato che invece delle direttive per il compilatore avevo usato semplicifi if..else per impostare il timer 2. Ho pensato quindi che forse, sostituendo le direttive (#if...#elif... ecc..) riuscivo a salvare qualche altro byte. Invece, con mia grande sorpresa, dopo il cambio ho potuto constatare che i byte del firmware erano sempre uguali, sia nel primo che nel secondo caso.
A questo punto mi è venuto da pensare che le ottimizzazioni introdotte in fase di compilazione tolgono dal codice tutte le parti non utilizzate. Quindi, un if su costanti viene probabilmente analizzato e le scelte non possibili (giustamente hai notato che F_CPU non può essere modificato) vengono scartate e non incluse.
Sicuramente in una versione futura adotterò le direttive perché mi pare più omogeneo col resto del codice, però è buffo "ammirare" questi comportanti del compilatore.
Si in effetti dovresti controllare il codice dei file .s e .i che sono prodotti dal compilatore se passi a questo
l'argomento -save-temps. Oppure andare a sbirciare il codice nella cartella /var/tmp/ecc....
Se il compilatore evita di creare la variabile prescaler e se trasforma le if in #if è un compilatore
intelligente e inoltre mi legge nel pensiero. Però non è del tutto senza senzo, cioè il compilatore sa che
F_CPU è una costante che non può cambiare e quindi seleziona il codice da compilare, come se operase
il preprocessore.
Altro suggerimento:
Di questa classe se ne dovrebbe creare solo una instanza, cioè all'interno del codice qualunque tentativo di
creare una seconda istanza dobvrebbe avere come risultato il ritorno della precedente instanza.
In questo caso si usa il pattern singleton, che vede il costruttore privato ed il metodo publico leOS *instance(), che ritorna sempre la stessa istanza di classe.
Ho modicato il codice ma non l'ho potuto provare. Ho usato l'operatore "new" non so se funziona.
Se funziona in ogni posto in ogni modulo puoi chiamare leOS *sys_leOS = leOS::instance(); è questo ti ritorna sempre lo stesso puntatore. In questo caso devi sostituire "." con "->".
Pezzi di codice modifcati:
// file leOS.h
class leOS {
public:
//public methods
static leOS *instance() { // get singleton instance
if (!m_instance) {
m_instance = new leOS; // operator "new" should work
// m_instance->setTimer(); // Fix me
}
return m_instance;
//leOS(); now this is private ctor
void begin(void);
void (*voidFuncPtr)(void);
uint8_t addTask(void (*)(void), unsigned long, uint8_t oneTimeTask=NULL);
uint8_t removeTask(void (*)(void));
uint8_t pauseTask(void (*)(void));
uint8_t restartTask(void (*)(void));
uint8_t modifyTask(void (*)(void), unsigned long, uint8_t oneTimeTask=NULL);
private:
//private methods
leOS(); // private ctor
void setTimer();
uint8_t setTask(void (*)(void), uint8_t, unsigned long taskInterval=NULL);
static leOS *m_instance;
};
// file leOS.cpp
leOS *leOS::m_instance = 0;
//class constructor
leOS::leOS(void) {
_initialized = 0;
}
Ciao.