First RPi2 bare metal code

First bare metal code for Raspberry Pi2 hardware uploaded at https://github.com/sokoide/rpi-baremetal/tree/master/001_led.
Used http://www.valvers.com/open-software/raspberry-pi/step02-bare-metal-programming-in-c-pt2/ for GPIO port definition for RPi2 and http://tatsu-zine.com/books/raspi-bm for section def & boot startup code.

When the hardware starts up, it halts CPU and starts GPU which loads bootloader from ROM which loads bootcode.bin which reads config.txt. Start.elf loads the boot image file written in config.txt at 0x00008000 and runs it.
When you build it, you’ll get hoge.img which is loaded and executed by start.elf during boot and see a blinking green LED at fast, regular, slow, regular, fast… paces.

Here is my first bare metal code which is only 480 bytes.

hoge.lds:

OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
	. = 0x8000;

	.text : { *(.text*) }
	. = ALIGN(4);

	__rodata_start = .;
	.rodata : { *(.data*) }
	. = ALIGN(4);
	__rodata_end = .;

	__data_start = . ;
	.data : { *(.data*) }
	. = ALIGN(4);
	__data_end = . ;

	__bss_start = . ;
	.bss : { *(.bss*) }
	. = ALIGN(4);
	__bss_end = . ;
}

startup.s: in supervisor mode (d3), using 1MB stack at 0x06400000 although I don’t need that much.

@ startup
  .global _start
  .align

_start:
  ldr r0, =0x000000d3
  msr cpsr, r0
  ldr sp, =0x06400000
  bl main
  b .

hoge.c:

#include "lib/rpi.h"
#define kFastInterval 200000
#define kRegularInterval 500000
#define kSlowInterval 1000000

volatile unsigned int* gpio = (unsigned int*)GPIO_BASE;
volatile unsigned int tim;

void wait(unsigned int interval);

void wait(unsigned int interval) {
  for (tim = 0; tim < interval; tim++)
    ;
}

void led_on() {
  /* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on
     for plus models )*/
  gpio[LED_GPSET] = (1 << LED_GPIO_BIT);
}

void led_off() {
  /* Set the LED GPIO pin low ( Turn OK LED on for original Pi, and off
     for plus models )*/
  gpio[LED_GPCLR] = (1 << LED_GPIO_BIT);
}

int main(int argc, char const* argv[]) {
  rpiInit();

  gpio[LED_GPFSEL] |= (1 << LED_GPFBIT);

  unsigned int intervals[] = {kFastInterval, kRegularInterval, kSlowInterval,
                              kRegularInterval};
  while (1) {
    for (int i = 0; i < sizeof(intervals) / sizeof(intervals[0]); i++) {
      unsigned int interval = intervals[i];
      {
        for (int j = 0; j < 3; j++) {
          wait(interval);
          led_on();
          wait(interval);
          led_off();
        }
      }
    }
  }

  return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *