/dev/gpiomem error for BaremetalPi (Mmap.mmap regression)

On a Raspberry PI 4 with 8 gig memory, I have upgraded the OS to Bookworm. Now when I execute the function init_gpio()
it gives me the error Could not map /dev/gpiomem . Make sure you have the required permissions.

When I look at the permissions of /dev/gpiomem, it is rw-rw----. I changed this to rw-rw-rw- to no avail. When I reboot the PI it goes back to the original permissions of rw-rw----.

This function was working on the previous OS, so that may be an option. Anything that I am overlooking? Perhaps @Ronis_BR can help.

1 Like

Some further research shows that /dev/gpiomem is part of the gpio group. The user name also has gpio as one of the groups it belongs to.

Hi! I have no idea! I always tested everything in the RPI using root.

Initially I thought the error may have something to do with the upgrade in OS from Bullseye to Bookworm. This turns out not to be the case.

Some internet searching indicates that gpio should be a member of the group logged in (use the groups command to find out). This seems to be the case by default. Also I did all testing as a normal user, not as root.

In using Bullseye, I went back to Julia 1.10.0, and the error is not present. Then I tried Julia 1.10.2 and the error is present. The error occurs in the line with the function call Mmap.mmap in the function init_gpio(), shown below, in BaremetalPi file gpio.jl, so it seems that the Mmap function call has changed.

Is this something that an issue should be raised for?

"""
    init_gpio()

Initialize the GPIO.
"""
function init_gpio()
    # Open and map /dev/gpiomem.
    try
        gpiomem_io  = open("/dev/gpiomem", "w+")
        gpiomem_map = Mmap.mmap(
            gpiomem_io,
            Vector{UInt32},
            (GPIOMEM_SIZE,),
            0,
            grow = false
        )

        objects.gpiomem_io  = gpiomem_io
        objects.gpiomem_map = gpiomem_map
        objects.gpio_init   = true
    catch
        error("Could not map `/dev/gpiomem`. Make sure you have the required permissions.")
    end

    return nothing
end

edit: I added to the title to more accurately reflect the problem

To see what the actual error is, copy paste first 2 function calls to julia repl. Otherwise, you see the error thrown in the catch block and it suppresses the one in try block.

Using a Raspberry PI 4, the output from Julia 1.10.0 is

julia> versioninfo()
Julia Version 1.10.0
Commit 3120989f39b (2023-12-25 18:01 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (aarch64-linux-gnu)
  CPU: 4 Ã Cortex-A72
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, cortex-a72)
  Threads: 1 on 4 virtual cores

julia> using Mmap

julia> io = open("/dev/gpiomem", "w+")
IOStream(<file /dev/gpiomem>)

julia> gpiomap = Mmap.mmap(io, Vector{UInt32}, (1024,), 0, grow=false)
1024-element Vector{UInt32}:
 0x21200900
 0x00040264
 0x12040000
 0x3fffffff
 0x00000064
 0x00000000
 0x00000000
 0x6770696f
 0x6770696f
 0x6770696f
          â®
 0x6770696f
 0x6770696f
 0x6770696f
 0x6770696f
 0x6770696f
 0x6770696f
 0x6770696f
 0x6770696f
 0x6770696f

julia> 

and from Julia 1.10.1

julia> versioninfo
versioninfo (generic function with 2 methods)

julia> versioninfo()
Julia Version 1.10.1
Commit 7790d6f0641 (2024-02-13 20:41 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (aarch64-linux-gnu)
  CPU: 4 Ã Cortex-A72
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, cortex-a72)
Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)

julia> using Mmap

julia> io = open("/dev/gpiomem", "w+")
IOStream(<file /dev/gpiomem>)

julia> gpiomap = Mmap.mmap(io, Vector{UInt32}, (1024,), 0, grow=false)
ERROR: IOError: filesize: Illegal seek for <file /dev/gpiomem>
Stacktrace:
 [1] filesize(s::IOStream)
   @ Base ./iostream.jl:226
 [2] mmap(io::IOStream, ::Type{Vector{UInt32}}, dims::Tuple{Int64}, offset::Int64; grow::Bool, shared::Bool)
   @ Mmap ~/.julia/juliaup/julia-1.10.1+0.aarch64.linux.gnu/share/julia/stdlib/v1.10/Mmap/src/Mmap.jl:215
 [3] top-level scope
   @ REPL[4]:1

julia> 

edit: I filed a bug report for Mmap, hopefully I did it correctly. Letting @Ronis_BR know, as it affects BaremetalPI.

I’m pretty sure the regression is due to 🐛 fix bus error on smaller readonly file in unix by xgdgsc · Pull Request #44354 · JuliaLang/julia · GitHub as I noted on the issue. The call to filesize introduced there is not appropriate in all cases.

OK. How many bytes can you actually read on the /dev/gpiomem and how many bytes filesize reports? If the filesize result matches correct size then 1024 is very long to request. Small internet search showed that people use 0xB4 for mmap block size. Nevermind, I found some uses 4096 so it might be different thing then I thought. Maybe, GPIOMEM_SIZE is not set to the correct value.

Thanks @Jake !

I will only have access to a Raspeberry Pi this weekend to test. However, I have no ideia if there is any workaround. Let’s see what the devs say in that issue.