Pull to refresh

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

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

Эта статья написана мной после прочтения публикации «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!
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.