¿Aumentar la velocidad de la transacción SPI?

1

Estoy usando SPI para escribir y leer los datos de la placa esclava. Tengo dos preguntas con respecto a este proceso:

Pregunta 1. ¿Por qué cuando trato de leer 1.000.000 bytes a través de SPI utilizando 1 mensaje, funciona más lento que si los divido en K mensajes?

Intenté reproducir la diferencia entre un mensaje grande por transacción y varios mensajes más pequeños (lo que en total nos brinda buffers del mismo tamaño) y observé que cuanto menor es el tamaño del mensaje, más rápida es la velocidad de transacción SPI.

Pregunta 2. ¿Hay alguna forma de aumentar la velocidad de las transacciones SPI?

Según mis pruebas, la transacción SPI pura para 1.000.000 bytes dividida en 500 paquetes está tomando 380 ms de tiempo de trabajo.

Lo que significa que tengo 8.000.000 bits por 0,38 segundos = > 20.55 Mbits / seg, que es menos de 48 Mbits / seg que se supone que debe ser.

Además, aquí hay algunas piezas de código que solía comparar y probar:

device = "/dev/spidev1.0";
mode = SPI_MODE_0;
bits = 8;
speed = 48000000;

fd = open(device, O_RDWR);

memset(read_buffer, 0, sizeof(read_buffer));

mass_xfer[0].tx_buf = (unsigned long)tx1;

mass_xfer[0].len = 2;
mass_xfer[0].speed_hz = speed;

// sz - amount of bytes within one SPI message

// n - amount of messages in one SPI transaction

unsigned long sz = 2000, i, n = (nbytes + sz - 1) / sz;
for (i = 0; i < n; i++) {
    mass_xfer[i + 1].rx_buf = (unsigned long)read_buffer + i * sz;
    mass_xfer[i + 1].len = min(sz, nbytes - i * sz);
    mass_xfer[i + 1].speed_hz = speed;
}

timestamp_t t0 = get_timestamp();
ret = ioctl(fd, SPI_IOC_MESSAGE(n + 1), mass_xfer);
// ret = ioctl(fd, SPI_IOC_MESSAGE(1), &read_xfer); // When I tried to read using one message, time was more than 600ms
timestamp_t t1 = get_timestamp();
printf(" SPI READ: %.2f (%d) %d\n", (t1 - t0)/1000.0L, n + 1, SPI_MSGSIZE(n + 1)); // After this output, for 1.000.000 bytes I am receiving 380.xx ms
if (ret < 1)
    pabort("can't send spi message");

¿Alguna idea?

ACTUALIZACIÓN 1:
SO: Linux 3.15.10-bone8 # 1 Vie 26 de septiembre 14:20:19 PDT 2014 armv7l GNU / Linux
CPU: Sitara AM3358 1GHz. Según esta CPU, la velocidad máxima del reloj SPI es de 48MHz.

El código está escrito en C ++ y usando la biblioteca spidev.h.

Básicamente, el tablero es BeagleBone Black .

ACTUALIZACIÓN 2: He hecho muchas pruebas y he descubierto qué está pasando y qué causa el problema.

La razón es las brechas entre las lecturas de bytes. Para ser más específicos, repasemos las líneas de código:     read_xfer.rx_buf = read_buffer;     read_xfer.len =;     read_xfer.speed_hz = 48000000;     ioctl (fd, SPI_IOC_MESSAGE (1), & read_xfer);

Si colocamos 100 (que se leen 100 bytes) en lugar de veremos la siguiente imagen en el osciloscopio: Como puede observar, lee 8 bits, luego se detiene, luego lee otros 8 bits. Así que el problema son esas brechas entre la lectura de los bytes. Aquí hay algunos resultados de prueba usando el osciloscopio:

  • bytes_amount = gap_width
  • 10 bytes = 480ns
  • 50 bytes = 410ns
  • 100 bytes = 200ns
  • 50 000 bytes = 200ns
  • 70 000 bytes = 350ns

Según los resultados, no puedo leer mensajes de más de 100 000 bytes en un paquete, ya que las brechas crearán una gran sobrecarga.

OTRA PREGUNTA ¿Qué causa esas brechas y cómo reducirlas?

    
pregunta aka

2 respuestas

2
  1. ¿Porque los datos se almacenan en búfer en algún lugar con los paquetes más grandes?
  2. ¿Cómo se configura el SPI y a qué está conectado?

Como regla general, este tipo de no se hace de esta manera. ¿Está realmente utilizando este código para hacer algo o simplemente está tratando de instrumentar las capacidades SPI? ¿Qué más se está ejecutando en la placa y cómo está configurado su núcleo? ¿Cuál es la velocidad del procesador realmente establecida y qué prioridad tiene su pequeña aplicación?

Si tienes algún tipo de requisito de casi tiempo real, te sugiero que mires

a) DMA (transmisión de descarga desde buffers de la zona del usuario)

b) Xenomai

c) (para los fanáticos locos) el PRU

Espero que esta no sea una pregunta de tarea! Aquí hay 2 enlaces para que empieces con A.

enlace enlace

    
respondido por el G Forty
0

Su búfer SPI está configurado para enviar solo un cierto número de bits a la vez. Dividirá su mensaje en segmentos del tamaño del búfer, como lo verá en el alcance.

    
respondido por el Kurt Stewart

Lea otras preguntas en las etiquetas