Cómo iniciar core 1,2,3 en Raspberry Pi 2

10

He escrito un ejemplo de núcleo múltiple de metal desnudo.

Código, el diagrama del circuito está aquí: https://github.com/jeffreyantony/multipi/tree/master/Example_01

En mi ejemplo, hay 3 LED conectados a los pines GPIO de la frambuesa Pi. Hay totalmente 4 núcleos en Raspberry Pi 2. Cada núcleo está asignado para parpadear su LED correspondiente.

Escribí la dirección del código que debe ejecutar cada núcleo en las siguientes direcciones 0x4000009C para el núcleo 1 0x400000AC para el núcleo 2 0x400000BC para el núcleo 3

Después de compilar el código, solo el LED asignado al núcleo 1 parpadea (como en este ejemplo, LED amarillo). Otros no lo son.

Esto significa que el código para Core 2 y 3 no se está ejecutando (ya que los otros LED no parpadean). También descubrí que el código después de iniciar todos los núcleos tampoco se está ejecutando, es decir, core0_submain (): esta función debería parpadear el LED ACT en la Raspberry Pi

¿Alguien podría decirme cuál es el problema? ¿Es porque los 4 núcleos intentan escribir en el mismo registro GPIO y solo Core 1 gana en la escritura?

Traté de agregar " atributo ((desnudo));" para core0_submain () pero no sirvió de nada.

Estoy usando la cadena de herramientas de https://launchpad.net/gcc-arm-embedded

una vez más código - https://github.com/jeffreyantony/multipi/blob/master/Example_01/main.c

makefile - https://github.com/jeffreyantony/multipi/blob/master/Example_01/Makefile

Actualización 20 de octubre de 2015 : he agregado soporte para JTAG. Pero no se pudo obtener la interfaz de depuración
Actualización 25 de octubre de 2015 : se solucionó el problema. Ver respuesta.

Diagrama de circuito ingrese la descripción de la imagen aquí

robomon
fuente
Esto parece realmente genial. Lo miraré. Quiero decir, puede haber algún software en raspbian que solo use 1 núcleo a menos que se necesiten otros para ahorrar energía o algo así ...
Kachamenus

Respuestas:

6

Actualización 25 oct 2015:

El foro Raspberry Pi me dio la respuesta .

  1. No existe el concepto de _start cuando se usa -nostdlib

  2. el código que se ejecutará primero debe ser el primer archivo que se pase al vinculador.

  3. Si se necesita un mejor control, el código debe colocarse en una sección de inicio y pedirle al vinculador que copie esta sección en 0x8000

Gracias a todos por el apoyo. Aprendí mucho sobre el compilador C de GNU.

Actualización 24 oct 2015:

Cuando cambié el orden de los archivos dados para compilar en el Makefile, obtuve el orden correcto (es decir 0x8000, tenemos la _startfunción) con -O2optimización. Pero aún _startno se resuelve mi pregunta de stackoverflow a continuación sobre el símbolo. Se ha registrado un nuevo código.

He tenido algo de exito. El nuevo código se registra en github .

El ejemplo no se está ejecutando completamente. Hay algunos problemas con la compilación. Explicaré cada uno:

  1. En realidad esperaba que se _starttomara el símbolo de mi inicio personalizado. Pero no fue el caso. Debido a esto, el puntero de la pila no se configuró y el salto a main no ocurrió.

Ya he hecho una pregunta sobre esto. Pero no he progresado mucho. Así que agregué un ensamblaje en línea para cargar el puntero de la pila en la función principal.

  1. Pero aún así el código no se ejecutó. Cuando revisé la lista de ensamblaje, encontré que en la dirección 0x8000(donde comienza la ejecución) de Raspberry Pi está el código para Core 1 - void core1_main(void). Mi suposición fue que 0x8000allí estaría la _start(que no es así desde el inicio. El archivo S no se toma para compilación) o al menos la función void main (void). Esto sucede debido a la -O2optimización de GCC. En GCC, con niveles de optimización más altos, las funciones se reordenan. Cuando apagué la optimización ( -O0), luego en la dirección 0x8000, el principal estaba presente.

Puede leer sobre el reordenamiento de funciones aquí

Resumen: el código actual es solo una solución. Problema principal a resolver: ¿por qué _start no se llama desde el inicio S? Si esto se soluciona, en la dirección 0x8000 _startvendría. Con esto no tenemos que preocuparnos por el orden de las funciones realizado por GCC durante una optimización más alta.

También hay un video de demostración de mi lado como prueba. Aunque las tasas de parpadeo del LED son diferentes y periódicas en el código, dado que todos los núcleos intentan escribir en los mismos registros GPIO, hay algunos conflictos que hacen que los LED parpadeen a intervalos aleatorios.

robomon
fuente
Intente ver el código fuente de htop para ver cómo lo hacen para mostrar datos de múltiples núcleos en la pantalla.
Piotr Kula
3
@ppumkin Eso no tiene sentido. htopes una herramienta de tierra de usuario basada en * nix. En Linux solo obtiene su información del núcleo a través de /proc. Esto es material de metal desnudo. No hay ningún núcleo para consultar.
Ricitos de oro