Nejprve je potřeba provést inicializaci procesoru, k tomu slouží kód v start.s, tento kód jsem příliš nemodifikoval a využil přebraný z https://raw.githubusercontent.com/dwelch67/raspberrypi/066f219ada52cf8c6990589566d06318ce2de5c7/boards/pi3/aarch32/SVC/README.
Všechno potřebné je na mém Gitu, viz odkaz níže.
Dále zde bude podstatný vektor přerušení, ale to předbíhám. Nyní nás zajímá pouze řádek s "bl notmain", který obsahuje instrukci skoku (branch and link) na funkci main (ze zvyku jsem si ji přejmenoval). A pak už žijeme s programování v jazyce C. Takže si nadefinujeme registry pro GPIO piny v souboru GPIO.h (starší verze Raspberry Pi mají registry na jiné adrese, tak tedy 0x20200000 a také se u nich pouští kernel.img).
#ifndef __GPIO_H
#define __GPIO_H
#define GPIO_BASE 0x3F200000
typedef struct
{
volatile unsigned int GPFSEL0; /*!< GPIO Function Select 0 */
volatile unsigned int GPFSEL1; /*!< GPIO Function Select 1 */
volatile unsigned int GPFSEL2; /*!< GPIO Function Select 2 */
volatile unsigned int GPFSEL3; /*!< GPIO Function Select 3 */
volatile unsigned int GPFSEL4; /*!< GPIO Function Select 4 */
volatile unsigned int GPFSEL5; /*!< GPIO Function Select 5 */
volatile unsigned int nic0;
volatile unsigned int GPSET0; /*!< GPIO Pin Output Set 0 */
volatile unsigned int GPSET1; /*!< GPIO Pin Output Set 1 */
volatile unsigned int nic1;
volatile unsigned int GPCLR0; /*!< GPIO Pin Output Clear 0 */
volatile unsigned int GPCLR1; /*!< GPIO Pin Output Clear 1 */
volatile unsigned int nic2;
volatile unsigned int GPLEV0; /*!< GPIO Pin Level 0 */
volatile unsigned int GPLEV1; /*!< GPIO Pin Level 1 */
volatile unsigned int nic3;
volatile unsigned int GPEDS0; /*!< GPIO Pin Event Detect Status 0 */
volatile unsigned int GPEDS1; /*!< GPIO Pin Event Detect Status 1 */
volatile unsigned int nic4;
volatile unsigned int GPREN0; /*!< GPIO Pin Rising Edge Detect Enable
0 */
volatile unsigned int GPREN1; /*!< GPIO Pin Rising Edge Detect Enable
1 */
volatile unsigned int nic5;
volatile unsigned int GPFEN0; /*!< GPIO Pin Falling Edge Detect Enable
0 */
volatile unsigned int GPFEN1; /*!< GPIO Pin Falling Edge Detect Enable
1 */
volatile unsigned int nic6;
volatile unsigned int GPHEN0; /*!< GPIO Pin High Detect Enable 0 */
volatile unsigned int GPHEN1; /*!< GPIO Pin High Detect Enable 1 */
volatile unsigned int nic7;
volatile unsigned int GPLEN0; /*!< GPIO Pin Low Detect Enable 0 */
volatile unsigned int GPLEN1; /*!< GPIO Pin Low Detect Enable 1 */
volatile unsigned int nic8;
volatile unsigned int GPAREN0; /*!< GPIO Pin Async. Rising Edge Detect
0 */
volatile unsigned int GPAREN1; /*!< GPIO Pin Async. Rising Edge Detect
1 */
volatile unsigned int nic9;
volatile unsigned int GPAFEN0; /*!< GPIO Pin Async. Falling Edge Detect
0 */
volatile unsigned int GPAFEN1; /*!< GPIO Pin Async. Falling Edge Detect
1 */
volatile unsigned int nic10;
volatile unsigned int GPPUD; /*!< GPIO Pin Pull-up/down Enable */
volatile unsigned int GPPUDCLK0; /*!< GPIO Pin Pull-up/down Enable Clock
0 */
volatile unsigned int GPPUDCLK1; /*!< GPIO Pin Pull-up/down Enable Clock
1 */
volatile unsigned int nic11;
volatile unsigned int Test;
} GPIO_TypeDef;
#endif
MEMORY { ram : ORIGIN = 0x8000, LENGTH = 0x10000 } SECTIONS { .text : { *(.text*) } > ram .bss : { *(.bss*) } > ram }
#include "GPIO.h"
GPIO_TypeDef *GPIO;
int main(void)
{
GPIO = (GPIO_TypeDef*)GPIO_BASE;
GPIO->GPFSEL1 |= 1UL << 18; // GPIO16 OUT - LED
GPIO->GPSET0 |= 1UL << 16; // GPIO16 SET - LED switch on
while(1){}
}
Vše co je nyní potřeba udělat, je spustit následující příkazy. Překlad assembleru, překlad céčkového souboru, slinkování a vytvoření binárky. Pak binárku překopírujeme na SD kartu do /boot/ jako .img, soubor kernel, který Raspberry Pi po startu pouští a provedeme restart.
arm-none-eabi-as start.s -o start.o
arm-none-eabi-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -c main.c -o main.o
arm-none-eabi-ld start.o main.o -T memmap -o main.elf
arm-none-eabi-objdump -D main.elf > main.list
arm-none-eabi-objcopy main.elf -O binary main.bin
sudo cp main.bin /boot/kernel7.img
sudo reboot
ARMGNU
?= arm-none-eabi
#ARMGNU ?= arm-linux-gnueabi
COPS = -Wall -O2 -nostdlib
-nostartfiles -ffreestanding
gcc : main.bin
all : gcc clang
clean :
rm -f *.o
rm -f *.bin
rm -f *.hex
rm -f *.elf
rm -f *.list
rm -f *.img
rm -f *.bc
rm -f *.clang.s
start.o : start.s
$(ARMGNU)-as start.s -o start.o
main.o : main.c
$(ARMGNU)-gcc $(COPS) -c main.c -o main.o
main.bin : memmap start.o main.o
$(ARMGNU)-ld start.o main.o -T memmap -o main.elf
$(ARMGNU)-objdump -D main.elf > main.list
$(ARMGNU)-objcopy main.elf -O ihex main.hex
$(ARMGNU)-objcopy main.elf -O binary main.bin
sudo cp main.bin
/boot/kernel7.img
sudo reboot
LOPS = -Wall -m32 -emit-llvm
LLCOPS0 = -march=arm
LLCOPS1 = -march=arm -mcpu=arm1176jzf-s
LLCOPS = $(LLCOPS1)
COPS = -Wall -O2 -nostdlib
-nostartfiles -ffreestanding
OOPS = -std-compile-opts
clang : main.clang.bin
main.bc : main.c
clang $(LOPS) -c main.c -o main.bc
main.clang.elf : memmap start.o main.bc
llvm-link main.bc -o main.nopt.bc
opt $(OOPS) main.nopt.bc -o main.opt.bc
llc $(LLCOPS) main.opt.bc -o main.clang.s
$(ARMGNU)-as main.clang.s -o main.clang.o
$(ARMGNU)-ld -o main.clang.elf -T memmap start.o
main.clang.o
$(ARMGNU)-objdump -D main.clang.elf >
main.clang.list
main.clang.bin : main.clang.elf
$(ARMGNU)-objcopy main.clang.elf main.clang.hex -O
ihex
$(ARMGNU)-objcopy main.clang.elf main.clang.bin -O
binary
Žádné komentáře:
Okomentovat