Подтвердить что ты не робот

Как запустить программу C без ОС на малиновой пи?

Я бы хотел поэкспериментировать с использованием малины Pi для некоторых различных низкоуровневых встроенных приложений. Единственная проблема заключается в том, что, в отличие от доступных микроконтроллеров AVR и PIC, Raspberry Pi обычно запускает ОС (например, Raspbian), который распределяет время процессора во всех запущенных программах и делает его нецелесообразным для определенных приложений реального времени.

Недавно я узнал, что, предполагая, что у вас установлен загрузчик, такой как GRUB, запуск программы на x86 (в форме ядра) занимает очень мало фактическая настройка, просто программа сборки для вызова основной функции и фактического кода C.

Есть ли способ достичь этого с помощью малины? Это был бы отличный способ узнать о программировании с низким уровнем ARM, и у него уже есть несколько сложных периферийных устройств, которые можно объединить с (USB, Ethernet и т.д.).

4b9b3361

Ответ 1

Хотя на Pi возможен голый металл, я бы избегал этого, так как Linux становится таким легким и обрабатывает целую кучу вещей для вас.

Вот учебник, который поможет вам начать, если вы хотите все еще изучать голые металлические вещи: http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

Со всем сказанным, я бы просто загрузил ваш любимый встроенный дистрибутив linux (исправление RT могло быть предпочтительным на основе ваших требований) и называть его хорошим.

Ответ 2

На самом деле малина Pi - одно из легких рук для программирования голого металла (без операционной системы). У меня есть много примеров в github, чтобы вы начали.

https://github.com/dwelch67/raspberrypi

Одна приятная вещь о малине pi заключается в том, что ей не нужен загрузчик, такой как uboot, есть gpu, который фактически приносит чип первым, тогда он загружает ядро ​​(или голеное металлическое приложение, что угодно) в ram и ветки в это так же, как и убут. Еще одна приятная вещь: вы не можете кирпича, как вы можете, с таким количеством других плат в этом классе, если вы испортите вам вытащить SD-карту, попробуйте еще раз, если вы сдаетесь, тогда положите на нее SD-карту с linux и запустить linux...

Ответ 3

Полностью автоматизированный пример с минимальным блинкером

Протестировано на хосте Ubuntu 16.04, Raspberry Pi 2.

dwelch - наиболее полный пример, но это минимально простой в настройке привет мир.

Использование:

  1. Вставьте SD-карту на хост

  2. Сделайте изображение:

    ./make.sh /dev/mmblck0 p1
    

    Куда:

    • /dev/mmblck0 - устройство SD-карты
    • p1 - первый раздел устройства (/dev/mmblck0p1)
  3. Вставьте SD-карту на PI

  4. Выключить и снова включить

enter image description here

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

start.S

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

main.c

#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"

QEMU дружественные примеры голого металла

Проблема с мигалкой заключается в том, что трудно наблюдать за светодиодами в QEMU: https://raspberrypi.stackexchange.com/questions/56373/is-it-possible-to-get-the-state-of-the-leds- и-GPIOs-в- для QEMU эмуляции, как-т

Здесь я опишу некоторые настройки QEMU для "голого метала", которые могут быть интересны: Как создавать ARM-программы для "голого метала" и запускать их в QEMU? Запись в UART - это самый простой способ получить выходные данные из QEMU.

бонус

Вот пример x86 для любопытных: Как запустить программу без операционной системы?

Ответ 4

https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ - отличный учебник, и, поскольку они расскажут вам, как быстро и грязно использовать код на голом металле, для захвата дистрибутива linux, для этого просто скомпилируйте kernel.img(с соответствующими параметрами архитектуры) и используйте его для замены существующего в дистрибутиве linux для этого раздела учебника вы можете перейти к: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html#pitime

Ответ 5

Pi может быть немного субоптимальным для того, что вы хотите сделать, поскольку дизайн SoC таков, что процессор ARM является гражданином второго сорта - это означает, что есть несколько обручей, чтобы перепрыгнуть, чтобы запустить запущенную металлическую программу на нем.

Однако вы можете немного обмануть и использовать U-Boot API, чтобы дать вам доступ к некоторым функций U-Boot, но вы можете добавить свои собственные функции на стороне.

Ответ 6

Вы можете скомпилировать паскаль для запуска непосредственно на Pi, используя Ultibo Core. Поиск Ultibo демо 1.0.0 на YouTube. Мы написали некоторые вещи для эмуляции адаптера elm327 с Ultibo на нуле Pi, и это работало очень хорошо.