36

I'm interested in using the Raspberry Pi as a pure embedded CPU unit, for the development of embedded applications. Since the Raspberry Pi has a powerful CPU with quite a bit of memory, it makes an excellent embedded board.

Is it possible to use the Raspberry Pi without a Linux OS? How can I do this?

iconoclast
  • 105
  • 3
FarhadA
  • 1,837
  • 2
  • 16
  • 20
  • 2
    I don't think this is a real question and not a good fit for the Q&A format. – Alex Chamberlain Jun 20 '12 at 07:14
  • 5
    Why not? You don't think people can ask about using RaPi any way other than with a Linux OS? Where in the list of the bylaws of this group is there a section that says one can not ask such questions? – FarhadA Jun 20 '12 at 08:06
  • 2
    I didn't say that. I actually think it would be quite cool to see some projects that didn't use Linux, but you didn't actually ask a question with a definitive answer, rather you made a discussion point. – Alex Chamberlain Jun 20 '12 at 08:09
  • @AlexChamberlain I agree - I've edited it into a question. FarhadA - I hope this is ok, in it's current state it would be closed. Please review and improve my edit! – Alex L Jun 20 '12 at 08:10
  • Ok, true, I have to make it a question, since this is a Q&A site :) – FarhadA Jun 20 '12 at 08:18
  • Removed my downvote. – Alex Chamberlain Jun 20 '12 at 08:38
  • Forgive my embedded systems ignorance. Can you explain to me how this is useful? – Jivings Jun 20 '12 at 10:22
  • For simple tasks where you don't need an OS of graphics, you can just write the code in simple C if the correct libraries are there, then you can control your application via the GPIO or other IOs on the board. – FarhadA Jun 20 '12 at 10:30
  • Do you have any further information related to this topic, because I'm also interested in. – Mokus Jul 10 '12 at 20:36

4 Answers4

24

I've looked into bare metal programming on the Raspberry Pi and it sounds like what you want to do. There are several good forum topics about bare metal programming with some people who have put in a lot of effort to get their code to work. Check these out for getting started:

Guide to Beginning Bare Metal on Raspi

Programming the RPi on the bare metal

Programming in Basic on Bare Metal Tutorial 1

or in general you can go to Raspberry Pi's Bare Metal Forum and just browse around.

My understanding is that you will have to boot from the SD card due to the boot sequence built into the Broadcom chip. I'm trying to find the link for the boot sequence but my google fu isn't working, I'll edit later if I find it.

Dan B
  • 2,907
  • 2
  • 20
  • 20
  • 3
    In addition, you could use this tutorial: http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/ it's about building an operating system, but if you extend your idea of an operating system, it can be applied to embedded systems. – ohblahitsme Sep 05 '12 at 20:07
6

the only way it will boot is from a fat32 formatted sdcard, goes from poweron to gpu firmware loading that executes any arm binary file named kernel.img so if you want to make a custom kernel that does whatever it is you are looking to do its at this point

joe
  • 69
  • 1
  • 3
    Yes, but that is not what I want to do, I would like to know if it is possible to change the boot code of the chip so instead of going to SD card to look for the boot image, it can be changed to go to a SPI flash memoery and boot from there instead. This way, the boot code can be on a SPI flash memory like AT25FS040 or AT25DF641 or other similar units. For embedded applications, those are enough to store all the code, and they can be loaded into SDRAM after boot. but the big challenge is to change the boot ROM code. – FarhadA Jun 21 '12 at 07:33
  • 9
    That's not what you asked in your question at all. – Alistair Buxton Jun 21 '12 at 18:10
  • I know, but my knowledge of the RaPi boot sequence is limited, I had the proper question in my original question before it was voted down and edited to this current format. – FarhadA Jun 22 '12 at 07:44
  • 2
    @FarhadA - Your first comment here looks to me like it would stand as a practical, answerable question in it's own right. It would certainly be better that the original form of this question. – Mark Booth Jul 10 '12 at 16:56
  • Well, as I said my knowledge of RasPi boot sequence is limited. I am leaning toward creating a simple boot file on SD card and load the application from a SPI based flash on my own expansion board. I really don't like having the SD card in my system, but it seems to be the only quick and dirty way of doing so. Now I need to learn how to create a simple boot code for RasPi :) – FarhadA Jul 11 '12 at 08:59
4

I have created an IBM S/390 emulator in C# that theoretically will run under Mono/Linux as it compiles to CIL code and doesn't use any non-supported .NET resources. This will allow embedded solutions using platform independent control tables with a custom finite state machine interpreter. It would still have essential Linux O/S in the background though.

3

Fully automated minimal bare metal blinker example

Tested on Ubuntu 16.04 host, Raspberry Pi 2. Usage:

  1. Insert SD card on host

  2. Make the image:

    ./make.sh /dev/mmblck0 p1
    

    Where:

    • /dev/mmblck0 is the device of the SD card
    • p1 is the first partition of the device (/dev/mmblck0p1)
  3. Inset SD card on PI

  4. Turn power off and on

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. */
    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"