Go Down

Topic: Ottimizziamo il codice del core di Arduino (Read 28342 times) previous topic - next topic

Maurotec

Dec 06, 2013, 10:12 am Last Edit: Dec 06, 2013, 11:59 am by MauroTec Reason: 1
In risposta a @gpb01 http://forum.arduino.cc/index.php?topic=186435.msg1496469#msg1496469
Si ci si è preoccupati per niente, anche se la 3.4.2 non si comportava bene come la 3.4.3. Guardiamo il lato positivo, abbiamo imparato qualcosa. Se vogliamo creare una nostra classe con metodi che prendono un puntatore in flash, nella lista dei parametri scriviamo:
Code: [Select]
myFnc(PGM_P ptrf);

Che però non ci permette di usare il polimorfismo di cui è capace il C++.
Risolviamo come nel core Arduino:

Code: [Select]

myFnc(const __FlashStringHelper *ifsh)
{
    PGM_P p =  (PGM_P)ifsh;
    ...
}


Tra l'altro __FlashStringHelper dovrebbe essere visibile negli sketch e quindi conviene usarla.
Se non è visibile allora si dovrà includere WString e se questo crea problemi dovrebbe anche bastare una semplice
class __FlashStringHelper; dopo gli include.

Io ci provo, arruolo lesto. Clona il repositor di arduino, sia in locale che in remoto, così noi possiamo vedere che lesto a un suo repo arduino su github, e poco per volta sistemi il core e tutto il quello che ti viene in mente.
Sai bene che di java io non ci capisco, mentre tu ci lavori tutti i giorni.

Ciao.

lestofante

io posso falro, ma non ho capito bene cosa dovrei cambiare nel java. Fate attenzione che ho già arduino clonato, ma una versione vecchissimissima.

Quello che dovremmo fare di sicuro è una serie di test per verificare che tutto funzioni con la nuova toolchain
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Maurotec

Intanto ripulire tutti i warning è cosa buona e giusta no.

Comparare un int e un unsigned int può portare facilmente a risultati inaspettati e allora perché non vedere di sistemare il core in modo che il compilatore non emetta warning.

Posso dirti con certezza che il mio codice viene compilato senza warning, sia lato PC che lato embedded, c'è anche il modo per evitare che gcc emetta unused warning, usando proprio l'attributo unused che al momento non ricodo come si fa.

Per le modifiche al IDE, nelle preferenze ci vorrebbero due line edit CXX_FLAGS e LFLAGS, così da poter modificare i flags di compilazione e linking. Potrebbero anche bastare alcune checkBox per limitare il numero di flags, una potrebbe essere quella che abilita i float nella printf. Poi se hai tempo e voglia, di modifiche profonde c'è n'è a iosa.

ciao.

lestofante

Quote
Intanto ripulire tutti i warning è cosa buona e giusta no.

Approvo, ma parliamo di modificare le lib, qui8ndi lato c++. Allora, tu hai modificato le lib per eliminare i warning?

io ad aggiungere una di textbox per passare degli argomenti al compilatore/linker/uploader credo di metterci un attimo.
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

gpb01

Mauro, Lesto ... molto interessanti le Vs. discussioni, ma questo thread è dedicato a "[MAC] Aggiornamento IDE 1.0x all'ultima versione Atmel Toolchain" ... quindi ...
... cortesemente aprite un altro thread dedicato a chi si vorrà dedicare alle modifiche del "core" (così questo resta dedicato al tuo titolo) e ... a convincere poi le alte sfere ad accettarle ed inserirle nelle distibuzioni.

@Leo : Poi ci pensi tu a spostare questi ultimi post di Mauro e Lesto nel giusto thread così il loro rimane un bel discorso pulito e logico ... e si riesce a seguirlo bene ?

Grazie ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

leo72

Ho messo la discussione in questo nuovo thread, mi pare appropriato come titolo.

Maurotec


Quote
Intanto ripulire tutti i warning è cosa buona e giusta no.

Approvo, ma parliamo di modificare le lib, qui8ndi lato c++. Allora, tu hai modificato le lib per eliminare i warning?

io ad aggiungere una di textbox per passare degli argomenti al compilatore/linker/uploader credo di metterci un attimo.


Lo so, lo so, potrei ripeterlo mille volte, ma non lo ricordereste comunque. Io non uso il core Arduino, non uso L'ide Arduino, ho le mie routine C, il mio IDE QtCreator, il mio flasher AvrDudeQui, con questi ho la massima flessibilità e con il mio codice gcc non emette warning e non ho disabilitato i warning. Questo vuol dire che durante lo sviluppo i warning ci sono, se stabilizzi un API devi provvedere a ripulire i warning, cosa che ho fatto nelle mie routine, quindi è fattibile ripulire il core come lo è stato per il mio codice.

Quote
io ad aggiungere una di textbox per passare degli argomenti al compilatore/linker/uploader credo di metterci un attimo.


Ok non correre, parliamone, dammi il tempo di visionare il codice java dove vengono lanciati i processi di build.
Comunque ci sono delle flags vitali per arduino e quindi non dovrebbe essere possibile modificarle o se si da la possibilità bisogna mettere un button che resetti le flags a quelle originali considerate vitali per arduino.

@gpb01
Hai ragione, ho fatto una escursione fuori pista.
@Grande leo, sei sempre più reattivo.

Ciao.

PaoloP

Consiglierei di revisionare il codice delle versioni 1.5.x e non quello delle 1.0.x in quanto prima o poi verrà abbandonato.
E' anche vero però che il codice della 1.0.5 è stabile mentre la 1.5.x (oggi arrivato alla 1.5.5) è in continua evoluzione.

nid69ita


Code: [Select]

myFnc(const __FlashStringHelper *ifsh)
{  PGM_P p =  (PGM_P)ifsh;
    ...
}

Tra l'altro __FlashStringHelper dovrebbe essere visibile negli sketch e quindi conviene usarla.
Se non è visibile allora si dovrà includere WString e se questo crea problemi dovrebbe anche bastare una semplice
class __FlashStringHelper; dopo gli include.


In questo thread:
http://forum.arduino.cc/index.php?topic=202262.msg1492087#msg1492087
un utente chiese come rendere la UTFT compatibile con F(); ho suggerito questo codice scopiazzando da print.cpp del core e mixando con la print della UTFT, non testato, ma scrissi correttamente?
my name is IGOR, not AIGOR

lestofante

Quote
dammi il tempo di visionare il codice java dove vengono lanciati i processi di build.


https://github.com/arduino/Arduino/blob/ide-1.5.x/app/src/processing/app/debug/Compiler.java
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Maurotec

@lesto
Code: [Select]
List baseCommandLinker = new ArrayList(Arrays.asList(new String[] {
      avrBasePath + "avr-gcc",
      "-Os",
      "-Wl,--gc-sections"+optRelax,
      "-mmcu=" + boardPreferences.get("build.mcu"),
      "-o",
      buildPath + File.separator + primaryClassName + ".elf"
    }));

    for (File file : objectFiles) {
      baseCommandLinker.add(file.getAbsolutePath());
    }

    baseCommandLinker.add(runtimeLibraryName);
    baseCommandLinker.add("-L" + buildPath);
    baseCommandLinker.add("-lm");


Questo dovrebbe essere il codice per il linker, dove si vede che alla fine viene aggiunto -lm per la libreria math che deve essere sempre presente. L'ideale sarebbe che il campo editabile permetta di fare questo:
-(Os) + (O2). Il significato è: rimuovo il flag Os e aggiungo O2, ma è troppo complicato, rendiamolo semplice.
Per cui una edit line con un buddy button così: Optimize flags: -Os    [reset default flags]
dove [text] è un pulsante, cliccandoci il campo edit viene impostato a 0s.

Il codice dovrebbe diventare così:
Code: [Select]
List baseCommandLinker = new ArrayList(Arrays.asList(new String[] {
      avrBasePath + "avr-gcc",
      optimizeFlags,    // oppure Preference.get("compiler.optFlags)
      "-Wl,--gc-sections"+optRelax,
      "-mmcu=" + boardPreferences.get("build.mcu"),
      "-o",
      buildPath + File.separator + primaryClassName + ".elf"
    }));

    for (File file : objectFiles) {
      baseCommandLinker.add(file.getAbsolutePath());
    }

    baseCommandLinker.add(runtimeLibraryName);
    baseCommandLinker.add("-L" + buildPath);
    baseCommandLinker.add("-lm");


A scelta se usare una line edit o più check box exclusive dove solo una check box può essere marcata.
Le ottimizzazione di gcc sono:
-O0, -O1, -O2, -O3, -Os.

@nid69ita
strlen non funziona, ma c'è una funzione specifica, ma non ricordo pgm_strlen o simile.
Che poi pgm_strlen conta i caratteri fino ad arrivare a NULL e quindi non è molto rapida come la strlen.

Ciao.


lestofante

#11
Dec 06, 2013, 01:29 pm Last Edit: Dec 06, 2013, 01:43 pm by lesto Reason: 1
io invece farei una textbox con i valori di default (e piccolo pulsantino "reset"), così che uno possa modificare il comportamento del compilatore, però sarebbe da decidere cosa può essere utile modificare (e qui chiedo a te, io non gioco mai con i compilatori)

edit: per le ottimizzazioni una combobox (per intenderci i menù a tendina) è ottima
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Maurotec

Quote
edit: per le ottimizzazioni una combobox (per intenderci i menù a tendina) è ottima


Ottimo tanto sono solo 4, quella di default sarà sempre -Os e il pulsante reset to default selezionerà questo valore.

La optimize e già un flag, se fai una text box si corre il rischio di poter modificare tutto a piacere con potenziali effetti disastrosi, teniamo sempre in conto il fatto che l'utente medio non è in grado di rimettere le flags correttamente, perché gli esiti della modifica delle flags può facilmente comportare una mancata compilazione. Il flag O0 è utile per il debug. Nota che l'optimize viene usato nel linker e nel compilatore vero e proprio, ancora devo isolare il codice e postarlo.

