Forum: Mikrocontroller und Digitale Elektronik Wie teste ich (schnell) Funktionen aus STM32CubeIDE - ohne Hardware und Debugger?


von Gunnar F. (gufi36)


Lesenswert?

Hi, ich schreibe gerade auf dem STM32F446VET eine Applikation, die 
Kommandos über UART vom HOST-PC erhält, diese abarbeitet und Antworten 
zurück sendet. Bin dabei, die Kommandostrukturen, den Parser und die 
Ausführungsschichten zu schreiben. Da steckt viel ANSI C (strtok_r, 
atoi, etc.) drin, wo ich alles andere als sattelfest bin.
Das im Debug zu testen, ist aufwendig, zumal auch die Host-App in C# 
noch in der Mache ist. Also müsste ich da vom Terminal aus senden.
Wie kann ich Teile dieser App (.c/.h) Module woandershin auslagern und 
dort auf die Schnelle austesten? Habe das schonmal in Code::Blocks 
probiert, war aber auch alles andere als straightforward.
Kennt jemand hier solche Tricks? Kann ich in der CubeIDE auch ein 
C-Projekt mit MinGW aufsetzen und das gschwind in der Konsole ausgeben 
lassen?
Danke an die Experten der Tafelrunde!
von Vanye R. (vanye_rijan)


Lesenswert?

> Bin dabei, die Kommandostrukturen, den Parser und die
> Ausführungsschichten zu schreiben.

Als ich sowas das letztemal brauchte habe ich mir das von flex schreiben 
lassen. .-)

Vanye
von Frank K. (fchk)


Lesenswert?

Du kannst das auf Deinem PC testen. Die hardwareabhängigen Funktionen 
(UART,...) kapselst Du in Funktionen, und Dein Parser wird auf dem PC 
genauso funktionieren wie auf dem STM32. Auf dem PC kannst Du in der 
Regel besser und einfacher testen, ohne den Code jedesmal hochzuladen.

Da Du auch C# Code hast: Das Visual Studio sollte eigentlich auch C Code 
veraerbeiten können. Eventuell musst Du die passenden Teile 
nachinstallieren.

fchk
von Andreas M. (amesser)


Lesenswert?

Wenn dein Code anständig gekapselt ist und keine Abhängigen zu den STM 
Libraries hat, dann kanns Du den einfach zusammen mit Testcode in eine 
Ausführbare Detei für deinen PC kompilieren und dort starten.

Nennt man UnitTest.
von N. M. (mani)


Lesenswert?

Frank K. schrieb:
> Du kannst das auf Deinem PC testen.

Genau so würde ich das auch machen.

Kapseln über eine HAL und dann Unittest schreiben die du auf dem PC 
laufen lassen kannst.

Musst du dir halt die ganzen Szenarien überlegen die dir einfallen. Zu 
kurz, zu lang, Wertebereiche, Terminierungen usw.
: Bearbeitet durch User
von Gunnar F. (gufi36)


Lesenswert?

Danke, bin gerade dabei das zu versuchen, mit MSYS2 und VSCode. Mal 
sehen, ob die Module sauber gekapselt sind, aber ich glaube schon. Die 
Befehlshandler enthalten HAL-Befehle.
von Ulrich (Firma: DC3AX) (uprinz)


Lesenswert?

Warum schreibt man eine M2M Kommunikation in einer Art und Weise, dass 
sie String-Vergleiche benötigt? Habt Ihr da Vorgaben, dass es 
Menschenlesbar sein muss oder wollt Ihr die Befehle per Terminal 
emulieren können?

Ich frage nur, weil es wirklich viel viel effizienter geht, wenn man 
sich in Pointer Tabellen und Function-Pointer einarbeitet. Danach geht 
alles sehr viel schneller und vor allem sehr sicher.
von Gunnar F. (gufi36)


Lesenswert?

Ulrich schrieb:
> Ich frage nur,

