Мигаем диодиком на Raspberry Pi с помощью ассемблера

в 11:47, , рубрики: Песочница, метки: , , ,

Здравствуйте, уважаемые читатели!

Эта статья написана мной после прочтения публикации «Baking Pi – Operating Systems Development» — очень хорошего курса по азам ассемблера для ARM на примере RasPI.

Надеюсь, будет интересно, так что добро пожаловать под кат.

Итак, приступаем.

Сперва форматируем SD-карту (строго в FAT32!!!), только не забудьте сделать бекап.
Затем ставим всё необходимое для компиляции под ARM:

sudo apt-get install binutils-arm-none-eabi

Создаём где-нибудь директорию, где мы будем работать и переходим в нее.
В ней делаем еще src и build, а потом пишем Makefile:

PREFIX = arm-none-eabi-

all:
	$(PREFIX)as src/*.s -o build/kernel.o -I src/
	$(PREFIX)objcopy -O binary build/kernel.o build/kernel.img
	rm -f build/*.o

clean:
	rm -f build/*

Теперь заходим в src и создаём ассемблерный файл, например main.s.

.offset 0x8000 // бутлоадер поместил наш код по адресу 0x8000
.text          // секция кода

b __main // безусловный переход
init_gpio:

push {lr} // в lr - адрес возврата
push {r0}
push {r1}
ldr r0, =0x20200000      // r0 := 0x20200000 (адрес контроллера GPIO)
mov r1, #1
lsl r1, #18              // r1 <<<= 18;
str r1, [r0, #4]         // memory[r0+4] = r1
pop {r1}
pop {r0}
pop {pc} // мы ставим указатель инструкции на адрес возврата

led_on:
push {lr}
push {r0}
push {r1}
ldr r0, =0x20200000
mov r1, #1               // r1 = 1
lsl r1, #16              // r1 <<<= 16
str r1, [r0, #40]        // memory[r0+40] = r1
pop {r1}
pop {r0}
pop {pc}

led_off:
push {lr}
push {r0}
push {r1}
ldr r0, =0x20200000
mov r1, #1               // r1 = 1
lsl r1, #16              // r1 <<<= 16
str r1, [r0, #28]        // memory[r0+28] = r1
pop {r1}
pop {r0}
pop {pc}

sleep: // плохой способ для задержки
push {lr}
push {r0}

mov r0, #1048576 // for(r0 = 1048576; r0 != 0; r0--){
__sleep_loop:    // ...
sub r0, #1       // ...
cmp r0, #0       // ...
bne __sleep_loop // }

pop {r0}
pop {pc}


__main:
mov r1, #1048576 // r1 := 1048576
mov r2, #0       // ...

bl init_gpio     // переход, в регистре lr - адрес возврата

__loop_:
bl led_on
bl sleep
bl led_off
bl sleep
add r2, #1  // r2 += 1
cmp r2, #10 // мигнем 10 раз
bne __loop_ // переход, если не равно

__halt: b __halt // глухой цикл

Переходим в предыдущую директорию и собираем наше «ядро»:

make

Если всё прошло удачно, копируем полученный файл kernel.img из build/ в корень SD-шки.

Стоп! Нам ещё нужен бутлоадер, он проприетарный, добыть его можно тут.

Нам нужны файлы start.elf, fixup.dat, bootcode.bin.
Копируем их в корень свежеотформатированной (см. выше) SD-карты.
А теперь самое интересное, отмонтируем карту, вставим её в RasPI и подключим питаниие.

Вуаля!

Если горит красный диод PWR, но ACT/OK светится тускло и даже не хочет мигать, попробуйте пошатать карточку в разъёме и переподключить Raspberry к питанию.

Спасибо за прочтение, удачи вам в ваших следующих опытах с RasPI!

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js