ANSI C: Position im Text finden

Moderator Persönliche Seite #7112985
Lesenswert?

PittyJ schrieb:
> Gerade den Code gesehen, es war sogar ein Lachen.

Was hilft diese Arroganz jetzt dem TE?

Um's konkret zu machen:

* der gezeigte Code enthält keinerlei Auswertung der empfangenen 
Zeichen; aber genau um diese geht es ja eigentlich im Thread hier
* immer mal was zu lesen und dann eine ganze Sekunde warten beschwört ja 
(je nach Baudrate) Datenverluste regelrecht herbei; ich habe keine 
Ahnung vom Windows-API, aber es sollte doch irgendeine API-Methode 
geben, mit der man auf ein (oder mehrere) Zeichen warten kann, genau an 
der Stelle sollte der Thread warten
* einen Zeiger zuerst zu benutzen 
(pSeriell->LastInterruptTime=pSeriell->LastTime;) und danach zu testen, 
ob er nicht 0 ist, ist natürlich Humbug
Gast #7113006
Lesenswert?

Flo schrieb:
> Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere
> Möglichkeit?
> Es wird beim Empfang von seriellen Daten eingesetzt.

Ah, fein, 2 weitere Salamischeiben.

Ja, üblicherweise verwendet man eine state-machine als Parser für 
Einzelzeichen, der im state sich merkt wie viele Zeichen vorher korrekt 
waren und bei erkannter Zeichenfolge ein flag setzt so dass nachfolgende 
Zeichen ausgegeben werden.

Wie viele braucht es noch bis die Salami komplett ist ?

Flo schrieb:
> Die Applikation ist in C/C++ geschrieben

Ähm, nein. Du hast irgendwas von irgendwo her kopiert ohne zu wissen was 
es tut.
Gast #7113010
Lesenswert?

Wenn Nachrichten eintreffen wird die Callback Funktion ausgeführt. In 
dieser Callback Funktion wird dann die Funktion RxFrame ausgeführt.
1
void RxCallback()
2
{
3
  Len = Port.pM->ReceiveFrame(&Port, RxBuffer, UART_FRAME_SIZE);
4
  if (Len )
5
  {
6

7
        }
8
}
Gast #7113023
Lesenswert?

Jörg W. schrieb:
> PittyJ schrieb:
>> Gerade den Code gesehen, es war sogar ein Lachen.
>
> Was hilft diese Arroganz jetzt dem TE?
>

Nein, die hilft ihm überhaupt nicht. Allerdings ist der Code nicht von 
ihm. Wer sich in Callbacks etc. begibt, der sollte schon mal einfache 
Stringverarbeitung kennen.
Die Stelle, wo er die Vergleich machen möchte, befindet sich nicht im 
Sourcecode, sondern müßte komplett ergänzt werden.
Das, was wir als Source sehen, ist ein Copy& Paste, ohne dass der TO 
wirklich eine Ahnung davon hat.

Ich plädiere immer dafür, erst einmal ein paar Basics zu lernen. So 
einfach mal alle Stringfunktionen. Oder auch std::string, weil die 
angenehmer sind.

Sorry: 90% Copy und Paste, die restlichen 10% aus dem Forum hier? So 
geht die Welt nicht.
Gast #7113104
Lesenswert?

Ja genau nur eine Millisekunde.

Ich bin aktuell dabei das ganze nochmals durchzugehen woran es genau 
liegen könnte. Im Prinzip werden mittels Thread geprüft ob Daten 
anliegen wenn ja sollen diese im Puffer gespeichert werden. Die Daten 
von der seriellen Schnittstelle haben eine Enderkennung "\r\n". Und ein 
gültige Nachricht beginnt immer mit einem + danach folgenden die Daten 
und zum Schluss werden zur Enderkennung die zwei Zeichen gesendet 
"\r\n".
#7113152
Lesenswert?

Flo schrieb:
> Brauche
> eigentlich nur für einen Test eine funktionierende serielle
> Kommunikation

Gegenstelle ist ein Arduino?

dann hätte ich als etwas schrägen Vorschlag:
"processing" am PC.

https://processing.org/

Diese API kommt dir dann evtl. vertraut vor:

https://processing.org/reference/libraries/serial/index.html

das ganze Graphik-Künstler-Video-Zeug was mitkommt muss man ja nicht 
nutzen.
Gast #7113236
Lesenswert?

Um das also abzukürzen: du suchst also einen „AT Parser“.
Wenn Du nicht in der Lage bist, einen nach Deinen Vorstellungen zu 
entwickeln, nimm doch als Vorbild eins der ca. 42 Fantasillionen 
Beispiele: google „at parser“.
Gast #7113775
Lesenswert?

So ich bins nochmal.