Ich verstehe deine Frage nicht so recht. Ich habe eine Struct für 
Commands:
1
const Command_t myCommands[] =
2
{
3
    {  .code = 'K',
4
      .name = "Relais",
5
      .handler = switch_relay,
6
    },
7
    {  .code = 'V',    // immer mit Strom
8
      .name = "Voltage",
9
      .handler = get_volt,
10
    }, etc...
jedes Command hat seinen Funktionszeiger auf das was ich Handler nannte. 
Aber zunächst bearbeitet der Parser den empfangenen String vom Port und 
separiert die Parameter, übergibt dann an den Handler.
von Gunnar F. (gufi36)


Lesenswert?

Ulrich schrieb:
> Habt Ihr da Vorgaben, dass es
> Menschenlesbar sein muss oder wollt Ihr die Befehle per Terminal
> emulieren können?

P.S.: Ja, letzteres. Ich finde es gut, wenn ich an der Anlage, eben an 
der Steuersoftware vorbei, Kommandos auslösen kann.
von Nemopuk (nemopuk)


Lesenswert?

Gunnar F. schrieb:
> Kann ich in der CubeIDE auch ein
> C-Projekt mit MinGW aufsetzen und das gschwind in der Konsole ausgeben
> lassen?

Theoretisch müsste das gehen, denn die IDE besteht im Kern aus Eclipse 
mit dem CDT Plugin. Schaue dir dessen Doku an. 
https://projects.eclipse.org/projects/tools.cdt
: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Gunnar F. schrieb:
> Kann ich in der CubeIDE auch ein
> C-Projekt mit MinGW aufsetzen und das gschwind in der Konsole ausgeben
> lassen?

Ja das hab ich schon oft genau so gemacht.

Falls du von der klassischen STM32CubeIDE auf VS Code umsteigst, hier 
ein Tutorial für ein modernes Setup mit VS Code:

https://github.com/Erlkoenig90/VSCodeCMakeDemo

Das geht auch parallel in der selben VS Code Instanz die für STM32 
genutzt wird.
von Nick (b620ys)


Lesenswert?

Gunnar F. schrieb:
> Wie kann ich Teile dieser App (.c/.h) Module woandershin auslagern und
> dort auf die Schnelle austesten?

Lobenswerte Herangehensweise!
Das Ding hat auch einen Namen "Test driven developpment".
Dafür gibts auch ein passendes Buch, das du dir evtl. anschauen 
solltest:
...
Scheißlangen Amazon-Link gelöscht
...

"Test Driven Development for Embedded C". Von J.W. Grenning. Das 
verwendet aber das Ziel als Plattform. Nicht tragisch, die Techniken 
sind gleich.

Wenn du eine andere Plattform verwendest, achte penibel darauf, dass die 
Typen gleich sind. Also keine int. -> <stdint.h>
von Jonas W. (bitschubser101)


Lesenswert?

Mit minicom (https://linux.die.net/man/1/minicom) kann man einfache 
Kommunikation automatisieren (https://linux.die.net/man/1/runscript). 
Damit habe ich besonders mit dem expect Schlüsselwort im Kontext 
AT-Kommandos gute Erfahrungen gemacht.

Nick schrieb:
> "Test Driven Development for Embedded C". Von J.W. Grenning. Das
> verwendet aber das Ziel als Plattform. Nicht tragisch, die Techniken
> sind gleich.

Das Buch kann ich für komplexere Fälle nur empfehlen.
: Bearbeitet durch User
von Nick (b620ys)


Lesenswert?

NICHT ernst gemeint:
DA10 von W&G
https://www.amikon-shop.de/messtechnik/da10-datenanalysator-wandel-goltermann/a-2921

Wenn das Timing wichtig ist und Antworten innerhalb einer gegebenen 
Zeit.
Hatte ich tatsächlich vor nicht mal 10 Jahren verwendet für ein 
komplexeres Protokoll. Aber nur zu Anfang. :-))
Ihr dürft gerne auch lachen!
von Ulrich (Firma: DC3AX) (uprinz)


Lesenswert?

Gunnar F. schrieb:
> jedes Command hat seinen Funktionszeiger auf das was ich Handler nannte.
> Aber zunächst bearbeitet der Parser den empfangenen String vom Port und
> separiert die Parameter, übergibt dann an den Handler.

Cool! Genauso dachte ich mir das und habe das auch selbst schon so 
gemacht. Auch Misch-Zugriff geht, also ein Maschinen-Code als Befehl, 
aber parallel ein Token für eine Serielle Schnittstelle um Befehle zu 
testen. Da habe ich aber drauf geachtet, dass die Befehle z.B. nur 3 
Buchstaben interpretierten. Der Eingabe war es egal, es wurden immer nur 
die ersten drei Zeichen verglichen (strncmp). Schlank, nachvollziehbar 
und funktioniert völlig ohne Script Generatoren oder teure 
Zukauf-Testsoftware. Aber natürlich funktioniert es auch mit Teststand 
o.ä.
von Gunnar F. (gufi36)


Lesenswert?

Ulrich schrieb:
> Da habe ich aber drauf geachtet, dass die Befehle z.B. nur 3
> Buchstaben interpretierten.

Bei mir ists zur Zeit nur der erste als Kennbuchstaben. Ich werde wohl 
mit 26 Befehlen auskommen.
Zu meiner Ursprungsfrage: Ich habe etliche Stunden verbracht, zunächst 
in VSCode zu testen. Jetzt bin ich mit dem Ding noch überhaupt nicht 
klar gekommen, ich musste in der Windows11 Command Shell manuell die 
Befehle zum Compile/Build/Run eingeben. DAS ist eigentlich das Vorgehen, 
zu dem ich nicht mehr zurück will. Dasselbe in der WindowsPowerShell 
ging nicht (wegen Berechtigungen?) und in der neu installierten 
MSYS2-Bash auch nicht.
Also bin ich zurück zu CodeBlocks, testete dort etwas (endlich wieder 
einen Button für build und debug!).
Nur habe ich letztendlich damit keine Zeit gespart. Inzwischen läuft die 
Firmware auf dem Target Board, parst die Befehle richtig und antwortet. 
Jetzt geht es Schritt für Schritt weiter, muss ich den Allegro ACS37800 
ansteuern und auslesen. Damit fange ich ziemlich von Null an.

Aber vielen Dank für Eure Hinweise! So richtiges "Test driven 
development" mache ich sicher noch nicht. Aber ich teste sorgfältiger 
und mache intern bessere Fehlerbehandlung als früher.
von Rainer W. (rawi)


Lesenswert?

Nick schrieb:
> Dafür gibts auch ein passendes Buch, das du dir evtl. anschauen
> solltest:
> ...
> Scheißlangen Amazon-Link gelöscht
> ...
>
> "Test Driven Development for Embedded C". Von J.W. Grenning.

Du brauchst ihn nicht selber abzutippen. Copy & Paste wurde bereits 
erfunden.
https://www.amazon.de/dp/193435662X
von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

Zur Buchempfehlung "Test Driven Development for Embedded C":

>> "Test Driven Development for Embedded C". Von J.W. Grenning. Das
>> verwendet aber das Ziel als Plattform. Nicht tragisch, die Techniken
>> sind gleich.
>
> Das Buch kann ich für komplexere Fälle nur empfehlen.

Gibbets das noch in "neu"?
Ich find das jetzt als Taschenbuch nur gebraucht von 2014.
Es gibt auch 2011, ist aber nicht wirklich ein Hinderniss für mich.
von Nick (b620ys)


Lesenswert?

von Bradward B. (Firma: Starfleet) (ltjg_boimler)


Lesenswert?

> ZVAB ist immer ein guter Tip.

Danke für den Hinweis, da steht jetzt auch 2011, ich geh inzwischen 
davon aus, das es 2014 nicht wirklich eine neue Edition gegeben hat.

ZVAB merk ich mir, da steht zwar kein Liefertag vorne (wie bei großen 
A), ist aber bei diesen Auslandseditionen eh ein wenig Glücksspiel.

So jetzt heisst es "Warten auf den Postmann" ...
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Für Unit-Tests ist CppUTest ganz passabel, das kann man sowohl auf dem 
PC/Server als auch auf dem MCU laufen lassen. Kann man dann z.B. in eine 
CI-Pipeline integrieren sodass man seine Unit-Tests bei jedem Commit 
automatisch in der Cloud laufen lassen kann, ggf. auch im ARM-Emulator 
(z.B. qemu). Per eigenem CI-Runner könnte man die Unit-Tests auch 
automatisch auf einen MCU flashen und laufen lassen.
von Nick (b620ys)


Lesenswert?

Bradward B. schrieb:
> ZVAB merk ich mir, da steht zwar kein Liefertag vorne (wie bei großen
> A), ist aber bei diesen Auslandseditionen eh ein wenig Glücksspiel.

ZVAB ist eine Vereinigung von Antiquariaten, also hunderte Händler. 
Bisher war ich immer zufrieden. Ich hab da schon mehrfach gekauft, immer 
zügige Lieferung. Wenns aus dem Ausland kommt (hatte ich einmal? 
Canada?), k.A. wie lange es dann dauert.

Da findet man auch DDR-Literatur, die bei Fachbüchern durchaus 
vorteilhaft sein kann.
Da kann man auch schön stöbern. :-))
von Martin S. (strubi)


