Skip to content

Commit c3d9d7b

Browse files
Merge pull request #830 from jakaskerl/main
Updating docs
2 parents 0762f4d + bf4f0d0 commit c3d9d7b

File tree

4 files changed

+201
-15
lines changed

4 files changed

+201
-15
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Script EMMC access
2+
==================
3+
4+
.. note::
5+
6+
This example requires a device with onboard EMMC memory (e.g. OAK-1-POE).
7+
To check whether your device has EMMC memory, run the bootloader version script at :ref:`Bootloader Version` and check whether the output contains ``Memory.EMMC``.
8+
9+
10+
11+
This example shows how to use :ref:`Script` node to access EMMC memory of the device. Default location for EMMC memory is ``/media/mmcsd-0-0/``. The first script in the pipeline works by writing an image to EMMC memory.
12+
The second script starts a webserver on ::code:`/media/mmcsd-0-0/` directory and serves the image from EMMC memory.
13+
14+
15+
Setup
16+
#####
17+
18+
.. include:: /includes/install_from_pypi.rst
19+
20+
21+
Prerequisites
22+
#############
23+
24+
We first need to enable the EMMC memory as storage on the device. To do so, we need to flash the device with an application that has EMMC enabled.
25+
26+
Example application:
27+
28+
.. code-block:: python
29+
30+
import depthai as dai
31+
32+
# Create pipeline
33+
pipeline = dai.Pipeline()
34+
35+
# Set board config
36+
board = dai.BoardConfig()
37+
board.emmc = True
38+
config = dai.Device.Config()
39+
config.board = board
40+
pipeline.setBoardConfig(board)
41+
42+
(f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
43+
bootloader = dai.DeviceBootloader(bl)
44+
progress = lambda p : print(f'Flashing progress: {p*100:.1f}%')
45+
(r, errmsg) = bootloader.flash(progress, pipeline, memory=dai.DeviceBootloader.Memory.EMMC)
46+
if r: print("Flash OK")
47+
48+
49+
The above code will flash the device with the application that enables the script node to access EMMC memory. Now we should be able to access EMMC memory even when the device is in standard mode (connected to the host PC).
50+
51+
Source code
52+
###########
53+
54+
.. tabs::
55+
56+
.. tab:: Python
57+
58+
Also `available on GitHub <https://github.com/luxonis/depthai-python/blob/main/examples/Script/script_emmc_access.py>`__
59+
60+
.. literalinclude:: ../../../../examples/Script/script_emmc_access.py
61+
:language: python
62+
:linenos:
63+
64+
.. include:: /includes/footer-short.rst

docs/source/tutorials/code_samples.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ are presented with code.
128128
- :ref:`Script MJPEG server` - Serve MJPEG video stream over HTTP response (only OAK-POE devices)
129129
- :ref:`Script NNData example` - Constructs :ref:`NNData` in Script node and sends it to the host
130130
- :ref:`Script UART communication` - UART communication with Script node
131+
- :ref:`Script EMMC access` - Access EMMC memory from the Script node
131132

132133
.. rubric:: SpatialDetection
133134

docs/source/tutorials/standalone_mode.rst

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,26 +67,49 @@ can flash the pipeline to the device, along with its assests (eg. AI models). Yo
6767
After successfully flashing the pipeline, it will get started automatically when you power up the device.
6868
If you would like to change the flashed pipeline, simply re-flash it again.
6969

70-
..
71-
Clear flash
72-
###########
70+
Alternatively, you can also flash the pipeline with the :ref:`Device Manager`. For this approach, you will need a Depthai Application Package (.dap), which you
71+
can create with the following script:
7372

74-
Since pipeline will start when powering the device, this can lead to unnecesary heating. If you would like to clear
75-
the flashed pipeline, use the code snippet below.
7673

77-
.. warning::
78-
Code below doesn't work yet. We will be adding "flashClear" helper function to the library.
74+
.. code-block:: python
7975
80-
.. code-block:: python
76+
import depthai as dai
8177
82-
import depthai as dai
83-
(f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
84-
if not f:
85-
print('No devices found, exiting...')
86-
exit(-1)
78+
pipeline = dai.Pipeline()
79+
80+
# Define standalone pipeline; add nodes and link them
81+
# cam = pipeline.create(dai.node.ColorCamera)
82+
# script = pipeline.create(dai.node.Script)
83+
# ...
84+
85+
# Create Depthai Application Package (.dap)
86+
(f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
87+
bootloader = dai.DeviceBootloader(bl)
88+
bootloader.saveDepthaiApplicationPackage(pipeline=pipeline, path=<path_of_new_dap>)
89+
90+
91+
Clear flash
92+
###########
93+
94+
Since pipeline will start when powering the device, this can lead to unnecesary heating. If you would like to clear
95+
the flashed pipeline, use the code snippet below.
96+
97+
98+
.. warning::
99+
Code below doesn't work yet. We will be adding "flashClear" helper function to the library.
100+
101+
102+
.. code-block:: python
103+
104+
import depthai as dai
105+
(f, bl) = dai.DeviceBootloader.getFirstAvailableDevice()
106+
if not f:
107+
print('No devices found, exiting...')
108+
exit(-1)
109+
110+
with dai.DeviceBootloader(bl) as bootloader:
111+
bootloader.flashClear()
87112
88-
with dai.DeviceBootloader(bl) as bootloader:
89-
bootloader.flashClear()
90113
91114
Factory reset
92115
#############

examples/Script/script_emmc_access.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import depthai as dai
2+
import cv2
3+
4+
# Start defining a pipeline
5+
pipeline = dai.Pipeline()
6+
7+
board = dai.BoardConfig()
8+
board.emmc = True
9+
pipeline.setBoardConfig(board)
10+
11+
# Define source and output
12+
camRgb = pipeline.create(dai.node.ColorCamera)
13+
jpegEncoder = pipeline.create(dai.node.VideoEncoder)
14+
15+
# Properties
16+
camRgb.setResolution(dai.ColorCameraProperties.SensorResolution.THE_4_K)
17+
jpegEncoder.setDefaultProfilePreset(1, dai.VideoEncoderProperties.Profile.MJPEG)
18+
19+
#Set a write script
20+
script_write = pipeline.createScript()
21+
script_write.setProcessor(dai.ProcessorType.LEON_CSS)
22+
script_write.setScript("""
23+
24+
import os
25+
index = 1000
26+
import time
27+
while True:
28+
# Find an unused file name first
29+
while True:
30+
path = '/media/mmcsd-0-0/' + str(index) + '.jpg'
31+
if not os.path.exists(path):
32+
break
33+
index += 1
34+
frame = node.io['jpeg'].get()
35+
node.warn(f'Saving to EMMC: {path}')
36+
with open(path, 'wb') as f:
37+
f.write(frame.getData())
38+
index += 1
39+
time.sleep(3)
40+
41+
""")
42+
43+
#Set a read script
44+
script_read = pipeline.createScript()
45+
script_read.setProcessor(dai.ProcessorType.LEON_CSS)
46+
script_read.setScript("""
47+
48+
import http.server
49+
import socketserver
50+
import socket
51+
import fcntl
52+
import struct
53+
import os
54+
55+
def get_ip_address(ifname):
56+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
57+
return socket.inet_ntoa(fcntl.ioctl(
58+
s.fileno(),
59+
-1071617759, # SIOCGIFADDR
60+
struct.pack('256s', ifname[:15].encode())
61+
)[20:24])
62+
63+
# Note: `chdir` here will prevent unmount, this should be improved!
64+
os.chdir('/media/mmcsd-0-0')
65+
66+
PORT = 80
67+
Handler = http.server.SimpleHTTPRequestHandler
68+
69+
with socketserver.TCPServer(("", PORT), Handler) as httpd:
70+
ip = get_ip_address('re0')
71+
node.warn(f'===== HTTP file server accessible at: http://{ip}')
72+
httpd.serve_forever()
73+
74+
""")
75+
76+
# Linking
77+
78+
camRgb.video.link(jpegEncoder.input)
79+
jpegEncoder.bitstream.link(script_write.inputs['jpeg'])
80+
script_write.inputs['jpeg'].setBlocking(False)
81+
xout = pipeline.create(dai.node.XLinkOut)
82+
xout.setStreamName("rgb")
83+
script_read.outputs['jpeg'].link(xout.input)
84+
85+
86+
# Pipeline defined, now the device is connected to
87+
with dai.Device(pipeline) as device:
88+
# Output queue will be used to get the rgb frames from the output defined above
89+
qRgb = device.getOutputQueue(name="rgb", maxSize=100, blocking=False)
90+
91+
while True:
92+
inRgb = qRgb.tryGet()
93+
94+
if inRgb is not None:
95+
cv2.imshow("rgb", inRgb.getCvFrame())
96+
97+
if cv2.waitKey(1) == ord('q'):
98+
break

0 commit comments

Comments
 (0)