» »

Tezava s COM komunikacijo

Tezava s COM komunikacijo

bozjak ::

LP!

Naj najprej samo omenim, da je program napisan v C++ (QT), a mislim da to ni pomembno.

Imam sledec problem: Napisal sem terminal za COM komunikacijo, ki dela BP RAZEN ko je linija 100% zasedena dalj časa. Torej naj razložim, če po com portu pošljem request in druga stran odgovori je vse v redu. Če se to dogaja v loopu je vse v redu (samo da je nekoliko pavze vmes).

Če pa od druge stvari zahtevam da poslje dolg string (po par 10k znakov brez pavze) se po terminalu po določenem času zmesa, torej znake še vedno dobiva, le ne vseh, v napačnem formatu, itd... To se vedno zgodi po določenem času (oz po približno enakem številu bitov), ni mi pa jasno zakaj. Po tem ko se terminalu zmeša pomaga le reconnect (ni potrebno ponovno zagnati programa), če ročno zahtevam pavzo od druge strani po pavzi še vedno ne prihajajo pravilni podatki. Po reconnectu pa se zgodba ponovi. Nekaj časa dela BP nato se mu zmeša, recconnect in smo spet tam kjer smo bili.

Ni mi jasno kaj bi lahko bilo, saj zadeva deluje v nedogled (testirano s kratkimi stringi je bilo tudi 1 teden brez prekinitve) če le ni dolgih stringov. Z linijo / COM portom je vse v redu, saj z drugimi podobnimi programi deluje vse BP.

Hvala za pomoc, LP
http://upor.blogec.si
http://bozjak.deviantart.com

snow ::

Mogoče se pri tako dolgih stringih pozna, da oddajnik in sprejemnik nista na popolnoma enaki hitrosti zaradi interne ure. Če je oddajnik na 9601 baud sprejemnik pa na 9600 se bo po 9600 poslanih baudih vse pomešalo (zamaknalo na en bit). Pravim možno.

Kakšen oddajnik imaš? Kak drug PC ali kak mikrokontroler?

Včasih pomaga, da pokažeš del(e) relavantne kode - če ni top secret se ve ;)
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins

Groove ::

sicer se ne nanaša dobesedno na to temo, ampak ti dam predlog, da celoten program popraviš tko, da bo delu na novejših portih (npr USB), ker je samo sranje s temi COM porti. plus tega, da novejše plate po večini nimajo integriranega COM porta itd itd. uglavnem ogromno problemov pol pride s temi com porti :D

Azrael ::

Tudi moje mnenje je, da zadeva prej ali slej pade ven iz sinhronizacije. Izgubi en znak in tako pridejo ven hieroglifi.

Enak problem sem imel, ko sem hotel poenostaviti komunikacijo z merilnim inštrumentom. Nekaj časa je bilo vse OK, potem pa so začele leteti ven vse sorte cifer, samo pravih ni bilo.

@PraznaGlava:

USB, kljub imenu ni rešitev za vse, navadno je z njim povezovanje kakšne starejše opreme zapravljanje časa, saj v 99.999...% ne dela ali dela tako, da bi bilo mnogo bolje za vse, če sploh ne bi delalo. Lep dokaz so razni USB COM pretvorniki, ki v realnosti ne delajo z ničemer.

COM port je HW robustno in enostavna zadeva in za nekatere aplikacije enostavno na celi črti povozi kao naprednejši USB. Prenosniki, ki imajo COM port vgrajen se še dobijo novi, za dektop mašine, kjer COM porta ni več našvasan na matični, pa obstajajo PCI kartice. Zaenkrat ni problema.
Nekoč je bil Slo-tech.

Brane2 ::

Napake zaradi rahlo različne hitrsti prenosa tu niso verjetne, ker je COM asinhron.

Če sta clocka enaka na ene 6-8%, bi morala stvar delati, ker se stvar sinhronizira na start bitu.

Je pa možno/verjetno nekaj drugega. Lahko da je nekaj narobe z bufferjem tvojega čipa.

Nekje v kernelu piše, da se mnogi 16450-compatible čipi predstavljajo kot 16550 compatible, čeprav nimajo ustrezno globokega bufferja.