Lesenswert?

Ich schmeiss mal noch `Renode` rein. Ist eigentlich hier im Hause das 
Tool für Software/Hardware-Verifikation geworden. STM32-Peripherie deckt 
das ganz gut ab und die Unit-Tests kriegt man per Python/Robot für umme.

Nur so als Anmerkung, wenn der TE unbedingt ein eigenes Protokoll 
entwickeln "muss": strcmp(), strtok() usw. sind perfekte Stolperfallen 
was Exploits oder instabiles Verhalten angeht. Mit valgrind findet man 
die recht gut, mit Safety-Relevanz würde ich von der libc ganz absehen.
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Martin S. schrieb:
> Nur so als Anmerkung, wenn der TE unbedingt ein eigenes Protokoll
> entwickeln "muss": strcmp(), strtok() usw. sind perfekte Stolperfallen
> was Exploits oder instabiles Verhalten angeht.

Ich benutze ASCII basierte Protokolle nur wenn es unbedingt sein muss, 
allein schon wegen DMA - wenn man das Ende eines Befehls/Pakets z.B. nur 
am Zeilenende erkennt, kann man nicht das ganze Paket effizient per DMA 
empfangen weil man die Länge ja nicht im Voraus kennt. Klar kann man die 
Länge als ASCII-Zahl zu Beginn mit senden, aber deren Länge ist ja auch 
wieder variabel...