Un altro flag da inserire sarebbe "-save-temps" ma questo va in CXX_FLAGS cioè quando il sorgente viene trasformato in codice ".o", che poi è il processo di compilazione vero e proprio. -save-temps crea dei file ".i" già espansi dal preprocessore C/C++, così se abilitiamo questo flag possiamo vedere il lavoro svolto dal preprocessore ed è utile quando pasticciamo con le macro. Inoltre vengono creati dei file ".s" contenenti sorgente asm corrispondente ai singoli moduli "cpp". Tradotto in modo commestibile save-temps conserva i file temporaneamente creati durante il build.
Per questo basta una comune check box.

Alcune considerazioni:
Ogni progetto dovrebbe avere le proprie impostazioni, ma con arduino IDE non abbiamo file che descrivono il progetto e quindi cambiando impostazioni queste influiranno su qualunque progetto. Cosa utile allora sarebbe quella di documentare il progetto specificando quali flags si devono usare. In genere Os è la scelta primaria e le altre serviranno solo per debug e sperimentazione e test.

La stringa da inserire per fare in modo che printf accetti float è la seguente:
Code: [Select]
-Wl,-u,vfprintf -lprintf_flt
da inserire in baseCommandLinker.
Che verra inserita o meno in base ad una check box del tipo enable prinf float, con magari una tooltip del tipo: "La dimensione finale del firmware saranno maggiori ecc". Questo facilmente potrebbe portare l'utente a pensare di usare il core arduino con string & e in più abilitare print float e questo non è cosa senzata.

PS: con tooltip intendo quei messagi che compaiono se sosti con il mouse su un "widget" o components.

Ciao.




Maurotec

#13
Dec 07, 2013, 10:23 am Last Edit: Dec 07, 2013, 11:45 am by MauroTec Reason: 1
Code: [Select]
static private List getCommandCompilerS(String avrBasePath, List includePaths,
   String sourceName, String objectName, Map<String, String> boardPreferences)


Restituisce una lista di argomenti che saranno usati solo quando l'ide incontra un file sorgente ".S"
Qui non serve intervenire al momento, perché l'argomento -Ox non è previsto.

Code: [Select]

static private List getCommandCompilerC(String avrBasePath, List includePaths,
   String sourceName, String objectName, Map<String, String> boardPreferences)


Restituisce una lista di argomenti che saranno usati solo quando l'ide incontra un file sorgente ".c"
qui -Ox deve essere presente e -save-temps può essere presente o meno in base alla check box.

Code: [Select]
static private List getCommandCompilerCPP(String avrBasePath,
   List includePaths, String sourceName, String objectName,
   Map<String, String> boardPreferences)


Stessa cosa di sopra ma con i sorgenti ".cpp"

Quote
Consiglierei di revisionare il codice delle versioni 1.5.x e non quello delle 1.0.x in quanto prima o poi verrà abbandonato.
E' anche vero però che il codice della 1.0.5 è stabile mentre la 1.5.x (oggi arrivato alla 1.5.5) è in continua evoluzione.


Vero, peccato che il codice della 1.5 io non l'ho clonato e non so nemmeno cosa è cambiato, se non pesa molto ora clono il repo 1.5, ma quasi sicuramente in tempi umani non ne ricaverò informazioni necessarie per metterci mani, forse lesto può dire qualcosa di più che mi aiuti a studiare il codice più velocemente o quanto meno a farmi una idea. Il tree di progetto dell'ide io non l'ho comprendo, es perché Compiler.java si trova dentro la dir debug? Qual'è il codice dell'IDE e quello delle librerie di terze parti? ecc. Io ogni volta che navigo il tree mi perdo.

161Mb e ancora sta scaricando, troppo pesante...ma che si porta dietro java, il compilatore avr8, quello per arm ecc, ma che sono matto.

Ciao.

lestofante

#14
Dec 08, 2013, 01:27 am Last Edit: Dec 08, 2013, 01:35 am by lesto Reason: 1
la struttura non è molto user frindly, ma i java sono tutti assieme, i programmi esterni sono richiamati da terminale.

per la dimensione, si porta dietro tutta la storia, clona solo il ramo 1.5.x con una depth di 1 (solo ultima versione) e va più che bene.

il codice fondamentalmente CREDO sia lo stesso.

spero di avere tempo domani (aka non dormo fino a tardi, la sera mangio fuori), ah, potessi avere del tempo libero!!

edit: credo siano in debug perchè testavano la doppa copilazione multipiattafroma.

per il preferencies:
https://github.com/arduino/Arduino/blob/ide-1.5.x/app/src/processing/app/Preferences.java

mamma mia che casino, usano un sistema loro di preferencies quando basterebbe usare il sitema standar di java.. vabbè, in pratica devi far finire l'opne nella hashmap "table", dopo di che con un Preferencies.getBoolean(nome) o getTipoDato(nome) hai il dato dove vuoi (vedi linea 85 del Compile.java, usa Preferences.getBoolean("build.verbose"))
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Go Up