Problema de velocidad RPi GPIO en el metal desnudo

1

Después de leer el excelente artículo sobre metal desnudo de David Welch ( enlace ), un amigo y yo están tratando de implementar una simple palanca GPIO. Se basa en el blinker01 de David Welch ( enlace ). Simplemente actualicé los registros periféricos para que correspondieran con GPIO 3 en la frambuesa pi. Encontré estas direcciones mirando la hoja de datos del BCM2835 ( enlace ) . El Capítulo 6 enumera todas las ubicaciones de los ajustes de pin GPIO.

Cargamos el código en una tarjeta SD y luego lo encendemos. El programa funciona: obtenemos una onda cuadrada de 2.5MHz en el alcance.

** ¿Por qué es tan lento? **

El procesador tiene una velocidad de reloj de 1 Ghz. La operación implementamos lazos de 10 líneas de ensamblaje (es decir, hace 10 líneas de ensamblaje y luego se remonta a la primera línea de esas 10). Soy nuevo en los procesadores de metales básicos y entiendo que una línea de ensamblaje determinada puede llevar varios ciclos de reloj. Suponiendo que cada línea toma 10 ciclos de reloj, aún esperaría un período de 100 ns para la salida, que sería de 10MHz. Siento que es un límite inferior conservador en la frecuencia de salida, ya que algunas líneas de ensamblaje solo toman un solo ciclo.

Además, encontré este artículo: enlace

Esta persona logró obtener una salida de 22MHz en una frambuesa pi 1 usando un enfoque similar pero usando el mmap de linux. El código que utilizaron como base se encuentra como primer ejemplo en esta página: enlace

** Edit: Originalmente pensé que el 22MHz se logró en una frambuesa pi 2, pero eso es incorrecto. Afirman que lograron esta tasa de salida en un pi 1 que tiene el chip BCM 2835 **

Nota: aunque esto se debe a Debatably en StackOverflow, sentí que es un problema "más difícil" ya que tiene que ver con los circuitos del procesador y los periféricos.

Editar: El código de ensamblaje está aquí: Desmontaje de la sección .text:

00008000 '<_start'>:

    8000:   e3a0d902    mov sp, #32768  ; 0x8000
    8004:   eb000005    bl  8020 <notmain>

00008008 '<hang'>:

    8008:   eafffffe    b   8008 <hang>

0000800c '<PUT32'>:

    800c:   e5801000    str r1, [r0]
    8010:   e12fff1e    bx  lr

00008014 '<GET32'>:

    8014:   e5900000    ldr r0, [r0]
    8018:   e12fff1e    bx  lr

0000801c '<dummy'>:

    801c:   e12fff1e    bx  lr

