Compare commits

..

10 Commits

4 changed files with 32 additions and 22 deletions
+28 -17
View File
@@ -85,7 +85,7 @@
<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="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="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="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="129" fill="#d4d8f0" font-size="10">· xSemaphoreGiveFromISR(beepSemaphore) + portYIELD_FROM_ISR</text>
<text x="550" y="129" fill="#d4d8f0" font-size="10">· vTaskNotifyGiveFromISR(beepTaskHandle) + portYIELD_FROM_ISR</text>
<text x="550" y="144" fill="#6b7194" font-size="10"> ← gesamte Beep-Logik jetzt in beepTask</text>
<!-- 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>
<!-- ── 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"/>
<rect x="442" y="98" width="82" height="18" rx="3" fill="#0f1117"/>
<text x="483" y="111" text-anchor="middle" fill="#4f8ef7" font-size="10">beepSemaphore</text>
<rect x="436" y="98" width="90" height="18" rx="3" fill="#0f1117"/>
<text x="481" y="111" text-anchor="middle" fill="#4f8ef7" font-size="10">Task Notification</text>
<!-- 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"/>
<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) -->
<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>
<tr><th>Objekt</th><th>Typ</th><th>Größe</th><th>Produzent (ISR)</th><th>Konsument (Task)</th><th>Zweck</th></tr>
<tr>
<td><span class="tag t-task">beepSemaphore</span></td>
<td>Binary Semaphore</td><td></td>
<td><span class="tag t-isr">timerIsr</span> alle 10 ms</td>
<td><span class="tag t-task">beepTask</span> Core 0, Prio 5</td>
<td>Takt für Beep-State-Machine; ersetzt direkten ISR-Aufruf von PiepPattern::TaskCyclic()</td>
<td><span class="tag t-task">beepTaskHandle</span></td>
<td>Task Notification</td><td>32-bit Zähler im TCB</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<br><code style="font-size:10px">ulTaskNotifyTake(pdTRUE, …)</code></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>
<td><span class="tag t-task">rfEventQueue</span></td>
<td>Queue RfEvent_t</td><td>32 Einträge × 5 B</td>
<td><span class="tag t-isr">pinLevelChangeIsr</span> bei jeder Flanke</td>
<td><span class="tag t-task">rfDecodeTask</span> Core 0, Prio 4</td>
<td>Überträgt {dtMicros, pinValue}; alle 5 Receiver-State-Machines laufen jetzt im Task-Kontext</td>
<td>Queue RfEvent_t</td><td>8 Einträge × 5 B</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<br><code style="font-size:10px">xQueueReceive</code></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>
</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>
<!-- ═══════════════════════════════════════════════════════════
@@ -257,8 +268,8 @@
<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"/>
<text x="200" y="191" text-anchor="middle" fill="#4f8ef7" font-size="10">beepSemaphore</text>
<text x="200" y="205" text-anchor="middle" fill="#6b7194" font-size="10">binary</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">im TCB (kein Objekt)</text>
<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>
+1 -1
View File
@@ -98,7 +98,7 @@ void InterruptHandler_PauseReceive()
}
/**
* Woken every 10 ms by timerIsr via beepSemaphore.
* Woken every 10 ms by timerIsr via task notification.
* Handles short-beep timing and the PiepPattern state machine,
* then drives the buzzer supply pin — work that was previously in timerIsr.
*
+1 -2
View File
@@ -10,8 +10,8 @@
#include "Arduino.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#define ISR_TIME_US (10000uL)
@@ -23,7 +23,6 @@ typedef struct {
bool pinValue;
} RfEvent_t;
extern SemaphoreHandle_t beepSemaphore; /* given every ISR_TIME_US to wake beepTask */
extern QueueHandle_t rfEventQueue; /* RF pulse events for rfDecodeTask */
void InterruptHandler_Init(void);
+1 -1
View File
@@ -17,7 +17,7 @@
#endif
#define PROJECT_NAME "FENSTER_PIEPSER_NODEMCU_32_S_" PROJECT_VARIANT
#define VERSION_STR "_v2.0.8"
#define VERSION_STR "_v3.0.0"
#endif /* VERSION_H_ */