Poglej, kateri driver je uporabljen v kernelu za čip in za kateri čip gre, ter po potrebi probaj z bolj vanilla driverjem.
On the journey of life, I chose the psycho path.

snow ::

Brane a do sinhronizacije pride tudi če je start bit takoj za zadnjim bitom podatka (oziroma stop bitom)?


Po moje bi zelo kratka pavza v oddajanju pokazala, da je problem v sinhronizaciji,
bolj pogosto branje bufferja pa, da je problem v bufferju.

Stestiraj in poročaj. :)
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins

Brane2 ::

Brane a do sinhronizacije pride tudi če je start bit takoj za zadnjim bitom podatka (oziroma stop bitom)?


AFAIK da. Start bit je "0", stop pa "1".


Po moje bi zelo kratka pavza v oddajanju pokazala, da je problem v sinhronizaciji,
bolj pogosto branje bufferja pa, da je problem v bufferju.


Vprašanje koliko lahko vplivaš na pavzo in kdaj so podatki res poslani, če se zanašaš na high-level rutine za pošiljanje.

Poleg tega skrbi za sinhronizacijo čip. Če ti dela s kratkimi stringi, bi morala tudi z dolgimi.

Mi je pa padlo še nekaj na pamet:

- je pariteta na obeh straneh enako nastavljena ? ( ponavadi brez paritete)
- imata obe strani enako nastavljen handshake ? Ponavadi je hardverski preko dodatnih linij RTS/CTS, lahko pa je softverski z oddajo XON/XOFF kod.

Če si to zašuštral, se zna zgoditi da sprejemna stran uporablja SW handshake in poskuša ustaviti oddajno z XON/XOFF, kar ta ne razume ali celo zmede njen sprejemni SW, ki vidi XON/XOFF kot motnje...
On the journey of life, I chose the psycho path.

bozjak ::

hvala vsem za odgovore.

Ok naj malo bolj razjasnim zadevo. Na drugi strani prenosa je afaik mikrokontroler (pač postaja, ki jo je razvilo naše podjetje) in sam sem imel v mislih, da je nekaj izmed naslednjih možnosti:

- mala razlika v baud rate.
- različne timeout vrednosti (čeprav to pomoje nebi smelo vplivati, glede na to da do timeouta ne pride)
- različen handshake

Relavantna koda je ubistvu samo recive funkcija:

int beri(int n, QString *prebrano)
	if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL))
	{
		//napaka, sporoci uporabniku
		return 0;
	}
	else *prebrano = QString(szBuff).left(dwBytesRead); //prepise vse dobljene znake
	
	for (int i=0;i<dwBytesRead;i++) szBuff[i]='\0'; //izprazni buffer.
	
	return 1;
}



Najbolj vrjetno je, da je problem v hanshaku, moram priznati, da prej nisem pomislil na to, preprosto zato, ker je zadeva delovala (vsaj na kratkih prenosih). Na terminalu delam z "no hanshake", na postaji pa bi znal biti nastavljen hardwerski.

Bom se še malo igral, pa poročam.

Hvala, Lp
http://upor.blogec.si
http://bozjak.deviantart.com

bozjak ::

OK takole, malo sem se igral, na novo napisal funkcijo, ki klice funkcijo za branje, itd... aMpak nic ne pomaga, zato sem se lotil tesitranja. Odlocil sem se, da bom iz enega racunalnika na drugega (oba uporabljata moj terminal z identicnimi nastavitvami) poslal dolg string z zaporednimi stevilkami, tako da bom videl kaj tocno se dogaja.

Rezultati so taki:

9600 bps : 1111 (+/- 10)
19200 bps : 1081 (+/- 10)
38400 bps : 1046 (+/- 10)

Ne vem sicer kako je znak definiran v QStringu ampak domnevam da je 8 bitov za vsak znak, torej se moj program sesuje po okoli 30kb...

Ocitno se sesuje prej, ce je hitrost visja, a razlika ni velika. Tukaj nima veze a je uporabljena pariteta ali ne.

Ali je se kaksna ideja, ki bi mi pomagala resiti tezavo?

Hvala, LP
http://upor.blogec.si
http://bozjak.deviantart.com

snow ::

Kaj če daš po 1000 poslanih znakih pavzo za ene par bitov?
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins

Brane2 ::

Par predlogov:

-probaj zadevo brez ACPI podpore v kernelu ( start parameter noacpi)

-zrolaj si nov kernel s podporo _samo_ za prastari vanilla 8250 COMport chip

-probaj te tvoje teste na istem COMPortu sprejemat in oddajat hkrati ( naredi si loopback konektor) in poglej, če dobiš nazaj to, kar si oddal

- probaj, če na rezultat vpliva kaj narava poslanih podatkov. Poskusi denimo pošiljati same ničle, same enke, "0F", "F0" ali preplesti random podake s prej omenjenimi in poglej, kdaj stvar pade. Poskusi tudi s pavzami
On the journey of life, I chose the psycho path.

Brane2 ::

Še en preedlog:

Ne vem sicer, kaj počneš ampak mogoče bi kazalo razmisliti raje:

- o uporabi USBja, če gre za stvar, ki bo ob računalniku

- o uporabi Etherneta, če bo stvar nekaj dlje.

COM je zastarel in na mnogih ploščah ga ni več. Poleg tega je svinjsko počasen in nasploh neroden. Full enih žic in glavobolov za beden učinek.

Glede na to, da nisi v tem doma in da ti premagovanje problemov jemlje nekaj več časa, bi mogoče kazalo razmisliti o končnem učinku.

Ko enkrat premagaš probleme in opraviš pot do konca, naj bo za nekaj, kar ne bo že v štartu zastarelo.

Če pa gre za legacy opremo, na katero si vezan in pač moraš iti preko COMporta, je to seveda druga stvar.
On the journey of life, I chose the psycho path.

bozjak ::

Komunikacija mora obvezno potekati preko COM porta, to sploh ni vprasanje. Prav tako pavza po par k bitov ni možna rešitev, ker oprema s katero mora program v končni fazi delati, pač deluje kot deluje, in na to ne morem jaz vplivati. Je pa dejstvo, da po tem ko program propade (začne izpisovati nesmisle) preprost reconnect pomaga, in deluje vse pravilno, dokler pač ne pride spet do problema.

Hvala za odgovore, Lp
http://upor.blogec.si
http://bozjak.deviantart.com

Brane2 ::

O.K. Tisto s pavzami ni mišljeno kot končna rešitev, le kot debug orodje s katerim bi lažje določil mesto in naravo problema.
On the journey of life, I chose the psycho path.

Brane2 ::

BTW: kaj če bi si omislil enega od tistih oceni USB --- COM adapterjev ?

Če gre za kako resnejš aplikacijo, potem mogoče vložek od extra €10-20 lahko odtehta glavobole ?
On the journey of life, I chose the psycho path.

Brane2 ::

BTW: Kako ima tvoja naprava implementirana COM port ?

Gre na konektro samo tisti Rx, Tx in GND ( pina 2,3 in karkoli je že GND) ali še kaj več ?
On the journey of life, I chose the psycho path.

Brane2 ::

BTW:

Tisti predlog z zrolavanjem novega kernela spremeni v:

- zrolaj so nov kernel, ki bo imel COMport podporo v modulu in ne v kernelu. To velja tudi za podporo COMu skozi različne čipe (stari 8250, novi 16450, 16550,16550A)

- poglej v kernel parametre, če se da nastaviti zaznavanje čipa v stilu COM1=8250 ali kaj podobnega, da ti ni treba novega kernela delat.
Ti so zlistani v kernel source direktoriju. Pri meni je to /usr/src/linux/Documentation/kernel-parameters.txt
On the journey of life, I chose the psycho path.

bozjak ::

Na noben nacin si ne morem z USBjem pomagati. Zal. Sploh ni vrjante (res... sigurno...), tko da lahko to opustimo...

Karnela pa tudi ne bom slatov, ker zagotovo vem, da je problem v mojem programu in ne v OS-ju (drugi terminali delajo povsod BP)

Nasprava ima realizirane samo osnovne pine, torej tako kot si rekel 2 ali 3 pine in GND.

Glede pavze pa je tako... Pavza problem vsekakor resi ko gre za komunikacijo s postajo (torej kadar gre za prenos krajših stringov je vmes kratka pavza), tudi pri prensasanju znak po znak med dvema racunalnikoma ne pride do tezav, tako da pavze ne bom dodatno vgrajeval za debug ker sem sigurn, da ob uporabi pavze program nima tezav.

