-         
Ergebnis 1 bis 8 von 8

Thema: Java - Frage wg. Programmentwurf

  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.321

    Java - Frage wg. Programmentwurf

    Anzeige

    Hallo

    Ich bräuchte mal etwas Hilfe zwecks Softwareentwicklung. Es geht um eine Schaltung mit einem Mikrocontroller, der per FT232 mit einem Java-Programm redet. Jetzt geht es um das Java-Programm.

    Ich will die direkte Kommunikation in einem eigenen Thread laufen lassen, das Datenaufkommen kann erheblich werden (ich will versuchen mehrere MBaud hinzukriegen, mal sehen wieviel geht). Dieser Thread hat nicht viel weiter zu tun als auf Daten zu warten, CRC berechnen und zurücksenden, Auszeit überwachen. Und das in beide Richtungen.

    Reicht da sowas?
    Code:
        @Override
        public void run(){
            while(true){
                //Hier die Kommunikationsauswertung/CRC-Prüfung/usw...
            }
        }
    Ich will den Thread nicht 1ms (weniger geht anscheinend nicht) schlafen legen, das erscheint mir doch ein wenig viel. Allerdings muß der Thread im Leerlauf auch nicht die CPU voll auslasten.

    Könnte das so funktionieren? Hat jemand noch andere Tipps für mich?
    Das ist mein erstes "ernsthaftes" Java-Programm, mit Multi-Threading (und einigen anderen Dingen) hab ich mich in der Praxis noch nie beschäftigt, und doch hab ich da recht hohe Ansprüche an meine Arbeit.

    Edit:
    Ich hab grad etwas über Demonthreads gelesen. Ist es eine gute Idee, Threads mit solchen Aufgaben als Dämon laufen zu lassen? Wie geht das in Java? Ich hab das Runnable-Interface implementiert und nicht von der Thread-Klasse geerbt. Funktioniert das da auch?

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.395
    Deine Serielle Kommunikation dahinter läuft ungefähr mit 115,2 kbit/s (115200 Baud), je nachdem was du eingestellt hast (mehrere MBaud halte ich für unrealistisch weil den Mikrocontroller das auf der anderen Seite ja auch begrenzt)
    . Nun angenommen du willst jedes Byte einzeln lesen und zwar möglichst zeitnah. D.h. du musst 115,2 / 8 = 14,4 kbyte / s lesen. Das sind pro Byte dann: 1/14,4 kbyte = 0,069 ms pro Byte bei voller Auslastung. Da hast du recht. Das schafft man nicht wenn man 1ms wartet ->
    Nun hat die Seriellport Implementierung in Hardware und im Betriebssystem jedoch eine FIFO drin. D.h. du musst nicht jedes Byte in Echtzeit auslesen (Was auf einem normalen PC auch gar nicht möglich wäre) sondern dein PC speichert die Bytes zwischen und du kannst sie dann am Stück lesen und dann warten.

    Alle Implementierungen die ich bisher dazu geschrieben habe (Zwar nicht in Java sondern in C++) haben zwischen 10 bis 50 ms zwischen zwei Abfragen gewartet.

    Pseudo Code:
    Code:
    while(Abbruchbedingung)
    {
         while(Rs232Buffer != empty)
         {
               ReadByte(s)
         }
         Sleep(n - Ms)
    }
    Weniger als 1 ms warten geht nur wenn man selber aktiv wartet. D.h. man liest die High Precission Clock des Systems aus und zählt ticks.

    Zum Thema Multithreading in Java kann ich dir leider nichts sagen. (Solltest du C++ nehmen wollen melde dich

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.321
    Danke...
    Welcher einigermaßen Mikrocontroller ist denn bis 11kBd begrenzt? Selbst die ATMegas schaffen 2MBd...in diesem Fall werkelt da ein STM32, der schafft noch etwas mehr.

    Die Daten kommen von der API übrigens über das Observer-Muster rein, an den RS232-Buffer komm ich gar nicht ran...und wie gesagt, ich will (in diesem Thread) nicht alle Bytes auslesen, sondern eigentlich (bisher) nur maximal drei bis vier sowie die Bytes eines gesamten Datenblocks (maximal 255) zählen. Und Millisekunden zählen.

    Aber das soll hat fix und vor allem vom Rest des Programms unabhängig gehen.
    Geändert von White_Fox (22.07.2017 um 23:11 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.395
    Mit einem STM32 würde ich direkt USB Bulk Transfers machen.
    Außerdem wollte ich nicht sagen dass du keine 1-2 MBauds schaffst, sondern dass häufig mit geringeren Geschwindigkeiten geabeitet wird.

    Welche API du hast habe ich keine Ahnung. Jede Serielport Implementierung die ich bisher gesehen habe (C/C++/C#/Python) ermöglicht es einem eine Abfrage zu machen: Wie viele Bytes sind da? und dann lies n-Bytes am Stück aufzurufen.

    Letztendlich ist es ja genau das was du willst. Schauen wie viele Bytes sind da. Wenn deine API das nicht zulässt würde ich dir vorschlagen eine andere Implementierung zu suchen. In wirklich kurzen Zeitintervallen regelmäßig etwas zu machen ist auf einem normalen Desktoptechner nicht machbar allein scho nwegen des Schedulers.

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.321
    Wie gesagt, von dem USB-Kram hab ich keine Ahnung. Damit befasse ich mich vielleicht später mal...

    Die API die ich hab bietet zwar normale Lese- und Schreibmethoden, aber auch Observer-Benachrichtigung, und die benutze ich.

    Schade...keine Java-Programmierer hier? Dabei ist die Sprache klasse, wie ich finde.

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.395
    Wie gesagt. Ich bin kein Java Programmierer, bin aber der Ansicht, dass die Sprache im Endeffekt recht egal ist. Ein Serialport bleibt ein Serielport egal ob man in C, Java oder Brainfuck anspricht. Manche Sprachen bauen Wrapper drumherum, die manchmal Sinn machen zu verwenden, manchmal auch nicht.

    Nun lass uns deine Aufgabenstellung zerlegen. Du willst zum Einen das Observer Pattern verwenden, also benachrichtigt werden wenn neue Daten ankommen.
    Die ersten Fragen die sich an dieser Stelle stellen:
    1. In welchem Thread wird dieser Aufruf durchgeführt (main Thread, eigener Thread ?)
    2. Wirst du für jedes Byte oder nur einen Satz an Bytes benachrichtigt -> Allgemein welche Informationen bekommst du an dieser Stelle

    Diese Informationen können einem später weiterhelfen zu entscheiden ob ein extra Thread überhaupt Sinn macht.

    Nun kommen wir weiter zu deiner Anforderung bzw. deinem ersten Vorschlag.
    Du hast vorgeschlagen in einer Endlosschleife die Daten abzuprüfen. Hast du dir denn schon überlegt wie du die Daten an diese Stelle hinbekommst? (Ich habe dir an der Stelle einen recht klassischen Polling Ansatz beschrieben, deine Library oder das Betriebssystem macht untendrunter auch nichts anderes, wobei das Betriebssystem aber noch am ehesten die Möglichkeit hätte einen Interrupt basierten Ansatz umzusetzen)

    Wenn du deinen Ansatz so verfolgen willst, wirst du nicht darum kommen die Daten selber zwischen zu speichern und zwar in einer Form, dass du gefahrlos aus zwei Threads darauf zugreifen kannst. Letztendlich hättest du dabei aber nur einen weiteren Zwischenspeicher eingeführt (eben in deiner eigenen Anwendung statt in der Seriallib bzw. im Betriebssystem)

    Welche Schlüsse kann man daraus ziehen (bzw. die ich daraus ziehen würde): Wenn man den Event basierten Ansatz (also Observerpattern) verwenden willst, ist es meiner Ansicht nach am sinnvollsten direkt an der Stelle wo man benachrichtigt wird seine Bytes zu verarbeiten.

    Wenn man einen extra Thread verwenden will ist es am sinnvollsten die Daten selber abzuholen. Wenn du das richtig machst, kannst du dir (nachdem was du beschrieben hast) eventuell sorgar teilweise sparen die Daten zu holen sondern musst nur abfragen wie viele Bytes gerade da sind.

    Sollte man wirklich (auch dafür kann es gute Gründe geben) beide Ansätze kombinieren wollen, dann ist es das Sinnvollste eine Thread sichere Queue zu verwenden , dort von der Stelle wo man benachrichtigt wird welche Daten ankommen die Daten reinzuschreiben und in dem extra Thread die Daten aus der Queue zu holen und zu verarbeiten.

    Welche Variante man davon verwendet ist meiner Ansicht nach, bei den Datenmengen die über eine Serielleverbindung laufen egal. Die Daten direkt in einem extra Thread zu holen hat meiner Erfahrung nach die geringste Latenz.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    35
    Beiträge
    3.411
    Ich will den Thread nicht 1ms (weniger geht anscheinend nicht) schlafen legen, das erscheint mir doch ein wenig viel. Allerdings muß der Thread im Leerlauf auch nicht die CPU voll auslasten.
    Code:
    Thread.yield()
    
    oder
    
    try{
       Thread.sleep(x);
    } catch (InterruptedException ignore) {
    }
    zuerst einmal Thread.yield() das Allheilmittel gegen 100% CPU in einem Task der ohne Sleep arbeitet!



    Das bedeutet, dass der Task der gerade diesen Aufruf macht, dem System anbietet "Ich könnte jetzt Pause machen wenn du gerade etwas anderes zu tun hast"
    Du hast keine 100% Auslastung, das ist ein Missverständniss, du hast 100% blockiert, weil du niemals Pause machst, sondern selbst das Abrufen eines leeren COM Port ohne unterlass wiederholst ohne dem System (oder dem CPU Core) die Möglichkeit zu geben auch mal andere Arbeiten auszuführen

    Und das zweite was du bei einem Sleep beachten solltest, ein Sleep ist nicht zwangsläufig ununterbrechbar! Ein Sleep kann jedezeit utnerbrochen werden ohne dass die Daten verloren gehen, solange dein Input die MÖglichkeit hat deinen Schlafenden Thread zu wecken (Interrupt). Wie du deinen COM Port allerdings dazu bringst das Sleep zu Interrupten (Deswegen auch der Try-Catch-Block im Beispiel) müsstst du selber mal herausfinden, dafür efhlen mir zu viele Inofs
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  8. #8
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.321
    Ah...danke für die Erklärung der yield()-Methode. Ich hab da kurz was drüber gelesen, war mir aber nicht so sicher dabei. Ich denk das werd ich dann damit machen.

    Und gut zu wissen daß auch die sleep()-Methode unterbrochen werden kann...

Ähnliche Themen

  1. Antworten: 12
    Letzter Beitrag: 07.03.2018, 22:35
  2. Java-Programmierung Frage
    Von White_Fox im Forum Software, Algorithmen und KI
    Antworten: 9
    Letzter Beitrag: 16.03.2014, 19:26
  3. Frage an die Java-Profis
    Von pinsel120866 im Forum Open Source Software Projekte
    Antworten: 8
    Letzter Beitrag: 04.04.2009, 18:16
  4. Java
    Von emde im Forum Elektronik
    Antworten: 6
    Letzter Beitrag: 26.06.2007, 19:15
  5. Java 1.4 auf dem PDA?
    Von maze2k im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 7
    Letzter Beitrag: 11.11.2005, 14:26

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •