3

I am stuck and hoping for a clue. These lines seem to show the issue. It is for a Pi4.

.equ IOBASE, 0x7E200000

.equ GPFSEL2, 0x08 //offset to reg for IO Pins 20 - 29

.align 4

LDR R0, =IOBASE

//skip read modify write for now, just set the bits

LDR R1, =0x08

STR R1, [R0, #GPFSEL2] //Make Pin 21 output

It all assembles, compiles without warning or error, but I get a seg. fault at every STR operation when running. Makes no difference if I log in as pi or su. Using a high level language and/or a package like pigpio would defeat the purpose.

Any ideas?

Dirk
  • 3,541
  • 3
  • 18
  • 25
Sarge
  • 31
  • 3
  • Well, I would start troubleshooting with (1) a very small IOBASE, (2) GPFSEL2 = 0x00 instead of 0x08, just to narrow down the trouble making area. Seg fault sometimes relates to free memory, but in your case I think adjusting swapping memory won't help. – tlfong01 Apr 26 '20 at 05:29
  • 1
    you are trying to run bare metal code in a userland with MMU between you and hardware. Take a look at this and at this – Maxim Sagaydachny Apr 26 '20 at 05:47
  • Hi @Sarge, forget my amateurish troubleshooting suggestions. I have almost zero experience with MMU or ARM assembly programming. Cheers. – tlfong01 Apr 26 '20 at 06:56

1 Answers1

3

You get the error because you didn't map the IOBASE address range to your process' address space. Accessing an unallocated address is exactly what a SEGFAULT is.

Check the source code of any GPIO library init function to see how to map an address range. One example would be initMapMem() from pigpio.

Dmitry Grigoryev
  • 27,928
  • 6
  • 53
  • 144
  • 1
    Thanks Dmitry & Maxim. I understand the problem now, if not entirely the solution. It’s a rather different world for a hardware engineer. – Sarge Apr 26 '20 at 17:31
  • 3
    Simply put, you can't access any hardware on Linux without requesting access from the kernel. Doing it 100% in assembly will not be easy. My advice would be to switch to C and use its system library. – Dmitry Grigoryev Apr 26 '20 at 20:47