Ein gutes Beispiel sind die U-Blox GPS Empfänger: Die unterstützen neben 
dem textbasierten Standard-NMEA Protokoll noch das selbstdefinierte 
UBX-Protokoll. Bei NMEA muss man jedes Byte einzeln empfangen und 
analysieren um das Ende zu erkennen, und dann per strtok, atoi usw. den 
String zerlegen. Bei UBX kann man die ersten 6 Bytes am Stück per DMA 
empfangen, die Länge extrahieren, dann das ganze restliche Paket per DMA 
empfangen; macht also 2 Interrupts pro Paket. Die Paketinhalte sind 
binär, man kann also direkt in ein "struct" hinein empfangen lassen und 
dieses direkt auslesen (sofern Byteorder usw. kompatibel ist) ganz ohne 
stoi, atoi usw. Das kann man sich in deren interface description 
anschauen.

Solche binären Protokolle sind meist wesentlich einfacher und 
effizienter umsetzbar, und weil man keine Unmengen an 
Fallunterscheidungen braucht zur Korrektheitsprüfung der Pakete (hab ich 
jetzt ein Komma nach der Zahl oder nicht?) ist es auch stabiler.
von Gunnar F. (gufi36)


Lesenswert?

Niklas G. schrieb:
> Solche binären Protokolle sind meist wesentlich einfacher und
> effizienter umsetzbar, und weil man keine Unmengen an
> Fallunterscheidungen braucht zur Korrektheitsprüfung der Pakete (hab ich
> jetzt ein Komma nach der Zahl oder nicht?) ist es auch stabiler.

Das glaube ich gerne, aber mein F446 hat 99% Langeweile und ich finde es 
gut, wenn ich die Protokolle mitlesen kann und auch einfach vom HTerm 
tippen, mir wiederum meine Steuerung menschenverständliche Antworten 
gibt.

Martin S. schrieb:
> Nur so als Anmerkung, wenn der TE unbedingt ein eigenes Protokoll
> entwickeln "muss": strcmp(), strtok() usw. sind perfekte Stolperfallen
> was Exploits oder instabiles Verhalten angeht. Mit valgrind findet man
> die recht gut, mit Safety-Relevanz würde ich von der libc ganz absehen.

Das klingt wie von einem echten Profi gesprochen. Ich bin ja nur so ein 
als solcher getarnter!
Zum Empfang verwende ich jetzt:
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t *)rx_buffer, RXBUFSIZE);

Andererseits ist eine Anlage desselben Entwicklers mit noch 
unbedarfterer Protokollabwicklung seit 3 Jahren im täglichen 
Produktionsbetrieb und funktioniert immer (echt jetzt?) fehlerfrei. 
Allerdings hatte ich da USB_CDC und dessen Empfangsroutine verwendet.
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Gunnar F. schrieb:
> wenn ich die Protokolle mitlesen kann und auch einfach vom HTerm tippen,

Man kann sich auch eine simple eigene PC-Anwendung bauen, die das 
Protokoll sendet / empfängt. Solche 0815-Sachen sind auch dank KI 
blitzschnell umgesetzt.

Gunnar F. schrieb:
> :
> HAL_UARTEx_ReceiveToIdle_DMA

Dann musst du aber ganz sicher sein, dass die Gegenstelle keine Pausen 
zwischendurch macht, oder die wieder manuell abhandeln und Fragmente 
zusammensetzen. Und damit leben dass Pakete ggf. zu spät bearbeitet 
werden, wenn mehrere Pakete direkt hintereinander kommen, und die dann 
wieder auseinander dröseln zu müssen.

Gunnar F. schrieb:
> USB_CDC

Wenn man sowieso USB nutzt kann man sich zunutze machen dass USB-Pakete 
ein explizites Ende haben, und somit die ganze Problematik mit der 
Längenerkennung sparen. Geht aber nicht per CDC, weil die CDC -Treiber 
auf PC-Seite die Pakete beliebig aufspalten. Mit einem eigenen 
USB-Protokoll geht das besser und letztlich sehr einfach und stabil - 
man bekommt einen fertigen Datenblock geliefert der das ganze Paket ist, 
inkl. Prüfsummencheck, Flusskontrolle usw. Wenn der dann noch binär 
kodiert ist, spart man sich auch die Fummelei mit strtok etc.

Gunnar F. schrieb:
> immer (echt jetzt?) fehlerfrei

Ging es nicht in dem ganzen Thread darum, die Protokollbehandlung mit 
strtok testen zu können, eben weil es so kompliziert ist das fehlerfrei 
umzusetzen? Bei Binärprotokollen ist das so einfach, dass sich diese 
Testerei nahezu erübrigt.
: Bearbeitet durch User
von Gunnar F. (gufi36)


Lesenswert?

Niklas G. schrieb:
> Man kann sich auch eine simple eigene PC-Anwendung bauen, die das
> Protokoll sendet / empfängt. Solche 0815-Sachen sind auch dank KI
> blitzschnell umgesetzt.

Habe ich ja. Hat trotz NI auch nicht so schrecklich lange gedauert.

Niklas G. schrieb:
> Wenn man sowieso USB nutzt kann man sich zunutze machen dass USB-Pakete
> ein explizites Ende haben, und somit die ganze Problematik mit der
> Längenerkennung sparen. Geht aber nicht per CDC, weil die CDC -Treiber
> auf PC-Seite die Pakete beliebig aufspalten. Mit einem eigenen
> USB-Protokoll geht das besser und letztlich sehr einfach und stabil -
> man bekommt einen fertigen Datenblock geliefert der das ganze Paket ist,
> inkl. Prüfsummencheck, Flusskontrolle usw. Wenn der dann noch binär
> kodiert ist, spart man sich auch die Fummelei mit strtok etc.