Hab nun mal was eigenes aufgesetzt. Jetzt ist es aber nach wie vor so, 
dass
wenn ich zyklisch jede 100ms UART Nachrichten (pro Frame 256 bytes) 
versende die von der Gegenstelle gesendeten Nachrichten nicht sofort 
empfangen kann.
Gast #7113782
Lesenswert?

1
CSerial::CSerial(char* com_port, DWORD COM_BAUD_RATE)
2
{
3
  connected_ = false;
4

5
  io_handler_ = CreateFileA(static_cast<LPCSTR>(com_port),
6
    GENERIC_READ | GENERIC_WRITE,
7
    0,
8
    NULL,
9
    OPEN_EXISTING,
10
    FILE_ATTRIBUTE_NORMAL,
11
    NULL);
12

13
  if (io_handler_ == INVALID_HANDLE_VALUE) 
14
  {
15
    if (GetLastError() == ERROR_FILE_NOT_FOUND)
16
      printf("Warning: Handle was not attached. Reason: %s not available\n", com_port);
17
  }
18
  else {
19

20
    DCB dcbSerialParams = { 0 };
21

22
    if (!GetCommState(io_handler_, &dcbSerialParams)) 
23
    {
24
      printf("Warning: Failed to get current serial params");
25
    }
26

27
    else 
28
    {
29
      dcbSerialParams.BaudRate = COM_BAUD_RATE;
30
      dcbSerialParams.ByteSize = 8;
31
      dcbSerialParams.StopBits = ONESTOPBIT;
32
      dcbSerialParams.Parity = NOPARITY;
33
      dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;
34

35
      if (!SetCommState(io_handler_, &dcbSerialParams))
36
        printf("Warning: could not set serial port params\n");
37
      else 
38
      {
39
        connected_ = true;
40
        PurgeComm(io_handler_, PURGE_RXCLEAR | PURGE_TXCLEAR);
41
      }
42
    }
43
  }
44
}
1
string CSerial::ReadSerialPort(int reply_wait_time) 
2
{
3

4
  DWORD bytes_read;
5
  char inc_msg[1];
6
  string complete_inc_msg;
7
  bool began = false;
8

9
  unsigned long start_time = time(nullptr);
10

11
  ClearCommError(io_handler_, &errors_, &status_);
12

13
  while ((time(nullptr) - start_time) < reply_wait_time) 
14
  {
15
    if (status_.cbInQue > 0) 
16
    {
17
      if (ReadFile(io_handler_, inc_msg, 1, &bytes_read, NULL)) 
18
      {
19
        began = true;
20

21
        if (inc_msg[0] == '\n')
22
          return complete_inc_msg;
23

24
        if (inc_msg[0] != '\n')
25
          complete_inc_msg.append(inc_msg, 1);
26
      }
27
      else
28
        return "Warning: Failed to receive data.\n";
29
    }
30
  }
31
  return complete_inc_msg;
32
}
1
bool CSerial::WriteSerialPort(char* data_sent)
2
{
3
  DWORD bytes_sent;
4

5
  unsigned int data_sent_length = strlen(data_sent);
6

7
  if (!WriteFile(io_handler_, (void*)data_sent, data_sent_length, &bytes_sent, NULL)) 
8
  {
9
    ClearCommError(io_handler_, &errors_, &status_);
10
    return false;
11
  }
12
  else
13
    return true;
14
}
Gast #7113915
Lesenswert?

Bist du sicher, dass du das aufgesetzt hast?
Einerseits die teilweise ordentlichen, nicht trivialen Programmteile, 
die du postest.
Andererseits das Unverständnis von Basics und mangelnde Kenntnis von 
einfachsten Stringroutinen.
Deine ersten Tests waren in C. Jetzt kommt hier C++?

Für mich sieht das mehr so aus, als dass du nur eine neue Quelle für 
Copy&Paste erschlossen hast.
Moderator Persönliche Seite #7114562
Lesenswert?

Flo schrieb:
> Gibt es dazu noch Möglichkeiten dies zu optimieren?

Code verstehen, deinen tatsächlichen Flaschenhals finden, dann 
reparieren.

So kann dir das keiner sagen. Selbst mit 'ner UART von 1 MBaud ist ein 
heutiger PC locker in der Lage, da einige strstr()-Aufrufe auf das 
Resultat anzuwenden, ohne dass irgendwas klemmt. Wenn da bei dir was 
nicht funktioniert, liegt das also ganz sicher nicht an strstr() (oder 
ähnlichen Standardfunktionen), sondern an irgendwas ganz anderem.

Dafür müsstest du aber erstmal wissen, was du da überhaupt tust. Danach 
müsstest du analysieren, warum es bei dir zu langsam wird. Erst dann 
brauchst du drüber nachzudenken, wie man es "optimiert".

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren