3

I want to get the unique serial number from Beaglebone Black. AM335X Reference Manual 9.3.1.25 tells me that I should be able to get the unique serial id from mac_id0_lo and mac_id0_hi registers. The offsets of these registers are 630h and 634h.

How can I read the values of these registers? I found this post on stackoverflow, but it is not very helpful.

UPDATE

I finally got a python code working to read the mac_id0 and mac_id1 from beaglebone black.

from mmap import mmap
import struct

CONTROL_MODULE_OFFSET = 0x44E10000
CONTROL_MODULE_SIZE = 0x44E11FFF-CONTROL_MODULE_OFFSET
MAC_ID0_LO_OFFSET = 0x630
MAC_ID0_HI_OFFSET = 0x634
MAC_ID1_LO_OFFSET = 0x638
MAC_ID1_HI_OFFSET = 0x63C

def print_mac():
    file_handler = open("/dev/mem", "r+b")
    mem = mmap(file_handler.fileno(), CONTROL_MODULE_SIZE, offset=CONTROL_MODULE_OFFSET)

    mac_id0_lo_packed_reg = mem[MAC_ID0_LO_OFFSET:MAC_ID0_LO_OFFSET+4]
    mac_id0_hi_packed_reg = mem[MAC_ID0_HI_OFFSET:MAC_ID0_HI_OFFSET+4]

    mac_id1_lo_packed_reg = mem[MAC_ID1_LO_OFFSET:MAC_ID1_LO_OFFSET+4]
    mac_id1_hi_packed_reg = mem[MAC_ID1_HI_OFFSET:MAC_ID1_HI_OFFSET+4]

    mac_id0_lo = struct.unpack('<L', mac_id0_lo_packed_reg)[0]
    mac_id0_hi = struct.unpack('<L', mac_id0_hi_packed_reg)[0]
    mac_id0_bytes = [None]*6
    mac_id0_bytes[0] = (mac_id0_lo & 0xff00) >> 8 #byte 0
    mac_id0_bytes[1] = (mac_id0_lo & 0x00ff) #byte 1
    mac_id0_bytes[2] = (mac_id0_hi & 0xff000000) >> 24 #byte 2
    mac_id0_bytes[3] = (mac_id0_hi & 0x00ff0000) >> 16 #byte 3
    mac_id0_bytes[4] = (mac_id0_hi & 0x0000ff00) >> 8 #byte 4
    mac_id0_bytes[5] = (mac_id0_hi & 0x000000ff) #byte 4
    mac_address_id0 = 0
    for i, byte in enumerate(mac_id0_bytes):
        mac_address_id0 |= ((byte & 0xff) << (i*8))

    mac_id1_lo = struct.unpack('<L', mac_id1_lo_packed_reg)[0]
    mac_id1_hi = struct.unpack('<L', mac_id1_hi_packed_reg)[0]
    mac_id1_bytes = [None]*6
    mac_id1_bytes[0] = (mac_id1_lo & 0xff00) >> 8 #byte 0
    mac_id1_bytes[1] = (mac_id1_lo & 0x00ff) #byte 1
    mac_id1_bytes[2] = (mac_id1_hi & 0xff000000) >> 24 #byte 2
    mac_id1_bytes[3] = (mac_id1_hi & 0x00ff0000) >> 16 #byte 3
    mac_id1_bytes[4] = (mac_id1_hi & 0x0000ff00) >> 8 #byte 4
    mac_id1_bytes[5] = (mac_id1_hi & 0x000000ff) #byte 4
    mac_address_id1 = 0
    for i, byte in enumerate(mac_id1_bytes):
        mac_address_id1 |= ((byte & 0xff) << (i*8))

    print 'mac id0'
    print format(mac_address_id0, '08x')

    print 'mac id1'
    print format(mac_address_id1, '08x')

    if not file_handler.closed:
        file_handler.close()
    mem.close()
print_mac()
Community
  • 1
  • 1
DXM
  • 1,249
  • 1
  • 14
  • 22

2 Answers2

4

Those registers must be memory mapped, so question is how you can figure out complete physical address and find a way to access that physical address.

From the TRM:

The values read from Control Module (Base address 0x44E1_0000) MAC_ID0_LO register (Offset 0x630), MAC_ID0_HI register (Offset 0x634), MAC_ID1_LO register (Offset 0x638), and MAC_ID1_HI register (Offset 0x63C) represent unique MAC addresses assigned to each AM335x device. The values in these registers are programmed into each AM335x device by TI and can not be changed.

May be you can use devmem2 like devmem2 0x44e10630 however that may depend on Linux not having CONFIG_STRICT_DEVMEM. Worse you may need to write a small kernel driver to access those memory areas.

auselen
  • 27,577
  • 7
  • 73
  • 114
  • You can try using a ready purpose-built system like this project: https://github.com/kaiwan/device-memory-readwrite – kaiwan Jan 20 '17 at 03:37
0

As mentioned by auselen I just tried to read the value in the main counter register of the high precision timer chip by doing devmem2 0xfed000f0 and it worked despite CONFIG_STRICT_DEVMEM is set, due to the fact that it's non-RAM and thus readable/writable in userspace.

JohnnyFromBF
  • 9,873
  • 10
  • 45
  • 59