Deine Aussagen klingen, als weißt du gut, wovon du sprichst.
Für die erste Anlage verwendete ich CDC, weil der BluePill halt einen 
USB-Port hat und ich den mit Erfolg ausprobiert habe.

Für die neue habe ich einen FT232 aufs Board gesetzt, um die Wartbarkeit 
des Steuerrechners (Win11) für unsere IT sicher zu stellen. Mit den 
STM-Treibern gab das schonmal Probleme.

Aber das muss ja auch noch nicht alles in Stein gemeißelt sein. Ich 
teste gerade die ersten 5 Prototypen und werde sehen, was noch kommt.
Graue Haare habe ich eh schon!
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Gunnar F. schrieb:
> Für die erste Anlage verwendete ich CDC, weil der BluePill halt einen
> USB-Port hat und ich den mit Erfolg ausprobiert habe.

Jau, lässt sich eben recht gut auch auf ein natives USB-Protokoll 
umsetellen.

Gunnar F. schrieb:
> Mit den
> STM-Treibern gab das schonmal Probleme.

Die brauchst du überhaupt nicht; wenn du ein eigenes USB-Protokoll 
implementierst, hast du im Prinzip deinen eigenen Treiber, aber: Du 
kannst auch Windows automatisch den WinUSB-Treiber laden lassen und dann 
von der Anwendung aus direkt per libusb zugreifen. Dann musst du 
überhaupt nichts installieren oder konfigurieren, brauchst keine 
Admin-Rechte, funktioniert einfach plug-and-play. Das dürfte die IT 
freuen.

Gunnar F. schrieb:
> Graue Haare habe ich eh schon!

Willkommen im Club, Berufskrankheit 😉
von Martin S. (strubi)


Lesenswert?

Wenn du per *term mit dem Ding schreiben willst, empfiehlt sich 
vielleicht einfach eine shell, die typischerweise direkt ein echo 
zurueckgibt. Dein ACK fuer die interaktive Bedienung, also.
Ansonsten schliesse ich mich erlkoenig an - das Problem, was es zu 
beachten gibt, ist die Synchronisation. Spratzt dir irgendwann mal was 
dazwischen (was allerdings beim USB auf dem Phy noch weitgehend 
abgefedert wird), ist das Front-Back-Gespann schnell mal aus dem 
Konzept. Dann musst du dich mit dem Konzept START/STOP-Transaction Code 
und deren Escape-Codierungen in deinem Datenstrom auseinandersetzen, was 
nicht immer DMA-freundlich ist, oder du musst mit Timeouts und 
paketbasiert arbeiten und bist somit eher besser mit der binaeren 
performanteren Loesung bedient.

Fuers erste haette ich in deinem Fall mal Googles Protobuf angeschmissen 
anstatt das Rad neu zu erfinden.
Wenn es um erweiterte Kontrolle wie Discovery (was kann das Geraet) und 
Vernetzung bzw. Verwaltung von einer ganzen Anlage mit modbus, CAN u.a., 
macht netpp (Network Property Protocol) allenfalls mehr Sinn.
Kommen naemlich immer mal wieder neue Register oder Eigenschaften dazu, 
wird der Unterhalt immer aufwendiger.
von Hans W. (hanswieland)


Lesenswert?

Niklas G. schrieb:
> Klar kann man die Länge als ASCII-Zahl zu Beginn mit senden, aber deren
> Länge ist ja auch wieder variabel...

Lässt sich mit hexadezimaler Darstellung umgehen.
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Hans W. schrieb:
> Lässt sich mit hexadezimaler Darstellung umgehen.

Aber nur wenn man mit Nullen auffüllt, was man auch bei 
Dezimaldarstellung machen kann. Da aber das Ziel war dass man die Daten 
manuell eingeben will, ist das auch eher unhandlich; da kann man auch 
Binärdaten senden. In HTerm geht das super...
von Hans-Georg L. (h-g-l)


Lesenswert?

Niklas G. schrieb:
> Ich benutze ASCII basierte Protokolle nur wenn es unbedingt sein muss,
> allein schon wegen DMA - wenn man das Ende eines Befehls/Pakets z.B. nur
> am Zeilenende erkennt, kann man nicht das ganze Paket effizient per DMA
> empfangen weil man die Länge ja nicht im Voraus kennt. Klar kann man die
> Länge als ASCII-Zahl zu Beginn mit senden, aber deren Länge ist ja auch
> wieder variabel...
>
> Ein gutes Beispiel sind die U-Blox GPS Empfänger: Die unterstützen neben
> dem textbasierten Standard-NMEA Protokoll noch das selbstdefinierte
> UBX-Protokoll. Bei NMEA muss man jedes Byte einzeln empfangen und
> analysieren um das Ende zu erkennen, und dann per strtok, atoi usw. den
> String zerlegen. Bei UBX kann man die ersten 6 Bytes am Stück per DMA
> empfangen, die Länge extrahieren, dann das ganze restliche Paket per DMA
> empfangen; macht also 2 Interrupts pro Paket. Die Paketinhalte sind
> binär, man kann also direkt in ein "struct" hinein empfangen lassen und
> dieses direkt auslesen (sofern Byteorder usw. kompatibel ist) ganz ohne
> stoi, atoi usw. Das kann man sich in deren interface description
> anschauen.
>
> Solche binären Protokolle sind meist wesentlich einfacher und
> effizienter umsetzbar, und weil man keine Unmengen an
> Fallunterscheidungen braucht zur Korrektheitsprüfung der Pakete (hab ich
> jetzt ein Komma nach der Zahl oder nicht?) ist es auch stabiler.

Es geht auch mit ASCII + DMA und unbekannter Länge mit STM32 Chips 
welche "UART IDLE line detection" unterstützen.

Tilen Majerle von STM erklärt es hier genauer wie es geht:
https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Hans-Georg L. schrieb:
> Es geht auch mit ASCII + DMA und unbekannter Länge mit STM32 Chips
> welche "UART IDLE line detection" unterstützen

Ja, da bin ich doch schon drauf eingegangen:

Niklas G. schrieb:
> Dann musst du aber ganz sicher sein, dass die Gegenstelle keine Pausen
> zwischendurch macht, oder die wieder manuell abhandeln und Fragmente
> zusammensetzen. Und damit leben dass Pakete ggf. zu spät bearbeitet
> werden, wenn mehrere Pakete direkt hintereinander kommen, und die dann
> wieder auseinander dröseln zu müssen.

Manche STM32 haben auch beim UART einen Character Match (CM) Interrupt 
der ausgelöst wird wenn ein bestimmtes Zeichen, z.B. Zeilenumbruch, 
empfangen wurde.

Aber allein schon an der Länge des verlinkten Tutorials ist doch zu 
sehen wie umständlich das alles ist, und das nur um ein "ganz einfaches 
ASCII-Paket zu empfangen".

In diesem Sinne:

Gunnar F. schrieb:
> Entwicklers mit noch unbedarfterer Protokollabwicklung seit 3 Jahren

Erfahrene Entwickler versuchen meistens unnötige Komplexität zu 
vermeiden!
von Nick (b620ys)


Lesenswert?

Es muss ja unheimlich komplex sein, ein command-line Interface zu 
programmieren.
Als erstes würde ich mich, wenn ich komplett orientierungslos und 
hilflos wäre, an ModBus ASCII (im Gegensatz zu ModBus RTU) orientieren.

Ich nehme jetzt ModBus ASCII als Beispiel her.

Ja, die Ende-Erkennung ist ein "Problem". Für manche.

