I've posted a more generic version of this question on Stack Overflow, but since I've had no response I'm hoping someone over this side might have an idea.

I've been working on a project in PHP which requires mmap'ing /dev/mem to gain access to the hardware peripheral registers. As there's no native mmap, I have implemented a python subprocess, which communicates with the PHP app via stdin/stdout.

Strangely, everything works as expected for writing, but when it comes to reading, I have a weird issue where the data coming back is


for as many bytes as I read. It seems to me like it's no coincidence that this is in the GPIO register address space, since I have seen different repeating patterns in other address spaces.

The unusual thing is that this only occurs with mem.read(). The workaround I have is by using struct.unpack_from(), then packing it again with struct.pack(). It's slow and ugly.

sys.stdout.write(str(struct.pack('L', struct.unpack_from('L', mem, mem.tell())[0])))

From what I understood, both of those functions should be treating the stream in the same way - apparently they don't!

It's quite possible that I'm doing something completely stupid, but if someone could point it out that'd be great!

The file that contains the above issue is here. The project that uses it is here.


To see the issue, I've got some test code like this:

fd = os.open("/dev/mem", os.O_RDWR | os.O_SYNC)
mem = mmap.mmap(fd, 4096, offset=0x3f200000)

bytes_read = mem.read(4)
print bytes_read

bytes_unpack_pack = struct.pack('L', struct.unpack_from('L', mem, mem.tell())[0])
print bytes_unpack_pack

Which outputs


Should they not be the same?

  • The file link just points to another question. I think you get the peripheral name (gpio) when you read a write only address or a reserved address within the peripheral address space. – joan Oct 13 '16 at 15:10
  • Sorry about that, I misaligned the link number. You're actually just the person I thought might be able to help! Can you think of any reason then that it'd work fine one way and not the other? The standard mem.read() reads exactly the same bytes as the unpack_from() code if I map an ordinary file. – calcinai Oct 13 '16 at 15:14
  • Are you sure it's not something like using a byte offset to access a word indexed address, so you'b be trying to access word[x*4] instead of word[x]. That would account for 'gpio' being returned from invalid addresses. – joan Oct 13 '16 at 16:46
  • I'm not sure about that - I seem to recall that I wasn't that far off, like the first byte was ok but not the second - I'll have to test that again tomorrow and let you know. Thanks for your response. – calcinai Oct 13 '16 at 18:02
  • I've done some testing and added and example to reproduce – calcinai Oct 14 '16 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.