I'm trying to light an LED connected to GPIO pin 12 using Assembly, I have a coursework where I have to implement the game of MasterMind using C and Assembly, so I've been trying to light up an LED using Assembly
.section .init
.globl _start
_start:
ldr r0,=0x3F200000 // Base adress from GPIO
// Set the GPIO pin 12 as output
mov r1,#1
lsl r1,#6
str r1,[r0,#0x4] // 0x3F200004 is the GPSEL1 Register, where you can choose the function for the pin
// Prepare the number used for turning the LED off and on
mov r1,#1
lsl r1,#12
// Main loop, loops all the letters (bl means branch with saving the current physical adress in the link register (lr) so you can jump back to it)
loop$:
bl morseS
bl morseO
bl morseS
b loop$
morseS:
mov r6,lr // Move the lr adress to r6 so you dont override it (would be better if implemented with stack)
bl dotBlink
bl dotBlink
bl dotBlink
bl delayMedium
mov lr,r6 // Move the adress back into the link register
bx lr
morseO:
mov r6,lr
bl dashBlink
bl dashBlink
bl dashBlink
bl delayMedium
mov lr,r6
bx lr
dotBlink:
mov r7,lr
str r1,[r0,#0x1C] // This turns the led on (According to the BCM2835 documentation the Register found at 0x3F20001C is GPSET0, so you can turn on the GPIO Pin 12 there
bl delayShort
str r1,[r0,#0x28] // This is GPCLR0, so used for turning the pin off again
bl delayShort
mov lr,r7
bx lr
dashBlink:
mov r7,lr
str r1,[r0,#0x1C]
bl delayLong
str r1,[r0,#0x28]
bl delayShort
mov lr,r7
bx lr
delayShort:
ldr r4,=0x3f003004 // Address for the timer of the Raspberry Pi
ldr r4,[r4] // Load the value from the timer
ldr r5,=0x30D40 // 200'000 micro seconds in hexadecimal
delayLoop1$:
ldr r3,=0x3F003004
ldr r3,[r3] // Load new timer value
sub r3,r3,r4 // Save time passed since the beginning of subroutine in r3
cmp r3,r5 // Compare
blt delayLoop1$ // If difference is smaller than 200ms go to the delay loop again
bx lr // If time has passed return from function
delayMedium:
ldr r4,=0x3f003004
ldr r4,[r4]
ldr r5,=0x61A80
delayLoop3$:
ldr r3,=0x3F003004
ldr r3,[r3]
sub r3,r3,r4
cmp r3,r5
blt delayLoop3$
bx lr
delayLong:
ldr r4,=0x3f003004
ldr r4,[r4]
ldr r5,=0x927C0
delayLoop2$:
ldr r3,=0x3F003004
ldr r3,[r3]
sub r3,r3,r4
cmp r3,r5
blt delayLoop2$
bx lr
This is the code I have, I think it seems fine and I tried compiling it using
as -o testled.o testled.s
ld -o testled testled.o
sudo ./testled
and it gives a segmentation error, can someone please help me with this?
This program is written to run without an operating system with direct access to physical address space but you are running it on Linux which configures virtual memory.
Under Linux the physical address is in the file
/dev/mem, and specifically the gpio registers are also in/dev/gpiomem. To use these files open them then you can obtain a virtual address using the mmap system call.For example in C:
However I would expect attempting to access the timer like that will result in chaos as the operating system will be using the timer.
Linux also provides a high level interface to the gpio using files in
/sys/class/gpio.