Newsgroup: it.hobby.elettronica.digitale
Titolo: curiosita' sul  c

Salve!
Invogliato da capire un po di cose sul c ho visto scaricando diversi 
sorgenti in rete che di solito il programma e suddiviso in moltissimi 
piccoli programmi che hanno estensione xxxx.c e xxxx.h come mai esiste 
questo sistema? 


Premettendo che centra poco con questo ng (prova su it.comp.lang.c), questa 
tecnica si chiama modularità (o anche fattorizzazione).
2 vantaggi principali: facile gestione di progetti grossi e riutilizzazione dei 
moduli tra i vari progetti.
Qui mi fermo perché qui è OT.
Luca
-- 

"Luca Pascali" <pasckos...@TOGLIMI.yahoo.iTt> ha scritto nel messaggio 
news:3dwUh.39006$tx6....@tornado.fastwebnet.it...

Ti ringrazio della risposta, ma non creod l'argomento sia Off-topic visto 
che si parla di elettronica digitale di microcontroller che possno essere 
programmati in C 


Vero a metà.
La tua domanda riguarda il C come linguaggio in sè, non applicato ad una 
particolare architettura.
Il fatto di suddividere il condice in moduli (e relativi file header) è una 
caratteristica del C che prescinde dalla destinazione di tale codice.
Applicativi per PC sono divisi in file .c e .h
Applicativi per microcontrollori sono divisi in file .c e .h
Alcune librerie possono essere utilizzate indistintamente (a patto di 
ricompilare con il giusto compilatore) su diverse architetture (big-endian 
little-endian middle-endian a 8, 16, 32 o 64 bit).
Altre dipendono fortemente dall'architettura che ospiterà il programma (come nel 
caso dei microcontrollori)
Per le domande sul C applicato ai microcontrollori, questo ng va bene, ma per 
domande relative al linguaggio in sè converrebbe chiedere al ng dedicato al 
linguaggio stesso (se esiste, e in questo caso esiste). Lì potrai avere risposte 
più esaurienti.
Scusa la mia pignoleria :-)
Luca

 una caratteristica del C che prescinde dalla destinazione di tale codice.
Più che una caratteristica del C, direi che è una pratica di Buona 
Programmazione (tm) a prescindere da quale linguaggio si usi.
Fattorizzare bene il codice, rendere le funzioni ben separate e 
generiche aiuta anche se si programma in assembly.
Molto spesso chi programma microcontrollori parte da un background 
prettamente elettronico dove questi design patterns vengono lo stesso 
applicati, per esempio, alla progettazione elettronica.
In altre parole, se è normale suddividere un grosso schema in più 
pagine, raggruppando le diverse funzioni logiche dello schema, così si 
dovrebbe fare anche per la scrittura del firmware.
Non trovo che questo thread sul design del firmware sia particolarmente 
OT, anzi se ne parla troppo poco.
Molto spesso il firmware, in un'applicazione a microntrollore, richiede 
il 90% di tutto il lavoro di progettazione.
E in un ng che ha come topic "Tutto ciò che ruota intorno al micro", 
vedo più OT una discussione che parla di come alimentare un LED 
piuttosto che questa.
Ciao

 fare anche per la scrittura del firmware.
quoto..... solo un appunto però : spesso si usano compilatori C anche per 
architetture piuttosto "piccole", e mi riferisco in particolare anche a PIC 
della serie 16Fxxx o inferiori. In questi casi bisogna stare MOLTO attenti : 
anche a me piace fare dividere tutto il programma in funzioncine che 
risolvono piccoli problemi e poi metterle insieme, ma quando gli stack frame 
sono MOLTO piccoli (per esempio il pic16f877a ha 6(7) livelli) questo può 
diventare un vero e proprio flagello.
Di recente ho programmato proprio un 877, facendo il classico main piccolo 
piccolo con una decina di chiamate a funzioni : molto bello da leggere e 
tutto quanto ma.... troppo grande! Avendo fatto chiamate a funzioni di alto 
livello ho cominciato a sprecare stack dove non dovevo, ed il risultato è 
che obbligavo il compilatore a compilare le funzioni di livello più basso 
come se fossero "inline" e quindi sprecando un sacco di ROM.
L'errore del compilatore, infine, era sempre lo stesso "out of ROM, a 
segment or the program is too large", quando l'occupazione della rom era 
minore del 70%. Togliendo le chiamate a funzione di alto livello (che mi 
permettevano di fare un file .h e .c per ogni blocco principale del 
programma), e scrivendole direttamente (il CCS non supporta dichiarazioni 
inline), ho risolto il problema.....anche se adesso è un po' brutto da 
leggere.
Per cui... regole di buona programmazione ok ma con parsimonia :-) Sui PC, 
dove ormai la programmazione a oggetti è su larga scala, si fanno classi con 
metodi anche solo per cambiare solo una variabile privata booleana :-)
Ciao
-- 
____________________
      CG Engineering
 Lab. Ricerca & Sviluppo
********************
Skype : cg_ingegnering
MSN : 
cgaudiola...@interfree.it
ICQ UIN# : 104528066 

 Applicativi per microcontrollori sono divisi in file .c e .h
Ti ringrazio per la risposta, per il fatto di chiedere argomenti sul C 
probabilmente se l'avessi postato sul newsgroup che dici tu avrei avuto 
risposte sarcastiche ( se non si sanno queste cose sul c figurati il resto) 
comunque l'ho fatto perche' holetto sempre su questo news discussioni sui 
compilatori in C, se non ti dispiace mi spiegheresti per ad esempio si trova 
lo stesso nome con estensione c e poi con h. 

 leggere.
Ciao,
concordo con quello che hai scritto. Una cosa non mi è chiara: cosa 
intendi per "chiamate a funzione di alto livello?"
Semplicemente l'invocazione di una funzione, es. miafunc(); ?
Marco / iw2nzm

 metodi anche solo per cambiare solo una variabile privata booleana :-)
Bhe è chiaro che il mio discorso si riferisce a firmware dalla media grandezza in su.
Non ha senso fare 27 moduli quando il tutto deve solo generare per esempio un PWM. Ma se già pensi 
di riusare il PWM in un altro progetto, fattorizzare e modularizzare un minimo le cose porta grandi 
benefici.
In genere, è sempre possibile suddividere correttamente in moduli separati il programma.
Se proprio non ci si riesce per limitazioni hw/sw (stack hw limitato/compilatore idiota) si può 
sempre ricorrere a stratagemmi come macro/metaprogrammazione/include.
Insisto molto su questo punto perchè il firmware, essendo per lo più sviluppato da elettronici, 
viene sempre trattato come una cosa secondaria.
Io sono elettronico, ma mi sono reso conto che nei miei progetti, spendevo la maggior parte del 
tempo scrivendo il firmware. La parte grossa del lavoro, era sempre lì. Quindi il fw è quanto meno 
della stessa importanza dell'hw.
E se dedichiamo tanta cura alla parte hw dei nostri progetti, anche il fw ha bisogno della stessa 
dedizione.
Siccome scriverlo e debuggarlo richiede tanto tempo, viene da se che riusare cose già fatte riduce 
il tempo di progettazione. Ma per riusare le cose, esse devono esssere in primo luogo *pensate* per 
essere riusate. E da qui nasce tutto il discorso sulla generalità, modularità, fattorizzazione, 
portabilità etc.. a cui tengo molto.
Tutto questo per dire che le pratiche di Buona Programmazione (tm) sono alla pari delle pratiche 
che vengono usate quando si progetta uno schema o si realizza uno sbroglio.
E siccome non siamo disposti a rinunciare a uno sbroglio fatto bene (usando per esempio un 4 strati 
invece di 2 per creare dei piani di alimentazione o roba simile), così non dovremmo rinunciare ad un 
firmware scritto bene. Se sul micro scelto ci sono troppe limitazioni che ci costringono a dare 
porcare, significa che dovevamo sceglierne un'altro, e se ormai è tardi per cambiare dobbiamo farne 
tesoro per il futuro. Per esperienza, qualche euro in più per un micro migliore vengono ampiamente 
ripagati da una scrittura più agevole del firmware. E più l'applicazione è grossa e più questo 
diventa importante.
Scusate la divagazione, ma sono cose in cui credo e tengo molto :)
Ciao

 ha scritto:

i files .h sono chiamati file header
http://www.tutorialpc.it/c++9.asp
Leggi anche questo:
http://programmazione.html.it/guide/leggi/32/guida-c/
--
ciao
  Stefano

enzo (
endesi...@nonspamlibero.it
) ha scritto:
:: Ti ringrazio della risposta, ma non creod l'argomento
:: sia Off-topic visto che si parla di elettronica digitale
:: di microcontroller che possno essere programmati in C
Se non sai programmare in C, ti consiglio di leggere:
THE C PROGRAMMING LANGUAGE di Kerningham
e Ritchie (dovrebbe intitolarsi cosě).

 Semplicemente l'invocazione di una funzione, es. miafunc(); ?
No.... per esempio :
#include "main.h"
#include "menu.h"
#include "functions.h"
void main () {
    init_cpu();
    init_deck();
    init_lcd();
    init_rtc();
    init_adc();
    while (true) {
        menu();
        func_exec();
    }
}
intendevo questo come chiamate a funzioni di alto livello, in particolare 
menu() e func_exec() , che evidentemente racchiudono tutto il resto del 
programma, scritto sugli altri file, con tanto di header, che ho incluso. Le 
chiamate a queste ultime funzioni, di alto livello, mi sprecano un livello 
di stack....che non sprecherei se potessi (per esempio, nel mio caso), 
dichiarare funzioni inline, o scriverle direttamente là


 grossa e più questo diventa importante.
Sono d'accordo con te su tutto, però quest'ultimo punto mi ha lasciato un 
po' perplesso....
Dipende molto dal target a cui stai mirando.... io mi sono complicato la 
vita scegliendo un PIC16F877A mentre all'inizio pensavo di usare un 
PIC18F6621 (che tra l'altro ha anche un moltiplicatore hw che mi avrebbe 
fatto comodo), e la stessa cosa riguardo allo stampato : prevedevo un 4 
strati ed invece l'ho fatto su 2.
Se del pezzo che stai progettando devi farne molti, e non prevedi di fare 
troppe modifiche hardware, allora credo ti convenga complicarti un po' la 
vita e minimizzare le spese....in fondo un firmware finito lo programmi sul 
tuo hardware in 1 secondo.... hai più spese iniziali ma può valerne la pena
E' vero anche che se ne fai molti pezzi un 4 strati non costa troppo di più 
di un 2 strati... ma vale qualche decina di ore di progettazione in più ?


 dichiarare funzioni inline, o scriverle direttamente là
Scusa la mia ottusità :)
Che differenza c'è tra le funzioni menu() e func_exec() rispetto alle 
altre di init_x? Non credo il fatto che siano inserite nel ciclo while 
visto che la CPU non lo sa.
Voglio dire, a meno di non chiamare funzioni annidate es:
void func1() {
    func2();
}
void func2 {}
    func3();
}
.
.
.
dovrebbe essere sempre 1 il livello di stack impegnato, o mi sono preso 
un abbaglio clamoroso?
Inoltre se non erro l'include nel CCS è fittizio, nel senso che non 
disponendo di un linker è come se al posto della direttiva #include il 
compilatore sostituisse pari pari il contenuto del file. Serve quindi 
solo a migliorare (appunto) la leggibilità del codice.
Ciao!
Marco / iw2nzm

 a migliorare (appunto) la leggibilità del codice.
Questo è vero: non è che compila ogni file, crea i file oggetto e poi li 
linka... anche se, se un file venisse incluso in più di un sorgente, fa 
sempre bene dire al preprocessore :
#ifndef   libreria_h
#define  libreria_h
....codice....
#endif
per evitare più di una inclusione.... spero tu abbia capito cosa intendevo 
:)


in meno.
Questo però è più una limitazione di un µC con lo stack hardware che del
linguaggio C in se stesso.
Di solito lo stack in C oltre a mantenere l'indirizzo di rientro delle routines
è una cosa molto usata per passare le variabili e i puntatori  e in ram lo stack
può raggiungere profondità notevoli.
--
ciao
  Stefano

Cosa intendi  per dichiarazioni inline?
Ale



http://en.wikipedia.org/wiki/Inline_function
ciao!


ho chiesto prima per non sembrare inopportuno :)
il CCS fa anche questo, tratto dal manuale:
-----------------------------------
#INLINE
Syntax: #inline
Elements: None
Purpose: Tells the compiler that the function immediately following
the directive is to be
implemented INLINE. This will cause a duplicate copy of the code to be
placed
everywhere the function is called. This is useful to save stack space
and to
increase speed. Without this directive the compiler will decide when
it is best to
make procedures INLINE.
Examples: #inline
swapbyte(int &a, int &b) {
int t;
t=a;
a=b;
b=t;
}
-------------------------------
Spero ti sia utile.
Spero di spezzare una lancia a favore del CCS che a mio parere ha
adottato la filosofia più corretta nell'implementazione di un C non
del tutto ANSI. Lo standard è bello.... meno quando hai a che fare con
MICROrisorse!
Ciao
Alex


 MICROrisorse!
Non vedo il nesso.
Esiste uno standard, (ANSI C99) che dice che per dichiarare una funzione 
inline basta scrivere la parola chiave "inline" davanti al nome. Perchè 
il CCS deve inventarsi un nuovo modo non standard? La storia delle 
microrisorse non regge: è solo una convenzione a cui il compilatore deve 
sottostare; implementare la parola chiave "inline" o inventarsi la 
direttiva "#INLINE" non cambia nulla nella generazione del codice.
Questa mania che hanno i compilatori proprietari di reinventare l'acqua 
calda è solo una mossa commerciale: il codice scritto per il CCS girerà 
solo con il CCS costringendo gli utenti a comprarlo a vita. Non mi 
sembra una cosa positiva...
Ciao