我对将Raspberry Pi用作纯嵌入式CPU单元来开发嵌入式应用程序感兴趣。由于Raspberry Pi具有功能强大的CPU和相当多的内存,因此它是出色的嵌入式板。我该怎么办?

评论

我认为这不是一个真正的问题,也不适合问答格式。

为什么不?您认为除了Linux操作系统外,人们不会问使用RaPi的任何方式吗?在该组章程的列表中,有什么地方说不能问这样的问题?

我没那么说我实际上认为看到一些未使用Linux的项目会很酷,但是您实际上并没有提出明确的答案,而是提出了讨论要点。

@AlexChamberlain我同意-我已将其编辑为一个问题。 FarhadA-我希望这样可以,因为在当前状态下它将关闭。请查看并改进我的修改!

好的,是的,我必须提出一个问题,因为这是一个问答网站:)

#1 楼

我研究了Raspberry Pi上的裸机编程,这听起来像您想要做的。论坛上有一些关于裸机编程的好话题,有些人为使代码正常工作付出了很多努力。请查看以下这些入门指南:

在Raspi上开始裸金属的指南

在裸机上编程RPi

在Basic上进行Basic编程Metal教程1

或通常来说,您可以去Raspberry Pi的Bare Metal Forum并浏览一下。到Broadcom芯片内置的启动顺序。我正在尝试查找启动顺序的链接,但我的Google Fu无法正常工作,如果找到它,请稍后进行编辑。

评论


此外,您可以使用本教程:cl.cam.ac.uk/freshers/raspberrypi/tutorials/os是关于构建操作系统的信息,但是如果您扩展了操作系统的概念,则可以将其应用于嵌入式系统。

– ohblahitsme
2012年9月5日于20:07

#2 楼

引导它的唯一方法是从fat32格式的sdcard启动,从加电到gpu固件加载,执行任何名为kernel.img的arm二进制文件,因此,如果您要创建一个自定义内核,可以执行其所要执行的任务此时

评论


是的,但是那不是我想要做的,我想知道是否可以更改芯片的启动代码,因此无需转到SD卡来查找启动映像,而是可以将其更改为SPI Flash备忘录,然后从那里引导。这样,引导代码可以位于SPI闪存中,例如AT25FS040或AT25DF641或其他类似单元。对于嵌入式应用程序,它们足以存储所有代码,并且可以在引导后将其加载到SDRAM中。但是最大的挑战是更改引导ROM代码。

– FarhadA
2012年6月21日7:33



那根本不是您在问题中问的。

–阿利斯泰尔·巴克斯顿
2012年6月21日18:10

我知道,但是我对RaPi引导顺序的了解有限,在我对原始问题进行表决并将其编辑为当前格式之前,我曾有一个适当的问题。

– FarhadA
2012年6月22日7:44

@FarhadA-在我看来,您的第一个评论就其本身而言,将是一个切实可行的可回答问题。这个问题的原始形式肯定会更好。

– Mark Booth
2012年7月10日在16:56



好吧,正如我所说,我对RasPi引导顺序的了解是有限的。我倾向于在S​​D卡上创建一个简单的启动文件,并在自己的扩展板上从基于SPI的闪存加载应用程序。我真的不喜欢在系统中安装SD卡,但这似乎是唯一快捷而又肮脏的方法。现在,我需要学习如何为RasPi创建简单的启动代码:)

– FarhadA
2012年7月11日在8:59



#3 楼

我已经用C#创建了一个IBM S / 390模拟器,理论上它将在Mono / Linux下运行,因为它可以编译为CIL代码并且不使用任何不受支持的.NET资源。这将允许嵌入式解决方案使用与平台无关的控制表和自定义有限状态机解释器。但是,它仍然在后台具有基本的Linux O / S。

#4 楼

全自动的最小裸机信号灯示例

在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

开始。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. */
    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
}

< br makemake.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"