MMIO module for the Linux userspace /dev/mem
device.
local periphery = require('periphery')
local MMIO = periphery.MMIO
-- Constructor
mmio = MMIO(address <number>, size <number>)
mmio = MMIO{address=<number>, size=<number>, path="/dev/mem"}
-- Methods
mmio:read32(offset <number>) --> <number>
mmio:read16(offset <number>) --> <number>
mmio:read8(offset <number>) --> <number>
mmio:read(offset <number>, length <number>) --> <table>
mmio:write32(offset <number>, value <number>)
mmio:write16(offset <number>, value <number>)
mmio:write8(offset <number>, value <number>)
mmio:write(offset <number>, data <table>)
mmio:close()
-- Properties
mmio.base immutable <number>
mmio.size immutable <number>
MMIO(address <number>, size <number>) --> <MMIO Object>
MMIO{address=<number>, size=<number>, path="/dev/mem"} --> <MMIO Object>
Instantiate an MMIO object and map in the region of physical memory specified by the address
base physical address and size
size in bytes. The default memory character device /dev/mem
can be overridden with the table constructor, for use with sandboxed memory character devices, e.g. /dev/gpiomem
.
Example:
mmio = MMIO(0x40000000, 4096)
mmio = MMIO{address=0x40001000, size=0x1000, path="/dev/gpiomem"}
Returns a new MMIO object on success. Raises an MMIO error on failure.
mmio:read32(offset <number>) --> <number>
mmio:read16(offset <number>) --> <number>
mmio:read8(offset <number>) --> <number>
Read 32-bits, 16-bits, or 8-bits, respectively, from the mapped physical memory, starting at the specified byte offset, relative to the base physical address the MMIO object was opened with.
Returns the read unsigned integer on success. Raises an MMIO error on failure.
mmio:read(offset <number>, length <number>) --> <table>
Read an array of bytes from the mapped physical memory, starting at the specified byte offset, relative to the base physical address the MMIO object was opened with.
Example:
data = mmio:read(0x100, 4)
-- data is {0xff, 0xff, 0xff, 0xff}
Returns the read bytes in a table array. Raises an MMIO error on failure.
mmio:write32(offset <number>, value <number>)
mmio:write16(offset <number>, value <number>)
mmio:write8(offset <number>, value <number>)
Write 32-bits, 16-bits, or 8-bits, respectively, to mapped physical memory, starting at the specified byte offset, relative to the base physical address the MMIO object was opened with.
Raises an MMIO error on failure.
mmio:write(offset <number>, data <table>)
Write an array of bytes to mapped physical memory, starting at the specified byte offset, relative to the base physical address the MMIO object was opened with.
Raises an MMIO error on failure.
mmio:close()
Unmap the MMIO object's mapped physical memory.
Raises an MMIO error on failure.
Property mmio.base immutable <number>
Get the base physical address the MMIO object was opened with.
Raises an MMIO error on assignment.
Property mmio.size immutable <number>
Get the mapping size the MMIO object was opened with.
Raises an MMIO error on assignment.
The periphery MMIO methods and properties may raise a Lua error on failure that can be propagated to the user or caught with Lua's pcall()
. The error object raised is a table with code
, c_errno
, message
properties, which contain the error code string, underlying C error number, and a descriptive message string of the error, respectively. The error object also provides the necessary metamethod for it to be formatted as a string if it is propagated to the user by the interpreter.
--- Example of error propagated to user
> periphery = require('periphery')
> mmio = periphery.MMIO(0x40000000, 0x1000)
Opening /dev/mem: Permission denied [errno 13]
>
--- Example of error caught with pcall()
> status, err = pcall(function () mmio = periphery.MMIO(0x400000000, 0x1000) end)
> =status
false
> dump(err)
{
message = "Opening /dev/mem: Permission denied [errno 13]",
c_errno = 13,
code = "MMIO_ERROR_OPEN"
}
>
Error Code | Description |
---|---|
"MMIO_ERROR_ARG" |
Invalid arguments |
"MMIO_ERROR_OPEN" |
Opening MMIO |
"MMIO_ERROR_CLOSE" |
Closing MMIO |
"MMIO_ERROR_ALLOC" |
Allocating memory |
local MMIO = require('periphery').MMIO
-- Open am335x real-time clock subsystem page
local rtc_mmio = MMIO(0x44E3E000, 0x1000)
--- Read current time
local rtc_secs = rtc_mmio:read32(0x00)
local rtc_mins = rtc_mmio:read32(0x04)
local rtc_hrs = rtc_mmio:read32(0x08)
print(string.format("hours: %02x minutes: %02x seconds: %02x", rtc_secs, rtc_mins, rtc_hrs))
rtc_mmio:close()
--- Open am335x control module page
local ctrl_mmio = MMIO(0x44E10000, 0x1000)
-- Read MAC address
local mac_id0_lo = ctrl_mmio:read32(0x630)
local mac_id0_hi = ctrl_mmio:read32(0x634)
print(string.format("MAC address: %04x %08x", mac_id0_lo, mac_id0_hi))
ctrl_mmio:close()