Kysymys:
Kuinka vikaturvallinen on stop-tavu?
C. K.
2019-04-18 15:33:32 UTC
view on stackexchange narkive permalink

UART-viestinnässä minun on tiedettävä lähetetyn viestin aloitus- ja lopetustavu.Alkutavu on helppoa, mutta lopetustavu ei niin paljon.Olen toteuttanut viestin lopussa kaksi stop-tavua, ts. \ N ja \ r (10 ja 13 desimaalia).UART toimii vain tavuilla 0-255, joten kuinka vikaturvallinen tämä on?Voin kuvitella, vaikkakin pienellä todennäköisyydellä, että viestini saattaa sisältää arvot "10 ja 13" peräkkäin, kun ne eivät ole pysäytyskohdat.

Onko olemassa parempi tapa toteuttaa tämä?

Voit lähettää mielivaltaisia tietoja joko pakettien tai tavujen täyttämisen avulla.Sinun tapauksessasi todennäköisyys, että kuvio esiintyy tietyssä paikassa, on 1/65536.Mikä saa yhden, jos sinulla on tarpeeksi pitkä satunnaisdatavirta.
Voitteko antaa kontekstin, kiitos.Pysäytysbitit ovat osa UART-viestintää, mutta lopettavat tavut?Tämä kuulostaa puhtaalta ohjelmistokysymykseltä ja riippuu lähettäjän ja vastaanottajan sopimasta.
Jos toteutus on vain teksti *, käytä yhtä null (0) -terminatoria.Käytä muuten pakettirakennetta, kuten @Oldfart mainitsee.Jos olet huolissasi eheydestä, harkitse [virheenkorjaus] (https://en.wikipedia.org/wiki/Error_detection_and_correction)
@WarrenHill Kyllä, pysäytysbitit ovat osa UART-kumulaatiota, mutta lähetän tietojonon, ja minun on tiedettävä, milloin merkkijono loppuu.Tai pikemminkin lähetän monia tietojonoja, ja minun on tiedettävä, milloin jokainen merkkijono loppuu.
@RamblinRose tietoni ovat lukuarvoja, jotka voivat helposti olla 0. Silloin 0 päättäisi merkkijonon, eikö?
@MariusGulbrandsen, jos tietosi ovat todella mielivaltaisia eivätkä pelkästään tekstiä (ajattele ASCII: ta), tyhjä purkaminen ei toimi;joudut toteuttamaan paketin.
@MariusGulbrandsen, koska tämä on ehdottomasti käsittely- / ohjelmistokysymys, suosittelen etsimistä StackOverflow'sta, esim."UART-paketti"
@RamblinRose Teen sen, kiitos.Ajattelin myös: Käytän MCU: ta kommunikoimaan UART: sta Bluetoothiin.Voin ohjelmoida BT-moduulini kuin mikrokontrolleri ylimääräisillä IO-nastoilla.Voinko käyttää IO-nastaa asettamaan "start", kun High ja "stop", kun Low on?Onko tämä myös hyvä toteutus?
Koska sovelluksesi pullonkaulana on BLE: n sarjaominaisuuksien muutosilmoitus, joka on paljon, paljon hitaampaa kuin MCU: ita yhdistävä UART, kaiken UART: n pakeneminen tai heksakoodaaminen olisi yksinkertainen ratkaisu.Todellakin paras tapa voi olla pohjoismaisen BLE-sirun (erityisesti yhden sen viimeisimmistä jälkeläisistä) käyttäminen koko ongelman ratkaisemiseen, jolloin UART ei tarvitse kommunikoida toisen prosessorin kanssa.
@RamblinRose: Olen havainnut tekstivirrat tyhjillä tavuilla.Ehkä tavu 0x1C?
@Joshua todellisuus on se, että mikä tahansa arvo voidaan valita stop-tavuksi IFF: ksi, sitä ei koskaan tapahdu streamissa datana.Se riippuu todella ohjelmoijasta päättää, kuinka toteuttaa.{[Pituus] [data] [pääte]} -muoto on perustavanlaatuinen asia.
BTW: Tämä yleinen käytäntö on asettaa rivinvaihto _ ennen rivin syötettä: "" \ x0D \ x0A "".
@AdrianMcCarthy Mielestäni sen kääntämisen tarkoituksena on minimoida kertoimet siitä, että se on kelvollinen sekvenssi.Siitä huolimatta, kaksi Windows-rivinvaihtoa peräkkäin antaisi sinulle `` r \ n \ r \ n '', joka sisältää keskellä olevan \ n \ r-sarjan ...
Palaan historiaan ja käytän jotain todistettua ja toimivaa.Kuten [XMODEM] (https://fi.wikipedia.org/wiki/XMODEM) -protokolla.Se toimii.Kaikki, mitä yrität luoda itse, ei todennäköisesti toimi, ellei sinulla ole syvällistä ymmärrystä aiheesta tai olet erittäin fiksu.
Tai [Kermit] (https://fi.wikipedia.org/wiki/Kermit_ (protokolla)).Sitä käytetään edelleen nykyäänkin yksinkertaisuutensa vuoksi.
related: Sarjaprotokollan rajaus- / synkronointitekniikat https://electronics.stackexchange.com/questions/186254/serial-protocol-delimiting-synchronization-techniques
Viisi vastused:
Michel Keijzers
2019-04-18 15:59:16 UTC
view on stackexchange narkive permalink

Tämän voi estää eri tavoin:

  • Varmista, ettet koskaan lähetä 10/13-yhdistelmää tavallisissa viesteissäsi (joten vain pysäytyskohdina). Esim. lähettää 20 21 22 23 24 25:

20 21 22 23 24 25 10 10

  • Escape 10 ja 13 (tai kaikki muut kuin ASCII-merkit, joilla on esimerkiksi escape-merkki. Joten lähetetään 20 21 10 13 25 26 send: (katso kommentti / hyvitykset: DanW)

20 21 1b 10 1b 13 25 26

  • Määritä paketti, kun lähetät viestejä. Esim. jos haluat lähettää viestin 20 21 22 23 24 25 kuin lisätä sen sijaan tavujen lukumäärä lähetettyihin, niin paketti on:

< nr_of_data_bytes > < data >

Jos viestejäsi on enintään 256 tavua, lähetä:

06 20 21 22 23 24 25

Joten tiedät saatuasi 6 datatavua, että on loppu; sinun ei tarvitse lähettää 10 13 jälkeenpäin. Ja voit lähettää 10 13 viestin sisällä. Jos viestisi voivat olla pidempiä, voit käyttää 2 tavua datan kokoon.

Update 1: Toinen tapa määrittää paketit

Toinen vaihtoehto on lähettää komentoja, joilla on tietty pituus ja joilla voi olla monia variansseja, esimerkiksi

10 20 30 (komento 10, jossa on aina 2 datatavua)

11 30 40 50 (komento 11, jolla on aina 3 datatavua)

12 06 10 11 12 13 14 15 (komento 12 + 1 tavu seuraavien datatavujen määrälle)

13 01 02 01 02 03 ... (Komento 13 + 2 tavua (01 02 merkille 256 + 2 = 258 seuraavaa tavua)

14 80 90 10 13 (komento 14, jota seuraa ASCII-merkkijono, joka päättyy 10 13: een)

Update 2: Huono yhteys / tavuhäviöt

Kaikki yllä olevat toimivat vain, kun UART-rivi lähettää tavuja oikein. Jos haluat käyttää luotettavampia lähetystapoja, on myös monia mahdollisuuksia. Alla on muutama:

  1. Tarkistussumman lähettäminen paketin sisällä (tarkista Googlelta CRC: syklinen redundanssitarkistus).Jos CRC on kunnossa, vastaanottaja tietää, että viesti on lähetetty ok (suurella todennäköisyydellä).
  2. Jos tarvitset viestin lähettämistä uudelleen, on käytettävä kuittausmekanismia (ACK / vastaus) (esim. lähettäjä lähettää jotain, vastaanottaja vastaanottaa vioittuneita tietoja, lähettää NACK (ei kuitattu), lähettäjä voi kuin lähettää uudelleen.
  3. Aikakatkaisu: Jos vastaanotin ei saa ACK: ta tai NACKia ajoissa, viesti on lähetettävä uudelleen.

Huomaa, että kaikki yllä olevat mekanismit voivat olla yksinkertaisia tai niin monimutkaisia kuin haluat (tai tarvitset).Viestin lähettämisen yhteydessä tarvitaan myös mekanismi viestien tunnistamiseksi (esim. Järjestysnumeron lisääminen pakettiin).

"Varmista, ettet koskaan lähetä 10/13-yhdistelmää tavallisissa viesteissäsi (joten vain pysäytyskohdina)."- et ole sanonut, kuinka lähetetään tietoja, jotka * sisältävät 10/13-yhdistelmän - sinun on vältettävä sitä.Joten "20 10 13 23 10 13" saatetaan lähettää nimellä "20 1b 10 1b 13 23", jossa 1b on pakohahmosi.
Huomaa, että käyttämällä ehdotettua pituuskenttää, olet pulassa, kun sarjayhteytesi on huono ja menettää yhden tavun.Kaikki menee synkronoinnista.
@DanW Jos käytät ensimmäistä tai kahta tavua datatavujen lukumääränä, ei ole väliä onko 10 tai 13 osa näitä tietoja ... Joten 20 10 13 23 10 13 voidaan lähettää muodossa 06 20 10 13 23 1013 missä 06 on seuraavien datatavujen määrä.
@MichelKeijzers - kyllä, mutta se on toinen mainitsemasi ratkaisu.Ensimmäisestä ratkaisustasi puuttuu selitys pakosarjoista, jotta estetään pysäytyskohdat.
Molemmat lähestymistavat toimivat ja ovat yleisesti käytettyjä, mutta niillä on erilaisia etuja ja haittoja, jotka voit lisätä haluttaessa, vaikka se ei ylitä sitä, mitä toimenpideohjelma pyysi.
@DanW Ah nyt ymmärrän sinut ... kyllä, oletetaan, että vain ASCII-merkkejä lähetetään (muuten toista vaihtoehtoa voitaisiin käyttää, mutta sinun tapasi olisi toinen vaihtoehto. Lisän sen myös ja kiitos panoksestasi.
Rev1.0
2019-04-18 16:05:36 UTC
view on stackexchange narkive permalink

Kuinka vikaturvallinen \ n \ r on stop-tavuina?

Jos lähetät mielivaltaisia ​​tietoja -> ei todennäköisesti ole riittävän turvallinen.

A yleinen ratkaisu on käyttää pakenemista:

Määritetään, että merkkien 0x02 (STX - kehyksen alku) ja 0x03 (ETX - kehyksen loppu) on oltava ainutlaatuisia lähetetyssä datavirrassa. Näin viestin alku ja loppu voidaan tunnistaa turvallisesti.

Jos jokin näistä merkeistä tulisi lähettää viestikehykseen, se korvataan lisäämällä pakomerkki (ESC = 0x1b) etuliitteellä ja lisäämällä 0x20 alkuperäiseen merkkiin.

Alkuperäinen merkki korvattu

  0x02 -> 0x1b 0x22
0x03 -> 0x1b 0x23
0x1b -> 0x1b 0x3b
 

Vastaanotin kääntää tämän prosessin päin: Aina kun hän saa pakomerkin, tämä merkki pudotetaan ja seuraava merkki vähennetään 0x20: lla.

Tämä lisää vain jonkin verran käsittelykuluja, mutta on 100% luotettava (olettaen, ettei lähetysvirheitä tapahdu, jotka voit / pitäisi tarkistaa toteuttamalla lisäksi tarkistussumman mekanismi).

Hieno vastaus.ASCII-protokollissa käytetty yleinen pakomerkki oli '' \ x10 '' DLE (Data Link Escape).Jotkut Wikipedia-sivut viittaavat siihen, että DLE: tä käytettiin usein päinvastoin: sanoa, että seuraava tavu oli pikemminkin kontrollimerkki kuin datatavu.Kokemukseni mukaan se on yleensä päinvastainen merkitys paetulle.
Yksi asia, jota meidän on katsottava täällä, on se, että pahimman tapauksen puskurikoko kaksinkertaistuu.Jos muisti on todella tiukka, se ei ehkä ole paras ratkaisu.
@Rev Mikä on perustelu lisätä 0x20 alkuperäiseen merkkiin?Eikö pakenemisjärjestelmä toimisi ilman sitä yhtä hyvin?
@NickAlexeev: Kehyksen todellisten rajojen tunnistaminen on helpompaa / nopeampaa, jos poistat muut varatut merkit esiintymästä streamista.Tällä tavoin voit erottaa kehyksen vastaanoton ja kehyksen jäsentämisen (mukaan lukien poistumiset).Tämä voi olla erityisen tärkeää, jos sinulla on erittäin hidas ohjain ilman FIFO: ta ja / tai korkea tiedonsiirtonopeus.Joten voit vain kopioida saapuvat tavut (STX / ETX: n välillä) kehyspuskuriin niiden saapuessa, merkitä kehys valmiiksi ja suorittaa käsittely alemmalla prioriteetilla.
AilixjvoziCMT Hyvä asia.
Eric Towers
2019-04-18 20:55:07 UTC
view on stackexchange narkive permalink

Tiedät, ASCII: lla on jo tavuja näille toiminnoille.

  • 0x01: otsikon alku - alatavu
  • 0x02: tekstin alku - otsikot, aloita hyötykuorma
  • 0x03: tekstin loppu - hyötykuorman loppu
  • 0x04: lähetyksen loppu - lopeta tavu
  • 0x17: lähetyslohkon loppu - viesti jatkuu seuraavassa lohkossa

Siinä on myös koodeja eri käyttötarkoituksiin hyötykuormassa.

  • 0x1b: paeta (pakene seuraavasta merkistä - käytä hyötykuormassa ilmoittaaksesi, että seuraava merkki ei kuulu rakenteeseen, joka kuvaa protokollassasi käytettyjä koodeja)
  • 0x1c, 0x1d, 0x1e, 0x1f: tiedosto, ryhmä, tietue ja yksikköerotin - käytetään samanaikaisesti pysäytys- ja aloitustavuina hierarkkisten tietojen osille

Protokollasi tulisi määrittää ACK (0x06) ja NAK (0x15) hienoimmat yksityiskohdat, jotta negatiiviset kuitatut tiedot voidaan lähettää uudelleen. Tähän hienoimpaan yksityiskohtaisuuteen saakka on viisasta pitää pituuskenttä heti minkä tahansa (koristamattoman) aloitusindikaattorin jälkeen ja (kuten muissa vastauksissa selitetään) on viisasta seurata mitä tahansa (kieltämätöntä) pysäytysindikaattoria CRC: llä. p>

Lähetän mielivaltaisia tietoja. Luulen, että kysymyksessä "\ n \ r" on ollut hämmentävää, kun en lähetä ASCII-tietoja.Vaikka pidän tästä vastauksesta, se on erittäin informatiivinen ASCII: n lähettämisestä UART: n kautta
@MariusGulbrandsen: Niin kauan kuin protokollasi määrittää, missä hyötykuorma on ja mitkä koodit on vältettävä kussakin hyötykuorma-osiossa, voit lähettää mitä tahansa, ei vain tekstiä sisältäviä tietoja.
Lundin
2019-04-18 16:27:04 UTC
view on stackexchange narkive permalink

UART ei ole luonnostaan ​​vikaturvallinen - puhumme täällä 1960-luvun tekniikasta.

Ongelman ydin on se, että UART synkronoi vain kerran 10 bittiä kohden, jolloin näiden synkronointijaksojen välillä voi kulkea paljon katkeruutta. Toisin kuin esimerkiksi CAN, joka ottaa näytteet jokaisesta yksittäisestä bitistä useita kertoja.

Kaikki tietojen sisällä esiintyvät kaksinkertaiset bittivirheet vioittavat UART-kehyksen ja kulkevat huomaamatta. Aloitus- / lopetusbittien bittivirheet voidaan havaita tai ei havaita ylitysvirheiden muodossa.

Siksi riippumatta siitä, käytätkö raakatietoja tai paketteja, on aina todennäköistä, että EMI: n aiheuttamat bittikäännöt johtavat odottamattomiin tietoihin.

On olemassa lukuisia tapoja "perinteiseen UART-hakkaamiseen" tilanteen parantamiseksi niin vähän. Voit lisätä synkronointitavuita, synkronointibittejä, pariteettia, kaksoispysäytysbittejä. Voit lisätä tarkistussummat, jotka laskevat kaikkien tavujen summan (ja sitten kääntää sen - koska miksi ei) tai voit laskea binääristen lukumäärän tarkistussummaksi. Kaikki tämä on laajalti käytetty, villin epätieteellinen ja suurella todennäköisyydellä puuttua virheitä. Mutta tätä ihmiset tekivät 1960-luvulta 1990-luvulle ja paljon tällaisia ​​outoja asioita elää tänään.

Ammattimaisin tapa käsitellä turvallista lähetystä UART: n kautta on, että paketin lopussa on 16-bittinen CRC-tarkistussumma. Kaikki muu ei ole kovin turvallista ja todennäköisesti puuttuu virheitä.

Laitteistotasolla voit sitten käyttää differentiaalista RS-422 / RS-485: tä parantamaan huomattavasti lähetyksen kestävyyttä. Tämä on välttämätöntä turvalliselle siirtämiselle pitemmillä matkoilla. TTL-tason UART-järjestelmää tulisi käyttää vain sisäiseen viestintään. RS-232: ta ei tule käyttää mihinkään muuhun tarkoitukseen, mutta yhteensopivuus taaksepäin vanhojen tavaroiden kanssa.

Mitä lähempänä virheenpaljastusmekanismiasi on, sitä tehokkaampi se on.Tehokkuuden suhteen erosignaalit lisäävät eniten, mitä seuraa kehystys- / ylitysvirheiden jne. Tarkistaminen.CRC16 lisää joitain ja sitten "perinteinen UART-quackery" lisää hieman.

Tämä neuvo on melko tangentiaalinen - et ole oikeastaan käsitellyt kysymystä.Ehdotetut ratkaisut saattavat ratkaista erityisesti muita ongelmia, mutta ne eivät ratkaise tämän sivun kysymyksen ** perusongelmaa, joka on sekaannus kehysten ja hyötykuormien ohittamisessa.Ehdotuksesi hylkäsi korkeintaan * kelvollisen * datan, joka upottaa kehystystavun CRC: n tai vastaavan virheen takia, ilman mitään tapaa kommunikoida.
Itse asiassa tämä vastaus pahentaa sitä.Alkuperäisessä oli vain datatavut ja lopetustavut.Tämä lisää kolmannen luokan, CRC-tavut.Ja kuten tässä esitetään, ne voivat saada minkä tahansa arvon, mukaan lukien {10,13}.
@MSalters: CRC voidaan ASCII-koodatulla heksalla estää tämä ongelma.Toinen temppu, jonka olen nähnyt RS485: llä, on asettaa bitti 7 aloitus- / osoitetavulle.
Re * "CAN, joka ottaa näytteet jokaisesta yksittäisestä bitistä useita kertoja." *: Bittiarvon todellinen näytteenotto on vain kerran bittiä kohti.Mitä tarkoitat täällä?Jonkinlainen virheen tarkistus, kuten lähettäjä?Kellon synkronointi?
Tarkistussumman kääntäminen tehtiin niin, että koko tietolohkon summaaminen johtaisi nollaan, joka on hieman helpompi koodata ja hieman nopeampi suorittaa.Lisäksi CRC on paljon parempi kuin sinä teet sen, etsi se Wikipediasta.
@ChrisStratton Kysymyksessä kysytään kuinka turvallinen tietty UART-protokolla on, joten on melko tärkeää huomauttaa, että riippumatta siitä, mitä teet, se ei ole ollenkaan erityisen turvallinen.Tai muuten OP saattaa juosta pois käytöstä käyttää jotain kriittistä tehtävää, kuten olemme nähneet yhä uudelleen.Koska sivusto käsittelee _tekniikkaa_, meillä on vastuu huomauttaa tästä, koska historiallisesti useimmat kotitekoiset UART-protokollat perustuivat pikemminkin quackeryyn kuin todennäköisyysteoriaan.
No, ymmärrät väärin tämän sivuston.Voit antaa vastaukseksi * lisä * suosituksia, mutta se ei ole ** vastaus **, jos se ei koske oikeastaan esitettyä kysymystä.Lähettämisesi * jättää yksinkertaisesti huomiotta * sen, mitä kysyjä todella halusi tietää.Käytännössä julistajan järjestelmä * ei toimi lainkaan * ennen kuin he ratkaisevat sen, mitä haluavat tietää.Vaikka monien käytännön järjestelmien * ei tarvitse käsitellä sitä, mitä yrität lisätä.
@ChrisStratton Q: "Kuinka vikaturvallinen \ n \ on pysäytyskohdina?"V: Ei lainkaan turvallinen mihinkään tarkoitukseen.
Toisin kuin ehdotuksesi, ne todella toimivat * suurimman osan ajasta *.Ehdotuksesi ei toimi ollenkaan, ** koska jätät huomiotta kysymyksen, jota kysymys ratkaisee **.
@Transistor Ei, et voi lähettää FCS: ää ASCII: ksi.CRC-polynomi on suunniteltu vastaamaan erilaisten virheiden todennäköisyydelle paitsi hyötykuormassa myös itse FCS: ssä.Jos koodaat sen ASCII: lla, yhden bitin virhe saattaa kiertää "vasaran etäisyyden" yli, joten yhden bitin virhe johtaa tietojen dramaattisiin muutoksiin.
@PeterMortensen No, kerran bittiä kohti ja kerran synkronointipistettä kohti.SJW, jonka avulla se voi erota hieman.
Nick Alexeev
2019-04-20 02:07:04 UTC
view on stackexchange narkive permalink

... Voin kuvitella, vaikkakin pienellä todennäköisyydellä, että viestini saattaa sisältää arvot "10 ja 13" peräkkäin, kun ne eivät ole pysäytyskohdat.

Tilannetta, jossa osa tiedoista on yhtä suuri kuin lopetussarja, tulee ottaa huomioon suunniteltaessa sarjatietopaketin muotoa. Toinen huomioitava asia on, että mikä tahansa merkki voi vioittua tai kadota lähetyksen aikana. Aloitusmerkki, lopetusmerkki, tietojen hyötykuormatavu, tarkistus- tai CRC-tavu, eteenpäin tulevan virheenkorjaustavu ei ole suojattu korruptiolta. Kehystysmekanismin on kyettävä havaitsemaan, kun paketilla on vioittuneita tietoja.

Tähän on useita tapoja lähestyä.

Oletan, että paketit kehystetään vain sarjatuotteilla. Kädenpuristuslinjoja ei käytetä kehystykseen. Aikaviiveitä ei käytetä kehystykseen.

Lähetä paketin pituus

Lähetä paketin pituus alussa lopussa olevan loppumerkin sijasta [tai sen lisäksi].

Plussat: Hyötykuorma lähetetään tehokkaassa binaarimuodossa.

Miinukset: Paketin pituus on tiedettävä lähetyksen alussa.

Pakene erikoismerkit

Pakene erikoismerkkejä, kun lähetät hyötykuormatietoja. Tämä selitetään jo aikaisemmassa vastauksessa.

Plussat: Lähettäjän ei tarvitse tietää paketin pituutta lähetyksen alussa.

haittoja: Hieman vähemmän tehokas riippuen siitä, kuinka monta hyötytavua on vältettävä.

Hyödykedata on koodattu siten, että se ei voi sisältää aloitus- ja lopetusmerkkejä

Paketin hyötykuorma on koodattu siten, että se ei voi sisältää aloitus- tai lopetusmerkkejä. Yleensä tämä tapahtuu lähettämällä numerot ASCII- tai Hex-ASCII-esityksinä.

Plussat: Ihmisen luettavissa tavallisilla pääteohjelmilla. Pakenemista ei tarvitse koodata. Ei tarvitse tietää paketin pituutta lähetyksen alussa

haitat: Alhaisempi tehokkuus.Yhden tavun hyötykuormatiedoista lähetetään useita tavuja.



Tämä Q & A käännettiin automaattisesti englanniksi.Alkuperäinen sisältö on saatavilla stackexchange-palvelussa, jota kiitämme cc by-sa 4.0-lisenssistä, jolla sitä jaetaan.
Loading...