Aber erst mal vorne anfangen und synchronisieren. D.h. auf ":" warten. 
(Synchronisieren muss man auch im RTU-Modus).
Dann frägt man zyklisch, ob im Empfangspuffer das erhoffte cr/lf (oder 
was auch immer) ist. Was ist daran so kompliziert? RTU muss auch fragen, 
ob das letzte erhoffte Byte da ist. Thema time-out, Längenüberschreitung 
wenn das Längenbyte fehlerhaft ist.
Den Teil dann rausschneiden und verarbeiten.
Das Kommando selbst kann man unterschiedlich primitiv ermitteln. Bei 
wenigen mit brute force einfach der Reihe nach die 5 verschiedenen 
probieren, oder eleganter per binärer Suche in einer Tabelle mit den 
vorhandenen Befehlen.
bsearch, wer das noch nicht kennt.

Wenn man das ganze als state-machines aufbaut ist die Leserei von der 
Schnittstelle kein Problem, läuft im Hintergrund.
Wenn ein Paket komplett ist, dann bekommt es der nächste Task, der es 
dekodiert. Ab da geht es weiter wie im RTU-Modus.

Sobald man sich um eine Fehlerbehandlung kümmert, wird der RTU-Modus 
ähnlich unangenehm wie der ASCII-Modus. Anfang erkennen, Ende erkennen, 
kaputte Pakete erkennen, verwerfen, neu synchronisieren. Da ist beinahe 
Null Gewinn.

Ich weiß nicht, was da dran so kompliziert sein soll.
Ja, binär ist einfacher und durchaus richtig. Der TO will aber ein 
Menschen-bedienbares Interface, was durchaus sinnvoll begründbar ist. 
Gibt ja genügend cli-Anwendungen als Beispiel.
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Nick schrieb:
> Es muss ja unheimlich komplex sein, ein command-line Interface zu
> programmieren

Nö, aber es ist unnötig komplex. Wie gesagt, der ganze Thread hier 
existiert nur weil es so komplex ist.

Nick schrieb:
> Wenn man das ganze als state-machines aufbaut

hat man schon viel mehr Arbeit investiert als bei anderen Ansätzen. Mag 
ja spannend sein als akademische Fingerübung, aber nach dem fünften 
Protokoll was man so implementiert hat überlegt man sich doch, ob das 
unbedingt so sein muss. BTDT. Das entfällt alles komplett bei 
USB+Binärblock, oder auch CAN+Binärblock.

Nick schrieb:
> Anfang erkennen, Ende erkennen, kaputte Pakete erkennen, verwerfen, neu
> synchronisieren

Sind bei USB oder CAN genau Null Zeilen. Macht die Hardware alles 
automatisch. Und da ja sowieso schon USB verwendet wurde...

Nick schrieb:
> Dann frägt man zyklisch, ob im Empfangspuffer das erhoffte cr/lf (oder
> was auch immer) ist

Zyklisch heißt per Timer? Dann muss der Zyklus kürzer als die 
Übertragungszeit eines Bytes sein? Klingt (energie)ineffizient.

Btw, lustige Geschichte: Sogar Funkmodems, z.B. die SX126x, auch in der 
Variante die im STM32WLx5 integriert ist, machen das alles automatisch 
(Erkennung Anfang+Ende/Länge, Prüfsumme, Synchronisierung) - keine 
Statemachine nötig, die CPU kann im deep sleep sein und wird nur beim 
Empfang vollständiger Datenpakete aufgeweckt. Da könnte man auch 
ASCII-Pakete übertragen aber wozu... Somit wäre Funk sogar einfacher als 
der Eiertanz mit Idle-Interrupt, Zeilenumbruch-Erkennnung usw. - 
demnächst übertrage ich alles drahtlos, haha.

Nick schrieb:
> Gibt ja genügend cli-Anwendungen als Beispiel.

Eine gut bedienbare CLI-Anwendung ist aber auch nicht unbedingt so 
einfach umzusetzen. Für GUIs gibt es so viele ausgefeilte Frameworks, da 
kann man sich simpel was zusammenbauen und damit den Protokollaufwand 
auf Firmware-Seite sparen.
: Bearbeitet durch User
von Hans W. (hanswieland)


Lesenswert?

Niklas G. schrieb:
> Erfahrene Entwickler versuchen meistens unnötige Komplexität zu
> vermeiden!

Allerdings, und Chef weis es zu schätzen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.