Autor Wątek:  [Linux] UART błąd synchronizacji?  (Przeczytany 1804 razy)

0 użytkowników i 1 Gość przegląda ten wątek.

Offline marcinn

  • Wiadomości: 36
    • Zobacz profil
    • Budowa symulatora do MaSzyny
  • Otrzymane polubienia: 24
[Linux] UART błąd synchronizacji?
« dnia: 09 Maja 2021, 04:18:50 »
Witajcie.

Jestem po dosyć długiej diagnostyce problemów komunikacji z Maszyną.
Wydaje mi się, że synchronizowanie ramek nie działa. Tzn. działa, ale łapanie synchronizacji jest dziełem przypadku i zależy od kompilatora.

W momencie kiedy Maszyna gubi synchronizację, zaczyna czytać bajt po bajcie. Preambuła sprawdzana jest tak:

                if (sc == 0xEF)                                                                     
                        sync_cnt++;   

Jednak zmienna "sc" zdefiniowana jest jako char, a char jest signed:

    char sc = 0;


Skutkuje to (przynajmniej u mnie) pomijaniem bajtów "0xEF" i "zmęczeniem" synchronizacji ze względu na przekroczoną ilość prób.
Może ktoś będzie w stanie to potwierdzić. U siebie zmieniłem na unsigned char i widzę poprawę.
 
PS. Wrzucam na tę chwilę na forum, bo zgodnie z odp. PW od Milek7 najpierw trzeba dogadać komu (do którego forka i której gałęzi) podrzucać PR. Poza tym wydaje mi się, że kompilator VS (dla Windows) może dawać ten sam efekt, co czyniłoby błąd raczej krytycznym (dla korzystających z pulpitów).
« Ostatnia zmiana: 09 Maja 2021, 04:21:10 wysłana przez marcinn »

Offline tmj

  • Deweloper
  • Wiadomości: 3808
    • Zobacz profil
  • Otrzymane polubienia: 2351
Odp: [Linux] UART błąd synchronizacji?
« Odpowiedź #1 dnia: 09 Maja 2021, 05:21:02 »
Poza tym wydaje mi się, że kompilator VS (dla Windows) może dawać ten sam efekt, co czyniłoby błąd raczej krytycznym (dla korzystających z pulpitów).
Visual C domyslnie traktuje char jako signed (chyba ze dostanie inaczej w konfiguracji) wiec tak, zachowanie zapewne jest takie samo. Nie pamietam by ktos sie specjalnie skarzyl na problemy z synchronizacja, ale dalem na wszelki wypadek u siebie podmiane na unsigned.

Offline marcinn

  • Wiadomości: 36
    • Zobacz profil
    • Budowa symulatora do MaSzyny
  • Otrzymane polubienia: 24
Odp: [Linux] UART błąd synchronizacji?
« Odpowiedź #2 dnia: 09 Maja 2021, 10:56:58 »
Wpadłem na to grzebiąc w libie do Arduino. Zdarza mi się bowiem, że uruchomienie Maszyny resetuje mi uC (Mega 2560). Czytałem że jest to normalne po otwarciu portu szeregowego i bardziej dziwi mnie, że z rzadka to nie następuje.

Problem nie jest zauważalny, gdy po stronie Arduino transmisja określona jest tak:

uint8_t output[20] = {0xEF, 0xEF, 0xEF, 0xEF};
uint8_t input[52] = {0};

void setup() {
  Serial.begin(19200, SERIAL_8N1);
  while (!Serial);
}

void loop() {
  Serial.readBytes((uint8_t *) &input, 52);
  Serial.write((uint8_t *) &output, 20);
}

Ale problem można odtworzyć na wersji Maszyny z signed char, gdy w kodzie uC dodasz guarda:

uint8_t output[20] = {0xEF, 0xEF, 0xEF, 0xEF};
uint8_t input[52] = {0};

void setup() {
  Serial.begin(19200, SERIAL_8N1);
  while (!Serial);
}

void loop() {
  if (Serial.available() >= 52) {
    Serial.readBytes((uint8_t *) &input, 52);
  }
  if (Serial.availableForWrite() >= 20) {
    Serial.write((uint8_t *) &output, 20);
  }
}

Przy signed char Maszyna nie łapie synca:

uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: tired of trying
uart: bad sync
uart: read byte: 0
uart: read byte: -17
uart: read byte: -17
uart: read byte: -17
uart: read byte: -17
uart: read byte: 4
uart: read byte: -128
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0

Ale po zmianie na unsigned char - już tak:

uart: tx: EF EF EF EF 00 00 00 00 00 00 08 03 0C B0 00 DA 09 00 00 00 00 00 00 00 00 B4 5E 76 2F 1F 02 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
sm42-907 received command: [aidriverdisable]
New order for [passat]: JumpToNextOrder
[...]
uart: bad sync
uart: read byte: 0
uart: read byte: 239
uart: read byte: 239
uart: read byte: 239
uart: read byte: 239
uart: synced, skipping one packet..
uart: sync ok

Bez guarda readBytes() czeka na bufor wejściowy przez czas określany za pomocą Serial.setTimeout(), domyślnie 1s.
Zależy mi na tym, żeby blokować loop() czekając na dane.