Skip to content

Commit 0954dbd

Browse files
committed
imx500: Add support for Device ID and encrypted rpks
Allow the imx500 library to readback the device id from the kernel using a V4L2 control. Additionally parse the encryption flags (if present) in the rpk binary. Signed-off-by: Naushir Patuck <[email protected]>
1 parent ac763f8 commit 0954dbd

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from picamera2.devices.imx500 import IMX500
2+
from picamera2 import Picamera2
3+
4+
model = "/usr/share/imx500-models/imx500_network_mobilenet_v2.rpk"
5+
6+
# startup imx500 / picamera2
7+
imx500 = IMX500(model)
8+
picam2 = Picamera2()
9+
config = picam2.create_preview_configuration()
10+
picam2.start(config, show_preview=False)
11+
12+
# get device_id
13+
device_id = imx500.get_device_id()
14+
print("IMX500 Device ID =", device_id)

picamera2/devices/imx500/imx500.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
from libarchive.read import fd_reader
1515
from libcamera import Rectangle, Size
1616
from tqdm import tqdm
17-
from v4l2 import (VIDIOC_S_CTRL, VIDIOC_S_EXT_CTRLS, v4l2_control,
18-
v4l2_ext_control, v4l2_ext_controls)
17+
from v4l2 import (VIDIOC_G_EXT_CTRLS, VIDIOC_S_CTRL, VIDIOC_S_EXT_CTRLS,
18+
v4l2_control, v4l2_ext_control, v4l2_ext_controls)
1919

2020
from picamera2 import CompletedRequest, Picamera2
2121

@@ -27,6 +27,7 @@
2727
FW_MAIN_STAGE = 1
2828
FW_NETWORK_STAGE = 2
2929

30+
GET_DEVICE_ID_CTRL_ID = 0x00982902
3031
NETWORK_FW_FD_CTRL_ID = 0x00982901
3132
ROI_CTRL_ID = 0x00982900
3233

@@ -372,6 +373,36 @@ def convert_inference_coords(self, coords: tuple, metadata: dict, picam2: Picame
372373
out = self.__get_obj_scaled(obj, isp_output_size, scaler_crop, sensor_output_size)
373374
return out.to_tuple()
374375

376+
def get_device_id(self) -> str:
377+
"""Get IMX500 Device ID"""
378+
ret = None
379+
imx500_device_id = ""
380+
381+
r = (ctypes.c_uint32 * 4)()
382+
r[0] = 0x0
383+
r[1] = 0x0
384+
r[2] = 0x0
385+
r[3] = 0x0
386+
387+
c = (v4l2_ext_control * 1)()
388+
c[0].p_u32 = r
389+
c[0].id = GET_DEVICE_ID_CTRL_ID
390+
c[0].size = 16
391+
392+
ctrl = v4l2_ext_controls()
393+
ctrl.count = 1
394+
ctrl.controls = c
395+
396+
try:
397+
fcntl.ioctl(self.device_fd, VIDIOC_G_EXT_CTRLS, ctrl)
398+
for i in range(4):
399+
ret = ctrl.controls[0].p_u32[i]
400+
imx500_device_id += "%08X" % ret
401+
except OSError as err:
402+
print(f'IMX500: Unable to get device ID from device driver: {err}')
403+
404+
return imx500_device_id
405+
375406
def get_fw_upload_progress(self, stage_req) -> tuple:
376407
"""Returns the current progress of the fw upload in the form of (current, total)."""
377408
progress_block = 0
@@ -621,14 +652,25 @@ def __ni_from_network(self, network_filename: str):
621652
(magic, size) = struct.unpack('>4sI', fw[:8])
622653
if not magic == b'9464':
623654
break
624-
fw = fw[size + 60:]
655+
656+
# Parse flags
657+
fw = fw[8:]
658+
flags = struct.unpack('8B', fw[:8])
659+
device_lock_flag = flags[6]
660+
fw = fw[(size + 60 - 8):] # jump to footer
661+
625662
# Ensure footer is as expected
626663
(magic,) = struct.unpack('4s', fw[:4])
627664
if not magic == b'3695':
628665
raise RuntimeError(f'No matching footer found in firmware file {network_filename}')
629666
fw = fw[4:]
630667
cpio_offset += size + 64
631668

669+
if ((device_lock_flag & 0x01) == 1):
670+
# skip forward 32 bytes if device_lock_flag.bit0 == 1
671+
fw = fw[32:]
672+
cpio_offset += 32
673+
632674
cpio_fd = os.open(network_filename, os.O_RDONLY)
633675
os.lseek(cpio_fd, cpio_offset, os.SEEK_SET)
634676

0 commit comments

Comments
 (0)