Files
VersaMCU/doc/09_known_limitations.md
T

4.4 KiB

Bekannte Einschränkungen und Risiken

Diese Liste beschreibt den aktuellen Implementierungsstand. Sie ist keine Liste bereits umgesetzter Features.

Flash-Reservierung stimmt nicht vollständig mit dem NVM-Zugriff überein

Die Firmware liest und schreibt:

0x1FB00..0x1FCFF  Makros (512 Byte)
0x1FD00..0x1FFFF  Config (768 Byte, davon 740 Byte genutzt)

Das aktive Linker-Skript flash_without_bootloader.ld erlaubt Firmware jedoch bis einschließlich 0x1FDFF und reserviert nur 0x1FE00..0x1FFFF. Damit sind 0x1FB00..0x1FDFF nicht gegen ein zukünftig wachsendes Firmware-Image geschützt. Das aktuelle Image liegt deutlich darunter, aber der Build prüft diese NVM-Grenze nicht.

Das Bootloader-Linker-Skript reserviert aktuell gar keinen separaten NVM-Bereich. Das auskommentierte USB-Bootloader-Environment ist daher kein unterstütztes Ziel.

Die aktive Boarddatei benennt die MCU als samd21g17d, setzt für den Arduino-Core aber weiterhin das Kompatibilitätsmakro __SAMD21G18A__. Der PlatformIO-Build meldet korrekt 128 KiB Flash und 16 KiB RAM; vor device-spezifischen Änderungen sollte diese historische Makro-Abweichung trotzdem geprüft werden.

Event-Queue hat gemischte Producer

Matrixevents werden im Loop erzeugt, Encoderevents in EIC-Interrupts. Beide rufen CEventQueue::push() auf und verändern denselben Tail-Index ohne Interruptschutz. Ein Encoderinterrupt kann einen Matrix-Push unterbrechen. Die bisherige Annahme eines reinen Single-Producer/Single-Consumer-Ringbuffers ist deshalb nicht vollständig erfüllt; seltene verlorene oder überschriebene Events sind theoretisch möglich.

Zusätzlich werden Events bei voller Queue still verworfen.

HOST_COMMAND nutzt seine data nicht

SAction.data ist für ActionType::HOST_COMMAND vorhanden, wird in execute_action_down() aber nicht übertragen. Gesendet wird nur USB_EVT_KEY_DOWN (0x81) mit der Matrix-Key-ID beziehungsweise Encoder-ID.

USB_EVT_KEY_UP (0x82), USB_EVT_ENC_CW (0x83) und USB_EVT_ENC_CCW (0x84) sind definiert, werden vom aktuellen Controller aber nicht gesendet. Bei Encoder-Host-Actions geht dadurch die Richtung im gesendeten Paket verloren, sofern die Host-Anwendung sie nicht anderweitig aus der konfigurierten Action ableitet.

HID-Holds sind global

Der Keyboard-Report enthält zwar sechs Keycode-Felder, die Implementierung setzt aber nur das erste. Jeder neue HID_KEY-Down ersetzt den vorherigen Report; jedes Release sendet einen komplett leeren Report. Analog existiert nur ein globaler Consumer-Usage-Wert. Gleichzeitige unabhängige Holds werden daher nicht korrekt verwaltet.

CDC-Transfers sind nur schwach validiert

  • BEGIN speichert die angekündigte Chunkzahl, COMMIT vergleicht sie aber nicht mit empfangenen Chunks.
  • Doppelte, fehlende oder ungeordnete Chunks werden nicht verfolgt.
  • Config-Commit prüft Magic, Version und CRC, aber keine Feldwerte oder Enum-Bereiche.
  • Makro-Commit hat weder CRC noch Vollständigkeitsprüfung.
  • Das 8-Byte-Protokoll besitzt kein Framing. Ein verlorenes oder zusätzliches Byte desynchronisiert alle folgenden Pakete.

Insbesondere kann ein formal CRC-korrektes Profil ungültige Animationswerte enthalten. PULSE benötigt in der aktuellen Arithmetik eine Periode von mindestens 2 ms; dieser Mindestwert wird nicht validiert.

Farbanimationen umgehen Teile der Helligkeits-/Override-Logik

Globale und LED-spezifische Helligkeit werden beim Laden in die Base-Farbe eingerechnet. COLOR_CYCLE berechnet RGB dagegen direkt mit festen 40 % Helligkeit und ignoriert Base-Farbe sowie Override. COLOR_FADE benötigt den separaten Aufruf set_color_fade(); das reine Laden des Enum-Werts aus einer Config setzt keine Start- und Zielfarbe.

Reservierte beziehungsweise noch ungenutzte Hardware und Felder

  • Die drei Fader-Pins sind im Variant und in config/pins.h definiert, werden von der Firmware aber nicht eingelesen.
  • enc_sensitivity[4] wird gespeichert und mit Default 1 befüllt, beeinflusst die Encoderdekodierung derzeit aber nicht.
  • SET_LED_BASE verändert nur den RAM-Zustand und wird nicht in NVM persistiert.

Zeitverhalten

Makros und Encoder-Taps verwenden blockierende delay()-Aufrufe. Startsignal, Werksreset-Feedback und NVM-Operationen blockieren ebenfalls den Loop. Während dessen werden Matrix und CDC nicht bearbeitet; Encoder-ISRs können weiter Events erzeugen, bis die Queue voll ist.