Go Down

Topic: E’ possibile sviluppare un metodo simile al comando “goto” ma più efficiente (Read 942 times) previous topic - next topic

lelebum

Viene chiamata direttamente dal loop e quindi e software.
Poco importa se si mantiene sincronizzata con un contatore sotto interrupt.
Una cosa analoga ai millis()

maubarzi

ho usato una sintassi famosa ma volevo fare un discorso generale.
Di fatto, tu nel tuo codice assembler metti nello stack indirizzo di destinazione del salto e tempo di attesa, poi la AdslRst si occupa di capire se il tempo è passato o meno.
Non essendo una routine richiamata nel loop presumo si basi su interrupt. Oppure, se ho capito male, deve essere lanciata di continuo nel loop per valutare i vari delay.
puoi fare la stessa cosa schedulando in modo analogo, invece di indirizzi da raggiungere con il goto, dei puntatori a funzione da richiamare nel modo consueto.
Quindi nel tuo caso invece di fare
Code: [Select]
goto label_indirizzo_funzione
farai
Code: [Select]
x();
x è il puntatore alla funzione.

se ho sbagliato la sintassi mi corigerete, ma concettualmente si dovrebbe essere capito cosa intendo.

Se hai parametri li passi con
Code: [Select]
x(parametro_1, parametro_2);

puoi anche crearti delle strutture più complesse tipo array di puntatori, ecc. ecc. ecc. per potenziare il codice finchè vuoi.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

lelebum

La cosa è  un po' diversa.
La logica di SoftTmr attede sul registro A della CPU  il valore del ritardo e sopratutto che il codice da eseguire dopo il ritardo segua la chiamata stessa (vedi listato).
Quando si effettua una call in assembler, in modo automatico la cpu salva sullo stack l'indirizzo che segue il comando.
Quindi  SoftTmr sfrutta questo automatismo per leggere dallo stack l'indirizzo è inizializzare l'arrays dei timer e il punto dove riprendere l'esecuzione del codice restante.
E tutto questo viene chiamato solo al momento dell'avvio del ritardo.

Diversa cosa è il timer, che all'inizio di ogni loop e in sicronia con un contatore di sistema decrementa i vari timer e al momento del termine esegue una call all'indirizzo passato da SoftTmr.
.

maubarzi

Ma quindi come passi alla parte di codice da eseguire nell'attesa?
Un'altra goto basata su qualche convenzione specifica?
Io, dove avevi messo i puntini nel mezzo avevo inteso che ci fosse di tutto e di più, cioè che nel mezzo ci fosse il resto di codice, quindi il codice da eseguire nell'attesa fosse scritto sequenzialmente e solo il codice post attesa fosse da raggiungere mediante goto, un po' come una chiamata di funzione.
Diciamo che l'attesa è di un minuto, prendo il tuo ultimo esempio:

Code: [Select]
void loop(){
  Lettura_I2C();
  if (Serial.available()) {
    LeggiSerial();
  }
  if (digitalRead(pinModem)) {
    AdslRst();
  }
  // effettuare il restart del modem (commento originale)
  ... // codice di restart da effettuare quando passa il minuto.
  // Forse questo codice è dentro le parentesi dell'if precedente?
  // Se NO verrebbe eseguito sempre, se SI come si passa a fare un nuovo giro di loop per dire che la AdslRst non è bloccante e ad es. per leggere ulteriori dati dalla seriale?
  
  if (digitalRead(pinLuceScale)) {
    AccendiLuce();
  }

..... // altro codice

}

A parte i commenti, che ho eliminato per aggiungere i miei, ho messo le graffe per non fare casino con i blocchi di codice delle if.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

Standardoil

Quindi non solo interrupt, ma anche deve essere richiamato esplicitamente nella loop
E dove sarebbe la novità?
Ero capace anch'io di farlo, senza nemmeno fare tanto chiasso, anzi lo ho gia fatto e pubblicato mesi fa.
E sono solo l'ultimo e il più umile di una lunga serie, dei quali molti hanno fatto pure meglio di me
Insomma: tanto rumor per nulla....
Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

lelebum


Standardoil

Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

lelebum

Trovato e complimenti per la libreria.

Io in C non così avanti e l'ho sempre ammesso ...

Al momento uso un qualcosa di simile al tuo utilizzando i soliti millis.

Per non caricare il loop io ho preferito chiamare i millis una sola volta per loop.
Genero così una sorta di clock software che interroga ciclicamente con il solito IF i vari timer con variabili intere.
Avevo anche optato per gli arrays, ma strada facendo le ho abbandonate.

Per chiudere l'argomento, la mia mitica routine SoftTmr è madre di quanto accennato e le solite  personalizzazioni è un percorso obbligato per tutti.

E' risaputo che in assembler sono permesse cose non accessibili con altri linguaggi ed è stato un errore tentare di trovare una soluzione.


maubarzi

errore non direi, è giusto approfondire ed è legittimo chiedere
quando si passa da un linguaggio ad un altro è inevitabile, se poi quello di partenza è uno di basso livello, le differenze possono essere ancora più marcate.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

zoomx

E' risaputo che in assembler sono permesse cose non accessibili con altri linguaggi ed è stato un errore tentare di trovare una soluzione
Non sono un esperto ma credo che su architettura ATMEGA328 non sia possibile neanche in assembly perché le istruzioni sono tutte sulla flash. Ma magari esiste il salto con un indirizzo ottenuto da una combinazione insieme a qualche registro, quindi modificabile?
Su una STM32 invece penso sarebbe possibile poiché è possibile far girare un programma in RAM e quindi sarebbe possibile modificare il valore direttamente del salto del jump. Non so se è possibile mescolare flash e RAM.

Standardoil

Io in C non così avanti e l'ho sempre ammesso ...

Al momento uso un qualcosa di simile al tuo utilizzando i soliti millis.

Per non caricare il loop io ho preferito chiamare i millis una sola volta per loop.
Genero così una sorta di clock software che interroga ciclicamente con il solito IF i vari timer con variabili intere.
Avevo anche optato per gli arrays, ma strada facendo le ho abbandonate.

io non sono così avanti come credi
il tempo delle librerie è vecchiotto, e contiene alcuni accrocchi che NON sono buona programmazione
passo a passo a spasso invece non serve esattamente per una sorta di multitasking, ma per un timer ciclico
se dovessi rifarli adesso partire in una maniera differente, e l'idea mi tenta
Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

maubarzi

Non sono un esperto ma credo che su architettura ATMEGA328 non sia possibile neanche in assembly perché le istruzioni sono tutte sulla flash. Ma magari esiste il salto con un indirizzo ottenuto da una combinazione insieme a qualche registro, quindi modificabile?
Su una STM32 invece penso sarebbe possibile poiché è possibile far girare un programma in RAM e quindi sarebbe possibile modificare il valore direttamente del salto del jump. Non so se è possibile mescolare flash e RAM.
Faccio un discorso puramente teorico perchè anche io non conosco il dettaglio di dettaglio ;) , ma un modo per indirizzare le due aree di memoria deve esserci altrimenti non ci sarebbe accesso ai dati, magari si tratta semplicemente di istruzioni differenti oppure la modalità di indicazione dell'indirizzo di salto cambia per far capire di che indirizzo si tratta.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

Standardoil

Prima legge di Nelson (che sono io): Non scambiare il fine con il mezzo: ricorda "cosa" devi fare, non "come" devi farlo

Non bado a studenti, che copino altrove

Tu hai problema-Io ti domando-Tu non mi rispondi: vuol dire che non ti serve più

lelebum

In assembler non esistono limiti a quello ci se può fare, soprattutto anche ....
C'era chi per ottimizzare  l'esecuzione del codice macchina creava una routine che modificava se stessa e questo un Atmega 328 non potrebbe farlo perché ha la memoria programma su flash.
Conoscendo bene l'hardware e il codice macchina del 328 ci vorrebbe poco a fare la conversione della mia routine.

zoomx

lelebum,
per me era roba che si faceva sul 6510 del Commodore64. So che si può fare su STM32 perché quando è stato preso il codice del bootloader della MAple Mini per modificarlo si è scoperto che c'era questa possibilità, mai sfruttata, credo. E su quella scheda è montata una MCU direi basica, per cui immagino si possa fare anche sulle altre MCU superiori. E' che in genere hanno poca RAM rispetto alla flash.

Go Up