commit de3a098c609f95c8239ac178935e4253dbbf9437 Author: Weckyy702 <50154363+Weckyy702@users.noreply.github.com> Date: Tue Jan 20 00:49:39 2026 +0100 2026-01-20 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f0de8a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +main.pdf diff --git a/i2c-schedule.py b/i2c-schedule.py new file mode 100644 index 0000000..45c9044 --- /dev/null +++ b/i2c-schedule.py @@ -0,0 +1,49 @@ +from time import sleep +from random import binomialvariate + +DISPLAY = "display" +SENSOR = "sensor" +ZIGBEE = "zigbee" +LABELS = {DISPLAY, SENSOR, ZIGBEE} + +time = 0 + +transactions = [] +active_transaction = None +slice_labels = {l: "" for l in LABELS} + +def display(): + if time % 5 == 1: + transactions.append((DISPLAY, 4 if binomialvariate(p=0.15) else 2, 50)) + +def sensor(): + if time % 5 == 0: + transactions.append((SENSOR, 1, 10)) + +def zigbee(): + if time % 15 == 14: + transactions.append((ZIGBEE, 10, 100)) + +print(' '*5, *(l[0] for l in LABELS)) +while True: + + display() + sensor() + zigbee() + + if active_transaction is None and transactions: + active_transaction = min(transactions, key=lambda t: t[2]) + transactions.remove(active_transaction) + + print(f"t={time:02}: ", end="") + if active_transaction is not None: + label, duration, priority = active_transaction + print(*('x' if l == label else '#' if any(t[0]==l for t in transactions) else ' ' for l in LABELS)) + + active_transaction = (label, duration-1, priority) if duration > 1 else None + transactions = [(l, d, p*0.8) for (l, d, p) in transactions] + else: + print(" ") + + time += 1 + sleep(1) diff --git a/i2c-starvation-gantt.excalidraw b/i2c-starvation-gantt.excalidraw new file mode 100644 index 0000000..40753de --- /dev/null +++ b/i2c-starvation-gantt.excalidraw @@ -0,0 +1,2138 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "Hr1DYNPU_yQL5JrXTUA7_", + "type": "arrow", + "x": 400.5504300191999, + "y": 700.8220193029797, + "width": 1300, + "height": 0, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a0", + "roundness": { + "type": 2 + }, + "seed": 173172636, + "version": 62, + "versionNonce": 469223452, + "isDeleted": false, + "boundElements": [], + "updated": 1768851356798, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 1300, + 0 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "vXhMCbxlxnwo7yEY9u9am", + "type": "line", + "x": 400, + "y": 480, + "width": 0, + "height": 220, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a1", + "roundness": { + "type": 2 + }, + "seed": 1058658844, + "version": 64, + "versionNonce": 408680348, + "isDeleted": false, + "boundElements": [], + "updated": 1768851354246, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 220 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "WtFfHjLBagg77kkEjXzs3", + "type": "text", + "x": 260, + "y": 740, + "width": 118.80000305175781, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a2", + "roundness": null, + "seed": 1666982300, + "version": 36, + "versionNonce": 270617372, + "isDeleted": true, + "boundElements": [], + "updated": 1768850994662, + "link": null, + "locked": false, + "text": "Zigbee", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "Zigbee", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "zEocIH6_eI4rKYBEzSztk", + "type": "text", + "x": 180, + "y": 620, + "width": 198, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a3", + "roundness": null, + "seed": 1750701092, + "version": 16, + "versionNonce": 1238722084, + "isDeleted": false, + "boundElements": [], + "updated": 1768831894588, + "link": null, + "locked": false, + "text": "Temperatur", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "Temperatur", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "3qpdjCM_NE_wg-FNyU9MQ", + "type": "text", + "x": 240, + "y": 520, + "width": 138.60000610351562, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a4", + "roundness": null, + "seed": 70698276, + "version": 13, + "versionNonce": 1332731684, + "isDeleted": false, + "boundElements": [], + "updated": 1768831892938, + "link": null, + "locked": false, + "text": "Display", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "Display", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "98EibphSzeIIRQln4Hdkn", + "type": "rectangle", + "x": 500, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a5", + "roundness": { + "type": 3 + }, + "seed": 1535875364, + "version": 8, + "versionNonce": 1106469540, + "isDeleted": false, + "boundElements": [], + "updated": 1768831367878, + "link": null, + "locked": false + }, + { + "id": "zdKjm0tN32hfQFEQI6pmd", + "type": "rectangle", + "x": 700, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a6", + "roundness": { + "type": 3 + }, + "seed": 347021084, + "version": 26, + "versionNonce": 1999676316, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "OL7do7CYcosKoxDnJC7Sw", + "type": "rectangle", + "x": 880, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a7", + "roundness": { + "type": 3 + }, + "seed": 1799103388, + "version": 16, + "versionNonce": 158344868, + "isDeleted": true, + "boundElements": [], + "updated": 1768831401376, + "link": null, + "locked": false + }, + { + "id": "CgaAFxgTfGgIpLsTHvJrP", + "type": "rectangle", + "x": 900, + "y": 600, + "width": 100, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a8", + "roundness": { + "type": 3 + }, + "seed": 1953089436, + "version": 28, + "versionNonce": 1280439332, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "RJysAShHRL1RBTdBum0xc", + "type": "rectangle", + "x": 1100, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a9", + "roundness": { + "type": 3 + }, + "seed": 1907085988, + "version": 26, + "versionNonce": 1360121884, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "3xSVB5c1sbLqT9zfMmlhC", + "type": "rectangle", + "x": 1300, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aA", + "roundness": { + "type": 3 + }, + "seed": 1161929636, + "version": 18, + "versionNonce": 1573375908, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "BvnxMQ9dNlA65yV6U1Tbj", + "type": "rectangle", + "x": 520, + "y": 500, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aB", + "roundness": { + "type": 3 + }, + "seed": 696305444, + "version": 25, + "versionNonce": 521759900, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "eCv2I49JBckkt51umY0wJ", + "type": "rectangle", + "x": 640, + "y": 500, + "width": 80, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aC", + "roundness": { + "type": 3 + }, + "seed": 918637860, + "version": 27, + "versionNonce": 1648523300, + "isDeleted": true, + "boundElements": [], + "updated": 1768831505435, + "link": null, + "locked": false + }, + { + "id": "OALPAGO56CvKJhto8CbVu", + "type": "rectangle", + "x": 720, + "y": 500, + "width": 140, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aD", + "roundness": { + "type": 3 + }, + "seed": 26616996, + "version": 29, + "versionNonce": 183909156, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "kQCJTs-BWx3W8GxG_tKvZ", + "type": "rectangle", + "x": 920, + "y": 500, + "width": 60, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aE", + "roundness": { + "type": 3 + }, + "seed": 636519716, + "version": 25, + "versionNonce": 1928952092, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "1p8RaOJS6kQ6rjhu-sAxB", + "type": "rectangle", + "x": 1000, + "y": 500, + "width": 140, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aF", + "roundness": { + "type": 3 + }, + "seed": 1515484580, + "version": 42, + "versionNonce": 1850422948, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "ou4RsZS0-lz_7bNJMHDCB", + "type": "rectangle", + "x": 1200, + "y": 500, + "width": 80, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aG", + "roundness": { + "type": 3 + }, + "seed": 1675610532, + "version": 24, + "versionNonce": 1478751644, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "WnMAkSC1adbviLGu9JXME", + "type": "rectangle", + "x": 720, + "y": 700, + "width": 280, + "height": 100, + "angle": 0, + "strokeColor": "#1971c2", + "backgroundColor": "#a5d8ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aH", + "roundness": { + "type": 3 + }, + "seed": 650985124, + "version": 51, + "versionNonce": 276350116, + "isDeleted": true, + "boundElements": [], + "updated": 1768831545281, + "link": null, + "locked": false + }, + { + "id": "leb_UdjpAJ3iNcW4s5dea", + "type": "rectangle", + "x": 1120, + "y": 700, + "width": 280, + "height": 100, + "angle": 0, + "strokeColor": "#1971c2", + "backgroundColor": "#a5d8ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aI", + "roundness": { + "type": 3 + }, + "seed": 474783012, + "version": 71, + "versionNonce": 350240412, + "isDeleted": true, + "boundElements": [], + "updated": 1768831543782, + "link": null, + "locked": false + }, + { + "id": "kTHHFnbzRElq0cEt-GdC_", + "type": "rectangle", + "x": 1000, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aJ", + "roundness": { + "type": 3 + }, + "seed": 1401200924, + "version": 33, + "versionNonce": 611631652, + "isDeleted": true, + "boundElements": [], + "updated": 1768831542416, + "link": null, + "locked": false + }, + { + "id": "WE1JiPrrjKBuYE8b3Ur1G", + "type": "rectangle", + "x": 520, + "y": 500, + "width": 220.00000000000003, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aK", + "roundness": { + "type": 3 + }, + "seed": 654502820, + "version": 24, + "versionNonce": 1083913124, + "isDeleted": false, + "boundElements": [], + "updated": 1768851011555, + "link": null, + "locked": false + }, + { + "id": "uyItlkzUMPKfIl8h2yXm5", + "type": "rectangle", + "x": 700, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aL", + "roundness": { + "type": 3 + }, + "seed": 1333032732, + "version": 8, + "versionNonce": 365012124, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "8Egk85cJmkTtzvPhrjpTf", + "type": "rectangle", + "x": 720, + "y": 700, + "width": 300, + "height": 100, + "angle": 0, + "strokeColor": "#1971c2", + "backgroundColor": "#a5d8ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aM", + "roundness": { + "type": 3 + }, + "seed": 491563036, + "version": 26, + "versionNonce": 662737956, + "isDeleted": true, + "boundElements": [], + "updated": 1768831733406, + "link": null, + "locked": false + }, + { + "id": "0H-kZ9kOLTELrOO9nOoBK", + "type": "rectangle", + "x": 720, + "y": 500, + "width": 300, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aN", + "roundness": { + "type": 3 + }, + "seed": 515489188, + "version": 24, + "versionNonce": 1664666780, + "isDeleted": true, + "boundElements": [], + "updated": 1768831735048, + "link": null, + "locked": false + }, + { + "id": "6VK5w0h1Wze7-plql055U", + "type": "rectangle", + "x": 900, + "y": 600, + "width": 260, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aO", + "roundness": { + "type": 3 + }, + "seed": 381154724, + "version": 22, + "versionNonce": 1573375900, + "isDeleted": true, + "boundElements": [], + "updated": 1768831727358, + "link": null, + "locked": false + }, + { + "id": "VZIB3uBTaddqPJMGAeIof", + "type": "rectangle", + "x": 1020, + "y": 500, + "width": 140, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aP", + "roundness": { + "type": 3 + }, + "seed": 692657308, + "version": 15, + "versionNonce": 2035729956, + "isDeleted": true, + "boundElements": [], + "updated": 1768831731151, + "link": null, + "locked": false + }, + { + "id": "zbLSeESBO82iCzySYyedh", + "type": "rectangle", + "x": 1160, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aQ", + "roundness": { + "type": 3 + }, + "seed": 1060785316, + "version": 10, + "versionNonce": 16457244, + "isDeleted": true, + "boundElements": [], + "updated": 1768831731151, + "link": null, + "locked": false + }, + { + "id": "9K4o9ihG9-8aFhVT1E6TJ", + "type": "rectangle", + "x": 1180, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aR", + "roundness": { + "type": 3 + }, + "seed": 1734597276, + "version": 31, + "versionNonce": 1986159012, + "isDeleted": true, + "boundElements": [], + "updated": 1768831731151, + "link": null, + "locked": false + }, + { + "id": "L5yt-rr96lQVQUuCaRNTD", + "type": "rectangle", + "x": 1200, + "y": 700, + "width": 200, + "height": 100, + "angle": 0, + "strokeColor": "#1971c2", + "backgroundColor": "#a5d8ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aS", + "roundness": { + "type": 3 + }, + "seed": 1197285916, + "version": 28, + "versionNonce": 929515292, + "isDeleted": true, + "boundElements": [], + "updated": 1768831732208, + "link": null, + "locked": false + }, + { + "id": "4N9qYtMbn59UVrSZUpzpm", + "type": "rectangle", + "x": 720, + "y": 500, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aT", + "roundness": { + "type": 3 + }, + "seed": 1676367260, + "version": 16, + "versionNonce": 1544389412, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "WT4i8_TW3znuuYJRmhMc-", + "type": "rectangle", + "x": 900, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aU", + "roundness": { + "type": 3 + }, + "seed": 915970468, + "version": 34, + "versionNonce": 1473949980, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "tUZZ0NYxeaUWOlqrs_-mj", + "type": "rectangle", + "x": 920, + "y": 500, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aV", + "roundness": { + "type": 3 + }, + "seed": 1554750628, + "version": 30, + "versionNonce": 100806300, + "isDeleted": true, + "boundElements": [], + "updated": 1768831757359, + "link": null, + "locked": false + }, + { + "id": "6-sSthny1XnHENWr4v9o5", + "type": "rectangle", + "x": 920, + "y": 700, + "width": 280, + "height": 100, + "angle": 0, + "strokeColor": "#1971c2", + "backgroundColor": "#a5d8ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aW", + "roundness": { + "type": 3 + }, + "seed": 1166791844, + "version": 22, + "versionNonce": 1139888164, + "isDeleted": true, + "boundElements": [], + "updated": 1768850997442, + "link": null, + "locked": false + }, + { + "id": "E0wPAtb0lTh72kJRgA3oX", + "type": "rectangle", + "x": 1100, + "y": 600, + "width": 300, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aX", + "roundness": { + "type": 3 + }, + "seed": 1888633628, + "version": 23, + "versionNonce": 758742692, + "isDeleted": true, + "boundElements": [ + { + "type": "text", + "id": "OngzNk7mpvvecQHTLMrvl" + } + ], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "OngzNk7mpvvecQHTLMrvl", + "type": "text", + "x": 1111.3999938964844, + "y": 627.5, + "width": 277.20001220703125, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aXV", + "roundness": null, + "seed": 511752988, + "version": 21, + "versionNonce": 2082352540, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false, + "text": "Sensor starved", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "E0wPAtb0lTh72kJRgA3oX", + "originalText": "Sensor starved", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "bw-_bOozwozRjDWisptvi", + "type": "rectangle", + "x": 1220, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aY", + "roundness": { + "type": 3 + }, + "seed": 1626217116, + "version": 11, + "versionNonce": 199086116, + "isDeleted": true, + "boundElements": [], + "updated": 1768832056582, + "link": null, + "locked": false + }, + { + "id": "rXKLyHksejJHz4gZT310y", + "type": "rectangle", + "x": 920, + "y": 500, + "width": 320, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aZ", + "roundness": { + "type": 3 + }, + "seed": 1043400996, + "version": 25, + "versionNonce": 1857205660, + "isDeleted": true, + "boundElements": [], + "updated": 1768832051782, + "link": null, + "locked": false + }, + { + "id": "B4aDAFsD3gmSJUHTCwOxH", + "type": "rectangle", + "x": 1240, + "y": 500, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aa", + "roundness": { + "type": 3 + }, + "seed": 1893313052, + "version": 18, + "versionNonce": 502855452, + "isDeleted": true, + "boundElements": [], + "updated": 1768831812975, + "link": null, + "locked": false + }, + { + "id": "dwRgyyyrvAt5AnTuUGn6Q", + "type": "rectangle", + "x": 1200, + "y": 500, + "width": 200, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ab", + "roundness": { + "type": 3 + }, + "seed": 112181156, + "version": 43, + "versionNonce": 2119830052, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "p661l7EIsrM50J282TqiI", + "type": "rectangle", + "x": 1260, + "y": 620, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ac", + "roundness": { + "type": 3 + }, + "seed": 550135964, + "version": 42, + "versionNonce": 93800356, + "isDeleted": true, + "boundElements": [], + "updated": 1768832058590, + "link": null, + "locked": false + }, + { + "id": "L7cQR-qcXsoY9F3QFPuGm", + "type": "text", + "x": 1700, + "y": 800, + "width": 19.799999237060547, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ad", + "roundness": null, + "seed": 853877028, + "version": 21, + "versionNonce": 1681500836, + "isDeleted": false, + "boundElements": [], + "updated": 1768832124500, + "link": null, + "locked": false, + "text": "t", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "t", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "E-4WI5Rm98YyL_tya9qB_", + "type": "rectangle", + "x": 1400, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ae", + "roundness": { + "type": 3 + }, + "seed": 1589242660, + "version": 7, + "versionNonce": 868096540, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "v89_6VE2FdfJZgUbuBlcL", + "type": "rectangle", + "x": 1420, + "y": 500, + "width": 180, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "af", + "roundness": { + "type": 3 + }, + "seed": 2130722852, + "version": 16, + "versionNonce": 39658916, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "_s1MEw3hXMCbblksDq4kj", + "type": "rectangle", + "x": 1600, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ag", + "roundness": { + "type": 3 + }, + "seed": 1095045404, + "version": 21, + "versionNonce": 967603868, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "SGvsCVbM7Nng9HxyVFtYc", + "type": "rectangle", + "x": 920, + "y": 500, + "width": 280, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ah", + "roundness": { + "type": 3 + }, + "seed": 1053850916, + "version": 21, + "versionNonce": 1584451876, + "isDeleted": true, + "boundElements": [], + "updated": 1768851008035, + "link": null, + "locked": false + }, + { + "id": "-F5Arjwd38cm_FVY4r0bN", + "type": "arrow", + "x": 1340, + "y": 880, + "width": 84, + "height": 225, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ai", + "roundness": { + "type": 2 + }, + "seed": 557621020, + "version": 20, + "versionNonce": 561069604, + "isDeleted": true, + "boundElements": [], + "updated": 1768832238361, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -84, + -225 + ] + ], + "startBinding": null, + "endBinding": { + "elementId": "E0wPAtb0lTh72kJRgA3oX", + "mode": "inside", + "fixedPoint": [ + 0.52, + 0.55 + ] + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "zlzs526XFzGY3uOyZnp4m", + "type": "text", + "x": 1313.2000007629395, + "y": 898, + "width": 19.799999237060547, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aj", + "roundness": null, + "seed": 1926379172, + "version": 3, + "versionNonce": 69143324, + "isDeleted": true, + "boundElements": [], + "updated": 1768832213183, + "link": null, + "locked": false, + "text": "", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "FHZZeFFrKqaczWxLbHzFM", + "type": "text", + "x": 1316.2000007629395, + "y": 907, + "width": 19.799999237060547, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ak", + "roundness": null, + "seed": 1514793892, + "version": 3, + "versionNonce": 1900583324, + "isDeleted": true, + "boundElements": [], + "updated": 1768832215284, + "link": null, + "locked": false, + "text": "", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "I9DqoufF2zHQEIE2paTZF", + "type": "text", + "x": 1115, + "y": 629, + "width": 277.20001220703125, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ffc9c9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "al", + "roundness": null, + "seed": 539746972, + "version": 80, + "versionNonce": 1344377372, + "isDeleted": true, + "boundElements": [], + "updated": 1768832248201, + "link": null, + "locked": false, + "text": "Sensor starved", + "fontSize": 36, + "fontFamily": 8, + "textAlign": "right", + "verticalAlign": "top", + "containerId": null, + "originalText": "Sensor starved", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "B_AHKsGjU50UOOJd065ut", + "type": "rectangle", + "x": 760, + "y": 500, + "width": 60.000000000000014, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "am", + "roundness": { + "type": 3 + }, + "seed": 1528943004, + "version": 44, + "versionNonce": 1720019868, + "isDeleted": false, + "boundElements": [], + "updated": 1768851018437, + "link": null, + "locked": false + }, + { + "id": "M_RY6AEYGIbEF0Q37mfp2", + "type": "rectangle", + "x": 840, + "y": 500, + "width": 220.00000000000003, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "an", + "roundness": { + "type": 3 + }, + "seed": 1172059292, + "version": 34, + "versionNonce": 2003700388, + "isDeleted": true, + "boundElements": [], + "updated": 1768851021286, + "link": null, + "locked": false + }, + { + "id": "XE5Um7UMKh8ukOmM0k5Tq", + "type": "rectangle", + "x": 840, + "y": 500, + "width": 60.000000000000014, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ao", + "roundness": { + "type": 3 + }, + "seed": 1037675164, + "version": 53, + "versionNonce": 1003507356, + "isDeleted": false, + "boundElements": [], + "updated": 1768851024320, + "link": null, + "locked": false + }, + { + "id": "U9zz4PkOxdLiu6Xhuh6jT", + "type": "rectangle", + "x": 940, + "y": 500, + "width": 160.00000000000003, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ap", + "roundness": { + "type": 3 + }, + "seed": 1142784036, + "version": 52, + "versionNonce": 1021902620, + "isDeleted": false, + "boundElements": [], + "updated": 1768854406600, + "link": null, + "locked": false + }, + { + "id": "h-AEzJBYpYd8SgViHpfGE", + "type": "rectangle", + "x": 1040, + "y": 500, + "width": 60.000000000000014, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aq", + "roundness": { + "type": 3 + }, + "seed": 68832804, + "version": 49, + "versionNonce": 199650588, + "isDeleted": true, + "boundElements": [], + "updated": 1768854403226, + "link": null, + "locked": false + }, + { + "id": "0_n_0OhawRU7VZzyBnc9Y", + "type": "rectangle", + "x": 1180, + "y": 500, + "width": 60.000000000000014, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ar", + "roundness": { + "type": 3 + }, + "seed": 134897316, + "version": 49, + "versionNonce": 1566829732, + "isDeleted": false, + "boundElements": [], + "updated": 1768851037804, + "link": null, + "locked": false + }, + { + "id": "tqELz_BbNn16K3wrubqyC", + "type": "rectangle", + "x": 1260, + "y": 500, + "width": 240.00000000000006, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "as", + "roundness": { + "type": 3 + }, + "seed": 1936943260, + "version": 61, + "versionNonce": 530070812, + "isDeleted": false, + "boundElements": [], + "updated": 1768851045020, + "link": null, + "locked": false + }, + { + "id": "dz3MBPK4Qsz7VRK9RWNhx", + "type": "rectangle", + "x": 1520, + "y": 500, + "width": 40.00000000000001, + "height": 100, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "#ffc9c9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "at", + "roundness": { + "type": 3 + }, + "seed": 1280399780, + "version": 48, + "versionNonce": 539408412, + "isDeleted": false, + "boundElements": [], + "updated": 1768851049904, + "link": null, + "locked": false + }, + { + "id": "LtQsOEKjSClrWY_HUiv85", + "type": "rectangle", + "x": 740, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "au", + "roundness": { + "type": 3 + }, + "seed": 1112103460, + "version": 25, + "versionNonce": 423531044, + "isDeleted": false, + "boundElements": [], + "updated": 1768851059519, + "link": null, + "locked": false + }, + { + "id": "-bBn7OCwEFsqrF8vtqvSW", + "type": "rectangle", + "x": 700, + "y": 600, + "width": 40, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "av", + "roundness": { + "type": 3 + }, + "seed": 1055356828, + "version": 7, + "versionNonce": 1633886884, + "isDeleted": false, + "boundElements": null, + "updated": 1768851074038, + "link": null, + "locked": false + }, + { + "id": "wDFhgKGsP3g0OTgEZfeVb", + "type": "rectangle", + "x": 940, + "y": 600, + "width": 160, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aw", + "roundness": { + "type": 3 + }, + "seed": 1885666340, + "version": 39, + "versionNonce": 1414642212, + "isDeleted": false, + "boundElements": [], + "updated": 1768853310249, + "link": null, + "locked": false + }, + { + "id": "G0u1pQ9vembqAJrOH0TA2", + "type": "rectangle", + "x": 1100, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ax", + "roundness": { + "type": 3 + }, + "seed": 35349796, + "version": 47, + "versionNonce": 754199452, + "isDeleted": false, + "boundElements": [], + "updated": 1768853307015, + "link": null, + "locked": false + }, + { + "id": "e9Z6mFKAW6-pYg8uRG6RL", + "type": "rectangle", + "x": 1240, + "y": 600, + "width": 80, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "ay", + "roundness": { + "type": 3 + }, + "seed": 1622295964, + "version": 99, + "versionNonce": 622220452, + "isDeleted": true, + "boundElements": [], + "updated": 1768851145342, + "link": null, + "locked": false + }, + { + "id": "jtlY02NKqepK_HuOtXl1Q", + "type": "rectangle", + "x": 880, + "y": 760, + "width": 80, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "az", + "roundness": { + "type": 3 + }, + "seed": 1129676956, + "version": 110, + "versionNonce": 819561892, + "isDeleted": true, + "boundElements": [], + "updated": 1768851163928, + "link": null, + "locked": false + }, + { + "id": "E-EFWNvgETdwKs2nOuxLn", + "type": "rectangle", + "x": 1260, + "y": 600, + "width": 100, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b00", + "roundness": { + "type": 3 + }, + "seed": 1174079012, + "version": 58, + "versionNonce": 345709724, + "isDeleted": true, + "boundElements": [], + "updated": 1768851222631, + "link": null, + "locked": false + }, + { + "id": "JrwtBDtjtL0O7rGIzLo4f", + "type": "rectangle", + "x": 1300, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b01", + "roundness": { + "type": 3 + }, + "seed": 104226204, + "version": 60, + "versionNonce": 861292828, + "isDeleted": true, + "boundElements": [], + "updated": 1768853337403, + "link": null, + "locked": false + }, + { + "id": "-g4zpffGuHuoltEf8gUzR", + "type": "rectangle", + "x": 1300, + "y": 600, + "width": 200, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b02", + "roundness": { + "type": 3 + }, + "seed": 1251805340, + "version": 60, + "versionNonce": 1731441180, + "isDeleted": false, + "boundElements": [], + "updated": 1768853341048, + "link": null, + "locked": false + }, + { + "id": "31sEM49fN2skCnFhNBsQx", + "type": "rectangle", + "x": 1500, + "y": 600, + "width": 20, + "height": 100, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b03", + "roundness": { + "type": 3 + }, + "seed": 1321764004, + "version": 47, + "versionNonce": 1679314980, + "isDeleted": false, + "boundElements": [], + "updated": 1768852911427, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": true, + "viewBackgroundColor": "#ffffff", + "lockedMultiSelections": {} + }, + "files": {} +} \ No newline at end of file diff --git a/i2c-starvation-gantt.excalidraw.png b/i2c-starvation-gantt.excalidraw.png new file mode 100644 index 0000000..ddc95db Binary files /dev/null and b/i2c-starvation-gantt.excalidraw.png differ diff --git a/main.typ b/main.typ new file mode 100644 index 0000000..5f98730 --- /dev/null +++ b/main.typ @@ -0,0 +1,196 @@ +#import "@preview/ilm:1.4.2": * + +#set text(lang: "de") + +#show: ilm.with( + title: [Gerätetreiber unter Linux], + author: "Konstantin Veltmann", + date: datetime.today(), + date-format: "[day padding:zero].[month repr:short].[year repr:full]", + raw-text: (use-typst-defaults: true), + bibliography: bibliography("refs.bib"), + figure-index: (enabled: true, title: "Bilderverzeichnis"), +) + +#let link-text(body) = text(blue, body) + +#counter(page).update(1) + += Einleitung +Damit Computersysteme mit der Umwelt interagieren können, muss mit externen Sensoren und Aktoren kommuniziert werden. +Eine der Aufgaben eines Betriebssystems ist es, gemeinsame Schnittstellen für verschiedene Geräte darzustellen; Unter Linux werden dafür sogenannte _device files_ verwendet, so dass über klassische Dateioperationen auf diese Geräte zugegriffen werden kann. + +== Gerätezugriff per Dateisystem + +Nach der UNIX-Philosophie #quote("Everything is a file") melden Gerätetreiber spezielle Dateien im virtuellen Dateisystem an (in der Regel im Verzeichnis `/dev` oder `/sys`). +Wird auf dieser Datei zum Beispiel `write()` aufgerufen, so wird mit den geschriebenen Daten eine Funktion im Kerneltreiber aufgerufen, der sie dann an das physische Gerät weitergibt. + +=== Device-Dateien + +Folgender Beispielcode zeigt die Kommunikation mit einem BME280-Sensor mithilfe des Userspace I²C-Treibers auf einem Raspberry Pi: +```c +int main() { + // Öffne die Device-Datei + int driver = open("/dev/i2c-1"); // (1) + + // Setze die Slave-Addresse, die für die nachfolgenden Transaktionen verwendet wird + ioctl(driver, I2C_SLAVE, 0x76); // (2) + + // Schreibe die Addresse für das ID-Register + uint8_t const write_buf[] = {0xd0}; + write(driver, write_buf, sizeof(write_buf)); // (3) + + // Lese aus dem ID-Register. NOTE: Das ist eine separate I²C-Transaktion! + uint8_t id; + read(driver, &id, 1); // (4) + + printf("ID: %"PRIu8, id); +} +``` + +Der Beispielcode zeigt die vier typischen Datei-Operationen bei der Arbeit mit Device-Dateien: +1. Wie jede Datei muss auch die Device-Datei geöffnet werden. Der Treiber setzt die notwendigen Buchhaltungsstrukturen für eine weitere Anwendung auf. +2. Der `ioctl`-Syscall wird verwendet, um Treibereinstellungen zu ändern oder Operationen auszuführen, die nicht mit `read` oder `write` dargestellt werden können. Die Flags und Parameter für `ioctl` sind treiberabhängig. +3. Der `write`-Syscall sendet eine schreibende Transaktion auf den I²C-Bus. In der Regel wird `write` verwendet, um Daten auf Busse zu schreiben oder Ausgänge zu schalten. +4. `read` führt eine lesende Transaktion auf dem I²C-Bus aus. `read` wird typischerweise verwendet, um Gerätedaten auszulesen oder von Bussen zu empfangen. + +=== Zugriff über Sysfs + +Einige Gerätetreiber registrieren keine Dateien in `/dev`, sondern werden über Dateien im virtuellen Dateisystem unter `/sys` kontrolliert. +Die Konvention dafür ist, dass I/O-Geräte typsicherweise in `/dev` registriert werden, während andere Geräte über `/sys` konfiguriert werden. Außerdem wird `/sys` verwendet um Geräte zu finden. + +Geräte-Dateien in `/sys` haben eine String-basierte Schnittstelle, es werden also Menschenlesbare Werte in verschiedenen Dateien geschrieben. Das macht die Interaktion mit `/sys`-Dateien in der Shell attraktiv. + +Folgender Shell-Code liest die momentane Batteriespannung meines Laptops aus. +```sh +# ADC-Dateien finden, haben i.d.R voltage im Namen +find /sys -iname "*voltage*" +BAT='/sys/devices/[...]/BAT1/voltage_now' # Pfad gekürzt +cat $BAT +# > 12832000 [µV] +``` + +Folgender Shell-Code stellt auf einem #link("https://wiki.banana-pi.org/index.php?title=Banana_Pi_BPI-R3&oldid=17314", link-text[Banana Pi R3]) die Drehgeschwindigkeit des CPU-Kühlers auf 40%: +```sh +echo 40 > /sys/devices/platform/pwm-fan/hwmon/hwmon1/pwm1 +``` + += Beschreibung hardwarespezifischer Schnittstellen unter Linux + +== I²C + +Wie in der Einleitung beschrieben stellt der I²C-Treiber device-Dateien unter `/dev/i2c-*` bereit. +- Implementiert in #link("https://github.com/torvalds/linux/blob/master/drivers/i2c/i2c-dev.c", link-text[`drivers/i2c/i2c-dev.c`]) +- #link("https://www.kernel.org/doc/html/latest/i2c/dev-interface.html", link-text[Offizielle Dokumentation]) + +Implementierte Syscalls: + +#figure( + table( + columns: (auto, 1fr), + align: horizon, + table.header([Syscall], [Funktion]), + [`ioctl(, I2C_SLAVE, )`], [Setzt die Slave-Adresse für alle folgenden I²C-Transaktionen], + [`write(, , )`], [Sendet die Daten aus `buf` in einer einzelnen I²C-Schreib-Operation an die gesetzte Slave-Adresse], + [`read(, , )`], [Liest `len` Bytes vom ausgewählten Slave in `buf`], + [`ioctl(, I2C_RDWR, )`], [Sendet mehrere Schreibe- und Lese-Operationen an den ausgewählten Slave in einer Transaktion ohne Stop-Conditions], + ), + caption: [Systemaufrufe des I²C-Treibers] +) + +In modernen Computersystemen wird der mit I²C kompatible SMBus verwendet. Daher stellt der Treiber noch weitere `ioctls` bereit, die hier jedoch nicht besprochen werden. + +== GPIO + +Der GPIO-Treiber stellt zwei Schnittstellen bereit, eine unter `/dev` und eine veraltete unter `/sys`. Hier wird die aktuelle empfohlene Variante beschrieben. + +- Implementiert in #link("https://github.com/torvalds/linux/blob/master/drivers/gpio/gpiolib-cdev.c", link-text(`drivers/gpio/gpiolib-cdev.c`)); +- #link("https://www.kernel.org/doc/html/latest/userspace-api/gpio/chardev.html", link-text([Offizielle Dokumentation])). + +Implementierte Syscalls: + +#figure( + table( + columns: (auto, 1fr), + align: horizon, + table.header([Syscall], [Funktion]), + [`ioctl(, GPIO_GET_CHIPINFO_IOCTL, )`], [Informationen über einen Gpio-Chip holen], + [`ioctl(, GPIO_GET_LINEINFO_UNWATCH_IOCTL , )`], [Stoppt das Beobachten eines GPIO-Pins], + [`ioctl(, GPIO_V2_GET_LINEINFO_IOCTL, )`], [Beschafft Informationen über einen spezifischen GPIO-Pin], + [`ioctl(, GPIO_V2_GET_LINEINFO_WATCH_IOCTL, )`], [Beschafft Informationen über einen GPIO-Pin und], + [`ioctl(, GPIO_V2_GET_LINE_IOCTL, )`], [Reserviert und konfiguriert einen GPIO-Pin für das aufrufende Programm], + [`ioctl(, GPIO_V2_LINE_SET_CONFIG_IOCTL, )`], [Setzt Attribute für einen Pin, zum Beispiel Input/Output oder active LOW/HIGH], + [`ioctl(, GPIO_V2_LINE_GET_VALUES_IOCTL, )`], [Liest Werte von mehreren Eingangs-Pins], + [`ioctl(, GPIO_V2_LINE_SET_VALUES_IOCTL, )`], [Setzt/Cleared mehrere Ausgangs-Pins], + ), + caption: [Systemaufrufe des GPIO-Treibers] +) + + +== ADC + +ADCs werden in Linux nicht direkt als eigene Geräteklasse verwaltet, sondern sind in der Regel als _Hardware Monitoring_ (Überwachung) oder _Industrial I/O_ (iio). + +Als Beispiel wird hier der Kernel-eigene Treiber für den #link("https://www.kernel.org/doc/html/v6.12/iio/ep93xx_adc.html", link-text[ADC des Cirrus Logic EP93xx SoC]) genutzt. +Hier wird für jeden der ADC-Pins ein eigener Eintrag unter `/sys/bus/iio/devices/iio:device/` angelegt, wobei $N$ die Geräte-ID ist: + + +#figure( + table( + columns: (auto, 1fr), + align: horizon, + table.header([Sysfs-Eintrag], [Pin-Name]), + [in_voltage0_raw], [`Y-`], + [in_voltage1_raw], [`sX+`], + [in_voltage2_raw], [`sX-`], + [in_voltage3_raw], [`sY+`], + [in_voltage4_raw], [`sY-`], + [in_voltage5_raw], [`X+`], + [in_voltage6_raw], [`X-`], + [in_voltage7_raw], [`Y+`], + ), + caption: [Sysfs-Einträge des ADC-Treibers] +) + +Das Auslesen einer dieser Datein startet führt synchron eine ADC-Umwandlung durch und gibt den ganzzahligen µV-Wert als String aus. + += Design einer Hardwareschnittstelle für AT91SAM7-Timer + +Der AT91SAM7-Mikrocontroller stellt das _Timer Counter_ Peripheral bereit; Drei 16-bit Zähler + +== Features + +TODO + += Scheduling bei geteilten Bussystemen + +Angenommen man habe ein smartes Thermostat mit folgenden Sensoren und Aktoren, alle angeschlossen über einen geteilten I²C-Bus: +- OLED-Display +- BME280 Temperatur- und Luftfeuchtigkeitsmesser + +Jedes der Geräte hat einen eigenen Treiber, der über die kerneleigenen I²C-Funktionen auf den Bus zugreift. + +Da Displays typischerweise hohe Datenraten brauchen, verbringt der Display-Treiber viel Zeit auf dem Bus. +Zudem sollen in regelmäßigen Abständen Temperatur und Luftfeuchtigkeit vom Sensor angefragt werden. + +#figure( + image("./i2c-starvation-gantt.excalidraw.png"), + caption: [Gantt-Diagramm des smarten Thermostats], + alt: "A gantt diagram showing process starvation", +) + +Wie in @fig-i2c-starvation gezeigt, wird durch die häufigen Display-Übertragungen der Temperatur-Sensor "ausgehungert" (schraffierter Hintergrund) und kann seine Daten nicht rechtzeitig übertragen. + +Bei geteilten Ressourcen wie Bussen tritt dieses Problem häufig auf, weswegen im nächsten Schritt ein typsicher Lösungsansatz besprochen wird. + +== Lösungsansatz + +Da hier eine geteilte Ressource (der Bus) _fair_ zwischen mehreren Clients (den Treibern) verteilt werden soll, bietet sich ein #link("https://de.wikipedia.org/wiki/Prozess-Scheduler", link-text([Scheduling Verfahren])) an. + +Fragt ein Client einen I²C-Transfer an, so wird er nicht direkt ausgeführt, sondern mit anderen ausstehenden Anfragen in einer Warteschlange (Queue) gespeichert. +Nun kann der I²C-Scheduler die nächste anstehende Transaktion nach einem Scheduling-Verfahren wie dem #link("https://en.wikipedia.org/wiki/Completely_Fair_Scheduler", link-text([Completely Fair Scheduler])) aussuchen und durchführen, um Aushungern zu vermeiden. + +Nachfolgend ist der Ablauf mit dem simplen #link("todo", link-text([Round-Robin-Verfahren])) gezeigt: + +//TODO: + diff --git a/refs.bib b/refs.bib new file mode 100644 index 0000000..e69de29