Hvala za pomoc... LP
http://upor.blogec.si
http://bozjak.deviantart.com

Brane2 ::

Če so uporabljeni samo trije pini, ptem moraš imeti softverski način za handshake ali pa biti prepričan, da bufferja na nobeni strani ne boš nikoli prenafilal.
On the journey of life, I chose the psycho path.

bozjak ::

najlepša hvala! Vrjetno je bil prenafilan buffer kriv za to, ker pojasni vse težave, ki jih program ima...

Lp
http://upor.blogec.si
http://bozjak.deviantart.com

bozjak ::

Ja res je bil buffer. Ravnokar sem popravil, da prebere vecje stevilo bitov iz bufferja (Glej funkcijo zgoraj), in sedaj brez problema prebere tudi tiste daljse stringe.

Sedaj pa imam tezavo (za spremembo :D ) : A je kaksnen nacin, da bi preveril koliko znakov / bitov / bajtov (...) je shranjenih v bufferju? Rad bi namrec vsakic prebral vse, kar je v bufferju.

Problem je v tem, da sem imel prej nastavljeno na 1, torej vsakic ko je sel brat buffer je prebral 1 znak. Rezultat poznate ^^. Sedaj sem to nastavil na 100, in prebere vse, AMPAK je problem ker to ustvari zelo velik lag za uporabnika, ko poskusa kaj natipkati v terminal, ali dati kaksno drug ukaz (cel program obcutno zaostaja za uporabnikom), kar je izredno motece in tako pac ne more ostati.

Zanima me torej, ce je mozno, da bi vsakic prebral celotno vsebino bufferja. Ce je v tem 100 znakov naj jih prebere vseh 100, ce jih je le 10 pa le 10, tako da bo lag za uporabnik cim manjsi.

Hvala, LP
http://upor.blogec.si
http://bozjak.deviantart.com

snow ::

Niti (threads) - http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html.

Program bo delal dve(ali več) ločeni stvari istočasno (en za komunikacijo, drugi za vmesnik). Včasih je hudič v sinhronizaciji, ampak z zgornjim tutorialom bi se moralo naredit kaj uporabnega.
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins

BigWhale ::

Flow control se temu rece ja. Ce imas 'preslab' kabel, potem moras to poceti softversko. XON/XOFF si poglej.

S threadi si bos (precej verjetno) zakompliciral zivljenje. DOS programi so 15 let nazaj znali delati to kar ti pocnes sedaj, pa takrat se nihce ni delal threadov.

Brane2 ::

Ja, threadi tudi IMHO niso odgovor na tole. Zagotovo je kje funkcija, ki ti dovoljue prebrati vsebino bufferja, kot je v danem trenutku brez čakanja na neko zahtevano količino podatkov ali kaj temu ustreznega.
On the journey of life, I chose the psycho path.

bozjak ::

Najlepsa hvala za odgovore, tudi sam mislim, da threadi niso rešitev tukaj.

Problem sem ravnokar rešil preprosto z eno loop zanko, ki se ponavlja dokler je st prebranih znakov enako stevilu klicanih znakov (n == dwBytesRead), kar deluje prfektno (da pa zadevo pospesim, n v vsakem koraku zanke povecam).

Hvala za pomoc, Lp
http://upor.blogec.si
http://bozjak.deviantart.com

bosto ::

preberi si Serial Programming Guide for POSIX Operating Systems mogoce pa bos kej novega in uporabnega zvedu :)


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Simuliranje COM porta?

Oddelek: Pomoč in nasveti
6818 (661) Tilen
»

POS tiskalniki in v DOS okolju

Oddelek: Pomoč in nasveti
102642 (2026) Duhec
»

[VB] Komunikacija s serijskimi napravami

Oddelek: Programiranje
412306 (1580) mNeRo
»

Nul modem povezava, nujno

Oddelek: Programska oprema
5889 (811) Brane2
»

Modemi - Windowsi jih ne zaznajo!(podarim DivX Film, RES!)

Oddelek: Pomoč in nasveti
121815 (1622) miranpozar

Več podobnih tem