sistema raspberry programa para operativo noobs instalar descargar compilar compilador codigo c arm embedded raspberry-pi low-level

para - programa en c raspberry



¿Cómo ejecutar un programa en C sin sistema operativo en la Raspberry Pi? (5)

Me gustaría experimentar con la Raspberry Pi para algunas aplicaciones integradas de bajo nivel. El único problema es que, a diferencia de las placas de microcontroladores AVR y PIC disponibles, Raspberry Pi normalmente ejecuta un sistema operativo (como Raspbian) que distribuye el tiempo de CPU entre todos los programas en ejecución y lo hace poco práctico para ciertas aplicaciones en tiempo real.

Recientemente aprendí que, asumiendo que tiene un gestor de arranque como GRUB instalado, ejecutar un programa C en x86 (en forma de un núcleo) requiere muy poca configuración real, solo un programa de ensamblaje para llamar a la función principal y al código C real .

¿Hay alguna manera de lograr esto con una Raspberry Pi? Sería una excelente manera de aprender acerca de la programación ARM de bajo nivel, y ya tiene algunos periféricos complejos con los que se puede jugar (USB, Ethernet, etc.)


El Pi puede ser un poco subóptimo para lo que se quiere hacer, ya que el diseño de SoC es tal que la CPU ARM es un ciudadano de segunda clase, lo que significa que hay algunos obstáculos para lograr un programa completo que se ejecuta en él.

Sin embargo, podría hacer trampa un poco y usar la API de U-Boot para darle acceso a algunas de las funciones que proporciona U-Boot, pero podrá agregar sus propias funciones en el lateral.


En realidad, la Raspberry Pi es uno de los brazos más fáciles de programar para el metal desde cero (sin sistema operativo). Tengo muchos ejemplos en Github para que puedas comenzar.

https://github.com/dwelch67/raspberrypi

Una cosa buena de la frambuesa pi es que no necesita un gestor de arranque como uboot, hay un gpu que en realidad trae el chip primero, luego carga el núcleo (o la aplicación de metal, lo que sea) en ram y ramifica en el de la misma manera que tendría uboot. Otra cosa buena es que no puedes hacerlo con tantas otras tablas de esta clase, si te equivocas extrae la tarjeta SD, vuelve a intentarlo, si te rindes, vuelve a colocar una tarjeta SD con Linux y corre linux ...


Si bien es posible el uso de metal desde cero en el Pi, lo evitaría ya que Linux se está volviendo muy liviano y maneja un montón de cosas para ti.

Aquí hay un tutorial para comenzar si aún desea aprender cosas de metal desde cero: http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

Con todo lo dicho, simplemente cargaría su distribución de linux incrustada favorita (la RT parcheada podría ser la preferida según sus requisitos) y la calificaría de buena.



Intermitente completamente automatizado.

Probado en el host Ubuntu 16.04, Raspberry Pi 2.

dwelch''s es el ejemplo más completo , pero este es un mínimo fácil de configurar hola mundo.

Uso:

  1. Inserte la tarjeta SD en el host

  2. Haz la imagen:

    ./make.sh /dev/mmblck0 p1

    Dónde:

    • /dev/mmblck0 es el dispositivo de la tarjeta SD
    • p1 es la primera partición del dispositivo ( /dev/mmblck0p1 )
  3. Insertar tarjeta SD en PI

  4. Encienda y apague la alimentación

GitHub en sentido ascendente: https://github.com/cirosantilli/raspberry-pi-bare-metal-blinker/tree/d20f0337189641824b3ad5e4a688aa91e13fd764

empieza

.global _start _start: mov sp, #0x8000 bl main hang: b hang

C Principal

#include <stdint.h> /* This is bad. Anything remotely serious should use timers * provided by the board. But this makes the code simpler. */ #define BUSY_WAIT __asm__ __volatile__("") #define BUSY_WAIT_N 0x100000 int main( void ) { uint32_t i; /* At the low level, everything is done by writing to magic memory addresses. The device tree files (dtb / dts), which are provided by hardware vendors, tell the Linux kernel about those magic values. */ volatile uint32_t * const GPFSEL4 = (uint32_t *)0x3F200010; volatile uint32_t * const GPFSEL3 = (uint32_t *)0x3F20000C; volatile uint32_t * const GPSET1 = (uint32_t *)0x3F200020; volatile uint32_t * const GPCLR1 = (uint32_t *)0x3F20002C; *GPFSEL4 = (*GPFSEL4 & ~(7 << 21)) | (1 << 21); *GPFSEL3 = (*GPFSEL3 & ~(7 << 15)) | (1 << 15); while (1) { *GPSET1 = 1 << (47 - 32); *GPCLR1 = 1 << (35 - 32); for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; } *GPCLR1 = 1 << (47 - 32); *GPSET1 = 1 << (35 - 32); for (i = 0; i < BUSY_WAIT_N; ++i) { BUSY_WAIT; } } }

ldscript

MEMORY { ram : ORIGIN = 0x8000, LENGTH = 0x10000 } SECTIONS { .text : { *(.text*) } > ram .bss : { *(.bss*) } > ram }

make.sh

#!/usr/bin/env bash set -e dev="${1:-/dev/mmcblk0}" part="${2:-p1}" part_dev="${dev}${part}" mnt=''/mnt/rpi'' sudo apt-get install binutils-arm-none-eabi gcc-arm-none-eabi # Generate kernel7.img arm-none-eabi-as start.S -o start.o arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c main.c -o main.o arm-none-eabi-ld start.o main.o -T ldscript -o main.elf # Get the raw assembly out of the generated elf file. arm-none-eabi-objcopy main.elf -O binary kernel7.img # Get the firmware. Those are just magic blobs, likely compiled # from some Broadcom proprietary C code which we cannot access. wget -O bootcode.bin https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/bootcode.bin?raw=true wget -O start.elf https://github.com/raspberrypi/firmware/blob/597c662a613df1144a6bc43e5f4505d83bd748ca/boot/start.elf?raw=true # Prepare the filesystem. sudo umount "$part_dev" echo ''start=2048, type=c'' | sudo sfdisk "$dev" sudo mkfs.vfat "$part_dev" sudo mkdir -p "$mnt" sudo mount "${part_dev}" "$mnt" sudo cp kernel7.img bootcode.bin start.elf "$mnt" # Cleanup. sync sudo umount "$mnt"

Ejemplos de metales desnudos amigables con QEMU

El problema con la luz intermitente es que es difícil observar los LED en QEMU: https://raspberrypi.stackexchange.com/questions/56373/is-it-possible-to-get-the-state-of-the-leds-and-gpios-in-a-qemu-emulation-like-t

A continuación, describo algunas configuraciones QEMU de bare metal que pueden ser interesantes: ¿Cómo crear programas ARM bare metal y ejecutarlos en QEMU? Escribir en el UART es la forma más fácil de obtener salida de QEMU.

Prima

Aquí hay un ejemplo de x86 para los curiosos: ¿Cómo ejecutar un programa sin un sistema operativo?