Velocità del loop Mega 2560

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:

#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:

// 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.