Pages: 1 ... 6 7 [8]   Go Down
Author Topic: Velocità del loop Mega 2560  (Read 7137 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
il rallentamento indotto dalla creazione delle classi è minimo

No, è nullo.
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tuxduino, non avevo proprio guardato la main.cpp sei stato geniale smiley, però mi chiedevo ....
Adesso che le ISR di ricezione seriale vengono eseguite solo quando arrivano dei byte, cosa implica l'aver tolto quella linea? perchè se è stata messa un motivo c'era ... o no?
Tra l'altro hai reso più veloce anche la UNO, non ho provato ma dovrebbe essere così

ciao
« Last Edit: January 10, 2013, 06:26:26 am by pablos » Logged

no comment

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nel 1° caso escludi il setup delle seriali, quindi escludi check sui buffer e interrupt.
Nel 2° caso togli solo i check per verificare se ci sono byte nei buffer, quindi il guadagno prestazionale è minore dato che  hai le ISR a rallentare lo sketch.

(se ho capito bene a quali porzioni di codice ti stai riferendo)

Le ISR di ricezione seriale vengono eseguite solo quando arrivano dei byte. Il solo fatto che siano attive non consuma cicli di CPU.
Vero anche questo....
Logged


0
Offline Offline
Faraday Member
**
Karma: 30
Posts: 2905
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Io non uso più il core Arduino da tanto, ne uso il C++, ma solo C e strutture usate a mò di oggetti. Poi uso una specie di pseudo tipo per raggruppare i registri da passare alle funzioni e altre cose che mi permettono di andare alla massima velocità.

Il codice seguente attiva la seriale 0 e scrive qualcosa:
Code:
#include <mio.h>
#include <uart.h>
#include <stdio.h>


FILE uart_str;
// seriale numero 0
// questa define si trova in ogni file header dipendente dalla MCU, header che viene incluso dal file "mio.h"
// vedi anche USART_T
// #define USART0 &UCSR0A, &UCSR0B, &UCSR0C, &UBRR0, TXEN0, RXEN0

int
main(void) {
    usart_init(USART0, 230400, USART_CK_DOUBLE, &uart_str);
    while (1) {
        fprintf(&uart_str, "test uart");
        fprintf(&uart_str, "%d", UBRR0 );
    }
}

La funzione usart_init:
Code:
// USART_T è un pseudo tipo, ma è meglio dire che si tratta di un'accorpamente di dichiarazione di variabili
// che si trova nel file header dipendente dalla MCU.
// nel file atmega48.h c'è questa define:
// #define USART_T volatile uint8_t *ucsra, volatile uint8_t *ucsrb, volatile uint8_t *ucsrc,\
//                volatile uint16_t *ubrr, volatile uint8_t tx_en, volatile uint8_t rx_en
// pertanto i parametri passati a usart_init possono essere in numero deciso dall'header della MCU


void
usart_init(USART_T, uint32_t baud, const uint8_t ck_serial_mode, struct __file *strm);

void
usart_init(USART_T, uint32_t baud, const uint8_t ck_serial_mode, struct __file *strm)
{

    if (ck_serial_mode == USART_CK_DOUBLE) {
        /* Usart clock double */
        *ucsra _bit_set(UCSRA_U2X);
        *ubrr = USART_UBRR_2X(baud);
    } else {
        *ucsra _bit_unset(UCSRA_U2X);
        *ubrr = USART_UBRR_1X(baud);
    }
    *ucsrb = _BV(tx_en) | _BV(rx_en); /* tx/rx enable */


    fdev_setup_stream(strm, uart_putchar, uart_getchar, _FDEV_SETUP_WRITE);
}


Come si vede non scrivo molto, ma c'è un ma, per usare fprint per qualunque dato devo abilitare dei flag di compilazione che in arduino sono disabilitati, questo nel mio caso incrementa la dimensione dell'eseguibile.

Anche se sono poche righe di codice, un principiante non saprebbe scriverle e arduino è vincente per questo. Io non ho trovato modo per coniugare
l'efficenza e semplicità di uso. Ho anche provato altre librerie C++ nelle quali si è fatto qualcosa di efficente, ma per salvare l'efficenza si è compromesso la semplicità di uso. Per questo considero la semplicità e l'efficenza le due facce della medaglia, cioè o l'una o l'altra ma mai entrambe.

Comunque anche la complicata iniziazializzazione che uso ha risvolti negativi, uno tra questi il numero elevato di argomenti di funzione.

L'unico modo che conosco per scrivere codice efficiente e quello di non usare librerie automatizzate e usare direttamente i registri.

Una funzione specifica di  usart_init si avvantagerebbe dell'uso dei registri senza che queste debbano essere passati come argomento.

creare più funzioni di libreria con nome usart0_init, usart1_init ecc risolverebbe ma il programmatore non ha davanti sempre le stesse api.
Usare le strutture compilandole con gli indirizzi dei registri occupa memoria ram.

A proposito di ram, il compilatore dovrebbe fare pulizia se non c'è un riferimento ad una istanza, quindi anche l'array visto che non c'è codice che lo usa dovrebbe essere spazzato via e quindi non occupare memoria.

Ragazzi mi manca la volonta è il tempo per studiare asm, chi conosce bene asm può verificare cosa fa il compilatore tutti gli altri devono stare in fiducia.

Ciao.

Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10447
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

se cerchi bene in giro puoi usare la printf senza bisogno di modificare nulla, l'ho usato personalmente ma non ho uppato il codice... ma l'avevo trovato facilmente con google.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Offline Offline
Faraday Member
**
Karma: 30
Posts: 2905
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

se cerchi bene in giro puoi usare la printf senza bisogno di modificare nulla, l'ho usato personalmente ma non ho uppato il codice... ma l'avevo trovato facilmente con google.

Esatto, la printf & company scrivono già nella prima seriale, cioè su USART0, ma il codice che ho postato vale anche per le altre seriali. Inoltro con lo stesso sistema scrivo sul display con fptrintf 20x4.

In genere qualunque funzionalità mi serva tendo ad usare cio che già offre la avr-libc, sempre che sia possibile.
Più in la dovrei riscrivere il codice per il display 64128 usando sempre lo stesso sistema, in questo modo riutilizzo più volte sempre lo stesso codice fornito dalla avr-libc
diversamente usando molte librerie il codice si gonfia rapidamente. Poi è quello che viene fatto anche nel core di Arduino, dove la print viene usata anche per altre cose, almeno così mi ricordo.

Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tuxduino, non avevo proprio guardato la main.cpp sei stato geniale smiley, però mi chiedevo ....

smiley

Adesso che le ISR di ricezione seriale vengono eseguite solo quando arrivano dei byte, cosa implica l'aver tolto quella linea? perchè se è stata messa un motivo c'era ... o no?

Ho risposto qualche commento fa. Ripeto brevemente: serialEventRun fa sostanzialmente questo (pseudocodice per essere più chiari):

if (ci sono byte nel buffer di ricezione della seriale) then
    chiama la funzione serialEvent
endif

Nel caso della UNO lo fa per la sola Serial, nel caso della Mega lo fa per Serial, 1, 2, 3. A prescindere dal fatto che all'utente servano o meno.
Commentando quella riga, l'utente non dovrà più implementare la funzione serialEvent() (una per ogni seriale che usa), ma dovrà esplicitamente scrivere:

Code:
if Serial.available() {
    fai qualcosa
}

per le seriali che usa.

Tra l'altro hai reso più veloce anche la UNO, non ho provato ma dovrebbe essere così

ciao

Appunto, appena hai tempo e voglia fai una prova. smiley
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
fa sostanzialmente questo (pseudocodice per essere più chiari):

if (ci sono byte nel buffer di ricezione della seriale) then
    chiama la funzione serialEvent
endif

Nel caso della UNO lo fa per la sola Serial, nel caso della Mega lo fa per Serial, 1, 2, 3. A prescindere dal fatto che all'utente servano o meno.
Commentando quella riga, l'utente non dovrà più implementare la funzione serialEvent() (una per ogni seriale che usa), ma dovrà esplicitamente scrivere:

Code:

if Serial.available() {
    fai qualcosa
}
Ok, chiaro

Quote
Appunto, appena hai tempo e voglia fai una prova. smiley
Non ho provato perchè non ce l'ho io ahahahha  (non avevo specificato), tu ce l'hai  smiley-mr-green

riguardo a un appunto che hai fatto a pag 5 che mi era sfuggito
Quote
A proposito dell'influenza della seriale sulle prestazioni, vorrei sottolineare i risultati che ho ottenuto nel mio sketch di prova: tra baud rate di 9600 e 115200 c'è una differenza significativa.
Va ricordato però che nelle ultime versioni di Arduino anche la trasmissione seriale è fatta via interrupt, e diventa bloccante solo nel momento in cui il buffer di trasmissione è pieno, quindi in realtà se si trasmettono "pochi" (1) byte alla volta, l'impatto complessivo dovrebbe essere molto limitato.
ho rifatto i test prima con baud rate 9600 e 115200, non ho rilevato nessuna differenza

ciao
« Last Edit: January 10, 2013, 12:56:28 pm by pablos » Logged

no comment

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
ho rifatto i test prima con baud rate 9600 e 115200, non ho rilevato nessuna differenza

Sì ma con quale codice ? Inviavi caratteri oppure era solo uno sketch vuoto con un argomento diverso passato alla begin() ?
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

inviavo caratteri, ma c'era un errore nello sketch  smiley-grin , confermo c'è un abisso tra i 2 baud rate. 
Logged

no comment

0
Offline Offline
Faraday Member
**
Karma: 45
Posts: 5785
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

x iscrizione
Logged

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

L'ultimo messaggio è di 6 mesi fa, credo che sia abbastanza "morta" come discussione  smiley-wink
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3251
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si direi anche conclusa con un ottimizzazione dello speed sia della mega che della uno.
Logged

no comment

Pages: 1 ... 6 7 [8]   Go Up
Jump to: