我对将Raspberry Pi用作纯嵌入式CPU单元来开发嵌入式应用程序感兴趣。由于Raspberry Pi具有功能强大的CPU和相当多的内存,因此它是出色的嵌入式板。
是否可以在没有Linux操作系统的情况下使用Raspberry Pi?我怎样才能做到这一点?
我对将Raspberry Pi用作纯嵌入式CPU单元来开发嵌入式应用程序感兴趣。由于Raspberry Pi具有功能强大的CPU和相当多的内存,因此它是出色的嵌入式板。
是否可以在没有Linux操作系统的情况下使用Raspberry Pi?我怎样才能做到这一点?
Answers:
我研究了Raspberry Pi上的裸机编程,这听起来像您想要做的。论坛上有一些关于裸机编程的好话题,有些人为使代码正常工作付出了很多努力。查看这些以开始使用:
或者通常,您可以转到Raspberry Pi的Bare Metal Forum并浏览。
我的理解是,由于Broadcom芯片内置的启动顺序,您将必须从SD卡启动。我正在尝试查找启动顺序的链接,但我的Google Fu无法正常工作,如果找到,我将在稍后进行编辑。
引导它的唯一方法是从fat32格式的sdcard启动,从加电到gpu固件加载,执行任何名为kernel.img的arm二进制文件,因此,如果您要创建一个自定义内核,可以执行其所要执行的任务这一点
我已经用C#创建了一个IBM S / 390模拟器,理论上它将在Mono / Linux下运行,因为它可以编译为CIL代码并且不使用任何不受支持的.NET资源。这将允许嵌入式解决方案使用与平台无关的控制表和自定义有限状态机解释器。但是,它在后台仍将具有基本的Linux O / S。
全自动的最小裸机信号灯示例
在Ubuntu 16.04主机Raspberry Pi 2上进行了测试。
在主机上插入SD卡
制作图像:
./make.sh /dev/mmblck0 p1
哪里:
/dev/mmblck0
是SD卡的设备p1
是设备的第一个分区(/dev/mmblck0p1
)在PI上插入SD卡
关闭电源然后再打开
GitHub上游:https : //github.com/cirosantilli/raspberry-pi-bare-metal-blinker/tree/d20f0337189641824b3ad5e4a688aa91e13fd764
开始
.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. */
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; }
}
}
脚本
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"