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
'