@@ -85,7 +85,7 @@
< rect x = "50" y = "76" width = "380" height = "90" rx = "6" fill = "#1a2240" stroke = "#4f8ef7" stroke-width = "1" / >
< rect x = "50" y = "76" width = "380" height = "90" rx = "6" fill = "#1a2240" stroke = "#4f8ef7" stroke-width = "1" / >
< text x = "70" y = "96" fill = "#4f8ef7" font-size = "12" font-weight = "bold" > beepTask< / text >
< text x = "70" y = "96" fill = "#4f8ef7" font-size = "12" font-weight = "bold" > beepTask< / text >
< text x = "380" y = "96" text-anchor = "end" fill = "#6b7194" font-size = "10" > Prio 5 · Core 0 · Stack 2 KB< / text >
< text x = "380" y = "96" text-anchor = "end" fill = "#6b7194" font-size = "10" > Prio 5 · Core 0 · Stack 2 KB< / text >
< text x = "70" y = "114" fill = "#d4d8f0" font-size = "10" > · Wartet auf beepSemaphore (gegeben alle 10 ms von timerIsr)< / text >
< text x = "70" y = "114" fill = "#d4d8f0" font-size = "10" > · Wartet auf Task Notification (gegeben alle 10 ms von timerIsr)< / text >
< text x = "70" y = "129" fill = "#d4d8f0" font-size = "10" > · Short-Beep-Timing (30 ms Puls)< / text >
< text x = "70" y = "129" fill = "#d4d8f0" font-size = "10" > · Short-Beep-Timing (30 ms Puls)< / text >
< text x = "70" y = "144" fill = "#d4d8f0" font-size = "10" > · PiepPattern::TaskCyclic() → PiepMode → toneRequest → GPIO18< / text >
< text x = "70" y = "144" fill = "#d4d8f0" font-size = "10" > · PiepPattern::TaskCyclic() → PiepMode → toneRequest → GPIO18< / text >
@@ -120,7 +120,7 @@
< text x = "550" y = "96" fill = "#f75f5f" font-size = "12" font-weight = "bold" > timerIsr< / text >
< text x = "550" y = "96" fill = "#f75f5f" font-size = "12" font-weight = "bold" > timerIsr< / text >
< text x = "900" y = "96" text-anchor = "end" fill = "#6b7194" font-size = "10" > hw_timer 0 · 1 MHz · Alarm 10 000 µs< / text >
< text x = "900" y = "96" text-anchor = "end" fill = "#6b7194" font-size = "10" > hw_timer 0 · 1 MHz · Alarm 10 000 µs< / text >
< text x = "550" y = "114" fill = "#d4d8f0" font-size = "10" > · ++count; if count==10 → tDecis++ (volatile)< / text >
< text x = "550" y = "114" fill = "#d4d8f0" font-size = "10" > · ++count; if count==10 → tDecis++ (volatile)< / text >
< text x = "550" y = "129" fill = "#d4d8f0" font-size = "10" > · xSemaphore GiveFromISR(beepSemaphor e) + portYIELD_FROM_ISR< / text >
< text x = "550" y = "129" fill = "#d4d8f0" font-size = "10" > · vTaskNotify GiveFromISR(beepTaskHandl e) + portYIELD_FROM_ISR< / text >
< text x = "550" y = "144" fill = "#6b7194" font-size = "10" > ← gesamte Beep-Logik jetzt in beepTask< / text >
< text x = "550" y = "144" fill = "#6b7194" font-size = "10" > ← gesamte Beep-Logik jetzt in beepTask< / text >
<!-- pinLevelChangeIsr -->
<!-- pinLevelChangeIsr -->
@@ -146,15 +146,15 @@
< text x = "550" y = "409" fill = "#d4d8f0" font-size = "10" > 9 vTaskDelay(5 ms) – gibt Core 1 für ISRs frei< / text >
< text x = "550" y = "409" fill = "#d4d8f0" font-size = "10" > 9 vTaskDelay(5 ms) – gibt Core 1 für ISRs frei< / text >
<!-- ── FreeRTOS Primitives ── -->
<!-- ── FreeRTOS Primitives ── -->
<!-- beepSemaphore arrow: timerIsr → beepTask -->
<!-- Task Notification arrow: timerIsr → beepTask -->
< line x1 = "530" y1 = "108" x2 = "432" y2 = "108" stroke = "#4f8ef7" stroke-width = "1.5" marker-end = "url(#arr)" stroke-dasharray = "5,3" / >
< line x1 = "530" y1 = "108" x2 = "432" y2 = "108" stroke = "#4f8ef7" stroke-width = "1.5" marker-end = "url(#arr)" stroke-dasharray = "5,3" / >
< rect x = "442 " y = "98" width = "82 " height = "18" rx = "3" fill = "#0f1117" / >
< rect x = "436 " y = "98" width = "90 " height = "18" rx = "3" fill = "#0f1117" / >
< text x = "483 " y = "111" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > beepSemaphore < / text >
< text x = "481 " y = "111" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > Task Notification < / text >
<!-- rfEventQueue arrow: pinLevelChangeIsr → rfDecodeTask -->
<!-- rfEventQueue arrow: pinLevelChangeIsr → rfDecodeTask -->
< line x1 = "530" y1 = "210" x2 = "432" y2 = "218" stroke = "#4f8ef7" stroke-width = "1.5" marker-end = "url(#arr)" stroke-dasharray = "5,3" / >
< line x1 = "530" y1 = "210" x2 = "432" y2 = "218" stroke = "#4f8ef7" stroke-width = "1.5" marker-end = "url(#arr)" stroke-dasharray = "5,3" / >
< rect x = "438" y = "207" width = "82" height = "18" rx = "3" fill = "#0f1117" / >
< rect x = "438" y = "207" width = "82" height = "18" rx = "3" fill = "#0f1117" / >
< text x = "479" y = "220" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > rfEventQueue[32 ]< / text >
< text x = "479" y = "220" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > rfEventQueue[8 ]< / text >
<!-- receiver state arrow: rfDecodeTask → loop (dashed green) -->
<!-- receiver state arrow: rfDecodeTask → loop (dashed green) -->
< line x1 = "430" y1 = "242" x2 = "530" y2 = "310" stroke = "#3ecf8e" stroke-width = "1" marker-end = "url(#arr-g)" stroke-dasharray = "4,3" / >
< line x1 = "430" y1 = "242" x2 = "530" y2 = "310" stroke = "#3ecf8e" stroke-width = "1" marker-end = "url(#arr-g)" stroke-dasharray = "4,3" / >
@@ -170,20 +170,31 @@
< table >
< table >
< tr > < th > Objekt< / th > < th > Typ< / th > < th > Größe< / th > < th > Produzent (ISR)< / th > < th > Konsument (Task)< / th > < th > Zweck< / th > < / tr >
< tr > < th > Objekt< / th > < th > Typ< / th > < th > Größe< / th > < th > Produzent (ISR)< / th > < th > Konsument (Task)< / th > < th > Zweck< / th > < / tr >
< tr >
< tr >
< td > < span class = "tag t-task" > beepSemaphor e< / span > < / td >
< td > < span class = "tag t-task" > beepTaskHandl e< / span > < / td >
< td > Binary Semaphore < / td > < td > – < / td >
< td > Task Notification < / td > < td > 32-bit Zähler im TCB < / td >
< td > < span class = "tag t-isr" > timerIsr< / span > alle 10 ms< / td >
< td > < span class = "tag t-isr" > timerIsr< / span > alle 10 ms< br > < code style = "font-size:10px" > vTaskNotifyGiveFromISR < / code > < / td >
< td > < span class = "tag t-task" > beepTask< / span > Core 0, Prio 5< / td >
< td > < span class = "tag t-task" > beepTask< / span > Core 0, Prio 5< br > < code style = "font-size:10px" > ulTaskNotifyTake(pdTRUE, …) < / code > < / td >
< td > Takt für Beep-State-Machine; ersetzt direkten ISR-Aufruf von PiepPattern::TaskCyclic() < / td >
< td > Takt für Beep-State-Machine. Kein Heap-Objekt nötig, schneller als Semaphore. pdTRUE = Zähler nach Take auf 0 → verhält sich wie Binary Semaphore. < / td >
< / tr >
< / tr >
< tr >
< tr >
< td > < span class = "tag t-task" > rfEventQueue< / span > < / td >
< td > < span class = "tag t-task" > rfEventQueue< / span > < / td >
< td > Queue – RfEvent_t< / td > < td > 32 Einträge × 5 B< / td >
< td > Queue – RfEvent_t< / td > < td > 8 Einträge × 5 B< / td >
< td > < span class = "tag t-isr" > pinLevelChangeIsr< / span > bei jeder Flanke< / td >
< td > < span class = "tag t-isr" > pinLevelChangeIsr< / span > bei jeder Flanke< br > < code style = "font-size:10px" > xQueueSendFromISR < / code > < / td >
< td > < span class = "tag t-task" > rfDecodeTask< / span > Core 0, Prio 4< / td >
< td > < span class = "tag t-task" > rfDecodeTask< / span > Core 0, Prio 4< br > < code style = "font-size:10px" > xQueueReceive < / code > < / td >
< td > Überträgt {dtMicros, pinValue}; alle 5 Receiver-State-Machines laufen jetzt im Task-Kontext < / td >
< td > Überträgt {dtMicros, pinValue}. dtMicros wird in der ISR gemessen und by-value kopiert — Task decodiert den gespeicherten Wert, kein erneutes micros() nötig. Queue statt Notification, weil Nutzdaten übertragen werden. < / td >
< / tr >
< / tr >
< / table >
< / table >
< div style = "margin-top:14px;" >
< div style = "color:var(--orange);font-size:11px;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;" > Wann Semaphore statt Task Notification?< / div >
< table >
< tr > < th > Situation< / th > < th > Grund< / th > < / tr >
< tr > < td > Mehrere Tasks warten auf dasselbe Ereignis< / td > < td > Task Notification ist 1:1 — ein Handle, ein Empfänger< / td > < / tr >
< tr > < td > Mutex / gegenseitiger Ausschluss< / td > < td > < code > xSemaphoreCreateMutex()< / code > mit Priority Inheritance; Notification hat keine Mutex-Semantik< / td > < / tr >
< tr > < td > Produzent soll Feedback erhalten wenn voll< / td > < td > Counting Semaphore meldet < code > errQUEUE_FULL< / code > ; Notification-Zähler läuft lautlos über< / td > < / tr >
< tr > < td > Signalgeber kennt Empfänger nicht< / td > < td > Semaphore ist ein eigenständiges Objekt das man übergeben kann; Notification braucht < code > TaskHandle_t< / code > < / td > < / tr >
< / table >
< / div >
< / section >
< / section >
<!-- ═══════════════════════════════════════════════════════════
<!-- ═══════════════════════════════════════════════════════════
@@ -257,8 +268,8 @@
< text x = "70" y = "205" text-anchor = "middle" fill = "#6b7194" font-size = "10" > 10 ms · Core 1< / text >
< text x = "70" y = "205" text-anchor = "middle" fill = "#6b7194" font-size = "10" > 10 ms · Core 1< / text >
< rect x = "150" y = "175" width = "100" height = "40" rx = "5" fill = "#1a2240" stroke = "#4f8ef7" stroke-width = "1" / >
< rect x = "150" y = "175" width = "100" height = "40" rx = "5" fill = "#1a2240" stroke = "#4f8ef7" stroke-width = "1" / >
< text x = "200" y = "191" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > beepSemaphore < / text >
< text x = "200" y = "191" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > Task Notification < / text >
< text x = "200" y = "205" text-anchor = "middle" fill = "#6b7194" font-size = "10" > binary < / text >
< text x = "200" y = "205" text-anchor = "middle" fill = "#6b7194" font-size = "10" > im TCB (kein Objekt) < / text >
< rect x = "280" y = "175" width = "100" height = "40" rx = "5" fill = "#1a2240" stroke = "#4f8ef7" stroke-width = "1" / >
< rect x = "280" y = "175" width = "100" height = "40" rx = "5" fill = "#1a2240" stroke = "#4f8ef7" stroke-width = "1" / >
< text x = "330" y = "191" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > beepTask< / text >
< text x = "330" y = "191" text-anchor = "middle" fill = "#4f8ef7" font-size = "10" > beepTask< / text >