00008020 '<notmain'>:

    8020:   e92d4010    push    {r4, lr}
    8024:   e59f002c    ldr r0, [pc, #44]   ; 8058 <notmain+0x38>
    8028:   ebfffff9    bl  8014 <GET32>
    802c:   e3c01c0e    bic r1, r0, #3584   ; 0xe00
    8030:   e3811c02    orr r1, r1, #512    ; 0x200
    8034:   e59f001c    ldr r0, [pc, #28]   ; 8058 <notmain+0x38>
    8038:   ebfffff3    bl  800c <PUT32>
    803c:   e3a01008    mov r1, #8
    8040:   e59f0014    ldr r0, [pc, #20]   ; 805c <notmain+0x3c>
    8044:   ebfffff0    bl  800c <PUT32>
    8048:   e3a01008    mov r1, #8
    804c:   e59f000c    ldr r0, [pc, #12]   ; 8060 <notmain+0x40>
    8050:   ebffffed    bl  800c <PUT32>
    8054:   eafffff8    b   803c <notmain+0x1c>
    8058:   20200000    eorcs   r0, r0, r0
    805c:   2020001c    eorcs   r0, r0, ip, lsl r0
    8060:   20200028    eorcs   r0, r0, r8, lsr #32

'

    
pregunta Hunter Akins

2 respuestas

2

El culpable principal es una combinación de limitaciones de hardware / periféricos y la configuración del reloj. Si bien no he tenido que trabajar con BCM Baremetal específicamente, estos son problemas comunes de los proyectos de baremetal en cualquier arquitectura compleja.

Como una sugerencia sobre las limitaciones de los controladores de salida GPIO, puede ver que cuando está cableado como salida de reloj de hardware, la frecuencia máxima de salida es de 125MHz

De la página 106 de la Hoja de Datos Periféricos de BCM que proporcionó

  

Frecuencia de funcionamiento :   La frecuencia máxima de funcionamiento de los relojes de uso general es de ~ 125 MHz a 1.2 V, pero   esto se reducirá si los pines GPIO están muy cargados o tienen una carga capacitiva.

Esto se encuentra en el contexto de la configuración del periférico GPIO para emitir el reloj periférico directamente sin alternar el software.

Yo diría que es razonable esperar que incluso si los relojes están configurados correctamente y la CPU se ejecuta a una velocidad máxima, no puede esperar que un GPIO alterne más rápido que esto debido a las limitaciones de hardware.

También porque el dispositivo periférico puede bloquear el comando de su software a tiempo, no significa que los transistores de controlador de salida físicos, que son grandes y robustos, con una gran cantidad de carga inherente, puedan cambiar tan rápido como su código pueda ejecutarse. Si está realizando pruebas, es imperativo que se utilice un osciloscopio con suficiente ancho de banda analógico y sondas de alta calidad, ya que también está cambiando su resultado con el sistema de medición. Un analizador lógico puede no ser suficiente, una velocidad de giro lenta no es identificable con las entradas con umbral.

Cómo proceder

Parece que si tu objetivo es conducir GPIO tan rápido como lo necesites, para propósitos de reloj, deberías usar estos pines integrados de salida de reloj del periférico. Estos se configuran a través de registros

CM_GP0CTL CM_GP0DIV (repita para las salidas de reloj gp 1 y 2)

Luego, dependiendo de los resultados de esto, identificará la frecuencia de conmutación máxima para su sistema de hardware teniendo en cuenta la carga máxima de GPIO y el VDD de su circuito PIO.

Si la salida del reloj es más lenta de lo esperado para la configuración de su divisor nominal, esto indicaría que no ha configurado correctamente el reloj del sistema, el enrutamiento del reloj y los PLL.

Una vez que haya identificado ese desacuerdo, puede modificar su código de arranque directo para configurar los PLL y ver si se puede realizar una conmutación controlada por software para que se ejecute tan rápido como la salida de reloj controlada por hardware y vaya desde allí.

Es posible que existan factores contribuyentes adicionales en las caché de instrucciones y datos, que requieren la configuración del software, si no puede alinear el software alternando con el límite de hardware a través de PLL solo, ese sería el próximo lugar donde buscaría.

    
respondido por el crasic
1

Acabo de encontrar esta pregunta desde una publicación cruzada.
El problema principal que no se trata en todos los comentarios anteriores es la velocidad del bus . El procesador puede estar funcionando a 3GHz pero los buses en el chip no lo están. El bus en el lado ARM es mucho más lento que 3GHz. El bus hacia el GPIO es incluso más lento, corriendo a la velocidad de la GPU. Agregue a eso el tiempo perdido para el cruce del dominio del reloj y el hecho de que los buses son un recurso compartido entre los núcleos ARM y la GPU. Además, el chip utiliza el sistema AXI que tiene un reconocimiento de escritura, por lo que el procesador puede esperar a que llegue el reconocimiento de escritura, que es el doble de la velocidad de giro del bus. En la infraestructura del bus, se requieren varios ciclos de reloj para obtener la señal de un lado del bus al otro (pero permite que se realicen múltiples transacciones en el bus al mismo tiempo).

    
respondido por el Oldfart

Lea otras preguntas en las etiquetas