Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Architettura di Arduino

Tipologie, strumenti di sviluppo, hardware e progetti

Moderatore: Foto UtentePaolino

0
voti

[31] Re: Architettura di Arduino

Messaggioda Foto Utentedursino » 5 ott 2011, 10:24

Grazie per la risposta.
Do qualche info che saranno valide da qui a quando non lo specificherò.

Micro : ATMEGA 328
OS : ArchLinux ,Kernel 2.6.39-ARCH #1 SMP PREEMPT Sat Jul 9 15:31:04 CEST 2011 i686 Intel(R) Atom(TM) CPU N270 @ 1.60GHz GenuineIntel GNU/Linux

Compiler: avr-gcc (GCC) 4.6.0

Utilizzo avr-objcopy per creare l'esadecimale e poi avrdude per il burning sulla board.

Sto scrivendo sia in C sia in assembly mediante file esterni .S
Per quanto riguarda la corrispondenza fra C ed Assembly, conosco il comportamento
in ambiente PC,ma adesso sono un po' spiazzato.
Per esempio una funzione int f() sapevo che restituiva l'intero in EAX, qui invece dove?
Anche la sintassi dei registri mi spiazza.
Avete qualche link per approfondire,ho trovato qualcosa in rete, ma nessun documento
abbastanza completo per eliminare alcuni dubbi.

Grazie per la risposta
Avatar utente
Foto Utentedursino
255 1 5 5
Expert
Expert
 
Messaggi: 522
Iscritto il: 8 mar 2009, 13:24

2
voti

[32] Re: Architettura di Arduino

Messaggioda Foto Utentexyz » 5 ott 2011, 11:40

dursino ha scritto:Per esempio una funzione int f() sapevo che restituiva l'intero in EAX, qui invece dove?

EAX non esiste negli AVR, è un registro della CPU a 32 bit 386 dell'Intel. Ogni costruttore per ogni famiglia di CPU utilizza nomi diversi per i registri, set distruzioni e sintassi.

I passaggi dei parametri e il ritorno nelle chiamate a funzioni è una convezione imposta dal compilatore e si chiama ABI (Application Binary Interface). Compilatori diversi o versioni diverse dello stesso compilatore possono avere ABI diverse, quindi librerie compilate con una determinata ABI possono non funzionare se utilizzate con un ABI diversa.

La convezione utilizzata dal GCC del AVR è descritta qui:

http://www.nongnu.org/avr-libc/user-man ... _reg_usage

AVR per il ritorno di un intero a 8 bit utilizza il registro r24.

La documentazione su come interfacciare codice assembler per gli AVR con il C:

http://www.nongnu.org/avr-libc/user-man ... e_asm.html
Avatar utente
Foto Utentexyz
5.900 2 4 5
G.Master EY
G.Master EY
 
Messaggi: 1550
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[33] Re: Architettura di Arduino

Messaggioda Foto Utentedursino » 5 ott 2011, 12:22

Grazie, ora come ora non sto usando l'inline ASM ma sto usando dei file
esterni .s scritti solo in assembly (mi piace di più) .
Adesso ho un problemino però, chiamo una funzione dal codice C:
Codice: Seleziona tutto
void schedule(void body())
{
      tabella_proc[0].process_counter = 0 ;
            tabella_proc[0].process_counter = (unsigned int) body; 
      active(); return ;


}

in tabella_proc[0].process_counter inserisco il puntatore all'entry point della funzione
body, diciamo che sto cercando di implementare delle funzionalità multitasking.
active() è funzione in assembly,quello che dovrebbe fare è inserire nello STACK il nuovo puntatore a funzione (body) in modo tale che una volta eseguita l'istruzione RET,
si passi ad un nuovo processo con il suo corpo.

Per ciò che so l'indirizzo di ritorno ,ossia il return,è messo nello stack che poi si va gonfiare a seconda delle variabili locali,almeno nella traduzione C --> Assembly.
Il punto è che io chiamo una funzione Assembly quindi questo non dovrebbe accadere.
Visto che il Process Counter è di 16 bit,posso supporre che TOP e TOP -8 dello stack
siano gli indirizzi dove è locato l'indirizzo di ritorno.
Dunque ciò che voglio fare è modificare questo,in modo che sia l'indirizzo di BODY.

Una funzione così potrebbe funzionare ?
Codice: Seleziona tutto
.data

.global tabella_des_proc

tabella_des_proc:  .fill 40

.global active

active :
            LDS R2, tabella_des_proc $ Indirizzo meno significativo
            LDS R1, tabella_des_proc +8 $ + significativo
            POP R3  $ Svuoto pila
            POP R4
            PUSH R2 $inserisco nuovo indirizzo
            PUSH R1

            RET
            
            
Avatar utente
Foto Utentedursino
255 1 5 5
Expert
Expert
 
Messaggi: 522
Iscritto il: 8 mar 2009, 13:24

2
voti

[34] Re: Architettura di Arduino

Messaggioda Foto Utentexyz » 5 ott 2011, 13:55

Un programma in assembler può usare convenzioni proprietarie sui passaggi dei parametri ma se poi si interfaccia al C deve essere compatibile.

Credo che ti stai complicando la vita, in C esistono i puntatori di funzioni:

http://www.newty.de/fpt/intro.html#what

non servono giochetti strani nello stack (non è atomica), la stessa libreria standard del C lo utilizza per la funzione qsort, ad esempio. Molti sistemi di multi-task no-preemption sono implementati con una lista di puntatori di funzioni.

Comunque per chiamare un puntatore di funzione in assembler AVR non serve mettere l'indirizzo nello stack e usare l'istruzione "RET", esiste l'istruzione "ICALL".
Avatar utente
Foto Utentexyz
5.900 2 4 5
G.Master EY
G.Master EY
 
Messaggi: 1550
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[35] Re: Architettura di Arduino

Messaggioda Foto Utentedursino » 6 ott 2011, 10:27

Grazie xyz mi stai dando una grande mano.

Volevo però chiedere una cosa:
Vorrei fare un po' di debbuging ed ho visto in rete che c'è da utilizzare
avr-gdb (installato) e simulavr.
Quest'ultimo però non riesco ad installarlo,mi da errori di compilazione:
Codice: Seleziona tutto
buffer-size=4 -D_FORTIFY_SOURCE=2 -MT config_scanner.o -MD -MP -MF .deps/config_scanner.Tpo -c -o config_scanner.o config_scanner.c
config_scanner.c:1188:12: warning: ‘input’ defined but not used [-Wunused-function]
config_scanner.l: In function ‘config_lex’:
config_scanner.l:62:1: error: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result [-Werror=unused-result]
cc1: all warnings being treated as errors

make[3]: *** [config_scanner.o] Error 1
make[3]: Leaving directory `/home/dursino/Downloads/simulavr/src/simulavr-0.1.2.7/src/disp-vcd'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/dursino/Downloads/simulavr/src/simulavr-0.1.2.7/src'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/dursino/Downloads/simulavr/src/simulavr-0.1.2.7/src'
make: *** [all-recursive] Error 1
==> ERROR: A failure occurred in build().
    Aborting...

Questo è quello dall'AUR di ARchlinux,ma anche quello ufficiale dal sito di simulavr mi da errori.
Conoscete Simulavr,sarà davvero utile?
Avete mica dei binari precompilati?
Grazie

EDIT: HO risolto modificando tutti i makefile ed eliminando la flag -Werr .

(Noiosissimo), però se qualcuno vuole commentare gdb-avr ed simulavr ben venga
Avatar utente
Foto Utentedursino
255 1 5 5
Expert
Expert
 
Messaggi: 522
Iscritto il: 8 mar 2009, 13:24

0
voti

[36] Re: Architettura di Arduino

Messaggioda Foto Utentedursino » 15 ott 2011, 12:50

Salve, è un po' che non scrivo.
Ho fatto decisaemnte passi avanti sul progetto del Multitasking.

In particolare adesso i processi vengono creati,hanno una loro pila,un loro corpo
vengono messi in esecuzione e si alternano mediante uno scheduler.
Se interessa posto il codice.
Comuqneu adesso vorrei implementare una primitiva "delay()" che possa bloccare
un processo per un tot di tempo e poi rimetterlo in esecuzione.
Questo senza usare librerie esterne.
Dove posso leggere qualcosa sul set del timer e sulla scrittura del driver che viene lanciato appena il timer raggiunge tot tempo?
Grazie
Avatar utente
Foto Utentedursino
255 1 5 5
Expert
Expert
 
Messaggi: 522
Iscritto il: 8 mar 2009, 13:24

0
voti

[37] Re: Architettura di Arduino

Messaggioda Foto Utentexyz » 15 ott 2011, 15:51

Non so quanto conosci di sistemi operativi (altrimenti leggiti il Tanenbaum).

Uno scheduler no-preemption non può implementare la funzione delay altrimenti blocca tutti gli altri task. Al massimo puoi comunicare di bloccare l'esecuzione del task per un certo periodo.

Se vuoi utilizzare la funzione delay all'interno di un task devi implementare uno scheduler preemption non facile, le righe di codice aumentano parecchio, serve per forza del codice assembler messo in opportuni punti per salvare e ripristinare lo stato del task e tutto risulterà più difficile da debbuggare.

Le AVR-libc ha già le funzioni di ritardo ottimizzare ma per uno sheduler preemption è meglio usare interrupt.
Avatar utente
Foto Utentexyz
5.900 2 4 5
G.Master EY
G.Master EY
 
Messaggi: 1550
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

0
voti

[38] Re: Architettura di Arduino

Messaggioda Foto Utentedursino » 15 ott 2011, 16:41

xyz ha scritto:Non so quanto conosci di sistemi operativi (altrimenti leggiti il Tanenbaum).

Mah.. non saprei, un po' si,il Tanenbaum ? Il mio Tanenbaum è l'ing. Graziano Frosini :mrgreen: a mio modo di vedere un Guru nell'informatica Italiana,insieme al Corsini.
a parte gli scherzi ho fatto l'esame di Calcolatori Elettronici e Sistemi Operativi alla facoltà di Ing. Informatica di Pisa dove appunto insegnano i signori citati.
Uno scheduler no-preemption non può implementare la funzione delay altrimenti blocca tutti gli altri task. Al massimo puoi comunicare di bloccare l'esecuzione del task per un certo periodo.
Il mio scheduler è con Preemption,comunque quando chiamo la Delay lo metterei nella lista dei bloccati,quindi non bloccherebbe comunque nessuno.
codice assembler messo in opportuni punti per salvare e ripristinare lo stato del task e tutto risulterà più difficile da debbuggare.

Già scritto,perché ho già implementato i semafori e dunque lo switching contest c'è già,
dunque anche la salva/carica stato.
Le AVR-libc ha già le funzioni di ritardo ottimizzare ma per uno sheduler preemption è meglio usare interrupt.

Non voglio usare librerie esterne.
L'idea è:
/*dentro body processo A*/
my_delay(1000); //1000 ms=1s

.text
my_delay: Salva_stato
Inserisci A in lista bloccati
#Setta timer
#Setta Interrupt per quel timer dopo 1 s
schedule
RET
Poi quando parte l'interrupt mi sblocca il processo che torna in coda pronti
o va subito in esecuzione se il processo che ha la CPU ha priorità minore.

Il problema è che non è una passeggiata settare i timer e le interrupt
tutto a manina.
Ciao e grazie per la risposta
Avatar utente
Foto Utentedursino
255 1 5 5
Expert
Expert
 
Messaggi: 522
Iscritto il: 8 mar 2009, 13:24

0
voti

[39] Re: Architettura di Arduino

Messaggioda Foto Utentexyz » 15 ott 2011, 18:52

Questa è una mia routine per il delay lunghi, è simile a quella presente nelle AVR-libc solo che usa più registri:

Codice: Seleziona tutto
static inline void mydelay_ms(double ms)
{
        // (sbiw) 2 +
        // (sbc)  1 +
        // (sbc)  1 +
        // (brne) 2 =
        //        6 cycles
   
        uint32_t ticks = ((double)(F_CPU) / (double)(6*1000)) * ms;

        __asm__ volatile (
                "1:sbiw %A0,1"            "\n\t"
                "  sbc  %C0,__zero_reg__" "\n\t"
                "  sbc  %D0,__zero_reg__" "\n\t"
                "  brne 1b"
                : "=w" (ticks)
                : "0" (ticks)
        );
}


Tieni conto che quando serve precisione nelle tempistiche usare l'nterrupt collegato al timer hardware è fondamentale.
Avatar utente
Foto Utentexyz
5.900 2 4 5
G.Master EY
G.Master EY
 
Messaggi: 1550
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

Precedente

Torna a Realizzazioni, interfacciamento e nozioni generali.

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti