Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Asinhrono citanje sa USB-serial problem | Android/Java
#1
Pozdrav,

imam dosta glup problem ali ne znam kako da ga resim.

U pitanju je Android/Java i citanje sa seriskog USB porta.

Problem je manje vise klasika, treba da primimim paket podataka koji je na zalost promenljive duzine. U samom paketu ima i informaciji o duzini (treci i cetvrti bajt). Paket uvek ima i start sekvencu (0xDA 0xDA, prvi i drugi bajt)

Samo primanje se radi preko registrovane callback funkcije u nekom svom posebnom thread-u. Sve je to na nivou neke biblioteke viseg nivoa (baziranoj na Android API - Java).

Moj code samo stigne na kraju u tu callback funkciju i na meni je dalja obrada, za sad printam sta je to stiglo.

Evo prakticno "prepiska" izmedju Android-a i tog seriskog uredjaja i linija gde nastaje problem. Problem je 3. i 4. linija koja u stvari mora da bude jedan paket.

Quote:1. 2020-03-30 19: 42 :19.957 1887-1887/com.example: TX >>> DA DA 00 06 00 01 02 0A 0B 1E 
2. 2020-03-30 19: 42 :19.975 1887-1931/com.example: RX <<< DA DA 00 0A 00 01 02 0A 0C 38 00 00 01 14 
3. 2020-03-30 19: 42 :22.002 1887-1931/com.example: RX <<< DA DA 00 0A 00 01 02 0A 
4. 2020-03-30 19: 42 :22.018 1887-1931/com.example: RX <<< 0A 37 00 00 01 15 
5. 2020-03-30 19: 42 :22.354 1887-1931/com.example: RX <<< DA DA 00 06 00 01 02 0A 14 27 

Treba da "rekonstrusem" paket, da spojim te delove koji su primljeni iz dva puta u jedan da bih mogao dalje da procesiram.

Mozete da predlozite i resenje u nekom pseudo codu, samo da vidim logiku kako to sve da odradim.
Reply
#2
'De me nađe. Ja baš sad radim USB na 1-wire. Ovom "tvom" nedostaje CRC. Ja cu da ga implementiram kod mene.
Predlog:
Digni neku promenljivu (kad uđeš u callback) ako se broj bajtova ne slaže sa promenljivom koja označava dužinu.
U sledećem pozivu callback funkcije proveravaj tu promenljivu pa ako se broj primljenih slaže obori je na nulu, spoj bajtove sa prethodnim i to bi trebalo da radi.
Reply
#3
Nisam doktor al' volim da pogledam Smile
Što ne šalješ pakete iste dužine pa iza određenog markera 'odsečeš' višak? Ili na početku strima nešto što će se zanemariti kao info?
Iako asinhrono slanje (bez provere sadržaja), čitanje mora da prati neka pravila.
Reply
#4
Nemam uticaj na taj USB uredjaj, to je neki specifican modul sa svojim firmware. Po tom pitanju ne mogu nista da menjam, samo mogu da se "snalazim" sa moje strane u Java code-u.
Reply
#5
A neki timeout, pa kazes poruka je stigla ako je od poslednjeg primljenog bajta proslo vise od dve duzine prijema bajta, u suprotnom se kalemi na prethodnu?
Reply
#6
Kriticno mi je sa timeout, paketi mogu da budu duzine od cca 6 do 150 bajtova duzine.
Vidi se i u onoj prepisci, stigao deo paketa, posle nekih 16ms stigao ostatak. Posle 350ms stigao drugi paket.
Problem je sto ne znam gde ce da ga "prelomi", kako mu se cefne ...
Reply
#7
Ne timeout na celu poruku, nego timeout posle primljene poruke. Ako ne stize nista 20ms recimo, tu je onda kraj poruke. Ako stize, primljeno parce se nastavlja na prethodno, dokle god stize sa pauzom manjom od recimo 20ms nije kraj poruke
Reply
#8
Hmm, to bi moralo vec da se hendluje na nizem nivou tj da zaobidjem tu biblioteku koju sam koristio (povalicm kompajliran JAR biblioteke).

Ova je u pitanju:
https://github.com/felHR85/UsbSerial

U samoj biblioteci imaju delovi coda koji su nalik ovome (bulkTransfer je Android-ova funkcija), i uglavnom su svuda za timeout stavljali 0 sto znaci da nema timeout (cudno, sto se onda sve ovo desava!?):

Code:
return connection.bulkTransfer(outEndpoint, buffer, buffer.length, timeout);
Reply
#9
Bogu hvala ja sa JAVA ne radim, ali koliko vidim u SerialInputStream.java ima neka metoda
setTimeout(int timeout)
koja postavlja timeout koji se koristi u
device.syncRead(b, off, len, timeout)
pa ko velim, mozda da probas da stavis nesto vece od nule, u kojim god da je jedinicama Big Grin Na primer 20 Big Grin
Reply
#10
Ajd probacu i sam tim nesto. Vec sam se se igrao sa nizim pristupom (bulkTransfer) bez biblioteke i odprilike sam slicne probleme imao. Usput su se pojavili i drugi problemi koje nisam izhendlovao pa sam zato presao na tu biblioteku.
Mogao sam da upotrebim C/C++ biblioteku LibUSB sa jos nizim pristupom i naravno sa jos vise nekih problema koji bi me cekali (ioctl, thread-ovi i ostalo)
Dosta je kompleksnija USB implementacija na host strani kada imas OS, na device (MCU) strani to je neuporedivo manji scope problema i delimicno sve jednostavnije.
Reply
#11
da li ti poruke tj delovi stizu dobrim redosledom samo iseckane?
jer ako je tako sta te sprecava da red koji ne pocinje sa DA DA prisljamcis za prethodni jer verovatno njemu pripada,
ili drugo resenje da proveris u tekucem redu koji je poceo da DA DA koja je ocekivana duzina poruke, pa ako fali nesto na kraju reda da ga dodas iz sledeceg?
Reply
#12
Dobro je sto uglavnom stize dobrim redom poruke, jedna za drugom.
Znam sta mi predlazes, samo ne mogu da skontam u glavi kako prakticno da odradim.
Imam samo jedan entry-point odakle mogu da radim logiku, moram da pratim predhodno i sadasnje stanje + logika da radi i kada je sve normalno.
Reply
#13
Mozda ima smisla da na USB-u procitas prva 4 bajta poruke koja stize gde ces da vidis kolika je duzina celog RX-a o onda citas ostatak poruke poznate duzine koju vidis u 3. i 4. bajtu....
„Tastatura nije otkrivena. Pritisnite F1 za nastavak“
- Windows
Reply
#14
Cao Miki,
i ja milsim da je ovo logino resenje

Code:
Digni neku promenljivu (kad uđeš u callback) ako se broj bajtova ne slaže sa promenljivom koja označava dužinu.
U sledećem pozivu callback funkcije proveravaj tu promenljivu pa ako se broj primljenih slaže obori je na nulu, spoj bajtove sa prethodnim i to bi trebalo da radi.

Kada se sinhronizujes sa pocetkom poruke inicializuj promenjivu koje je jednaka ocekivanoj duzini.
Ako je stiglo manje sacekaj sledeci paket. Kada stigne spoj ostatak sa vec primljenim podacima, opet se sinhronizuj sa pocetkom i tako u krug.
Reply
#15
napravi vestacki buffer od jedne poruke, (tu drzis staru poruku) tek kad u novoj dobijes DA DA onda prethodnu proglasis kompletnom i ocistis buffer i strpas sadasnju poruku u njega
Reply
#16
(03-30-2020, 10:21 PM)enaB Wrote: Bogu hvala ja sa JAVA ne radim ...

Blago tebi, ovo u zivotu nisam video do sad ... pa jel su oni normalni, sta je bre ovo Smile
Primer/test, ako je 7 bita velicina onda moze na jednu foru al' ako je 8 bita ili vise podatak onda na drugu ... signed/usigned nesto ... stvarno nisu normalni ...

[Image: attachment.php?aid=32592]

Intelisense je bas super i mnooogo pomaze, aliii kad mi kaze da ce uslov uvek da evaluira u TRUE zbog ovog problema, pa jos kaze tamo "Find cause" i ne moze da nadje uzrok ... mislim ...ludnica

Mislim da sam resio ovo sa prijemom, samo da testiram pa cu da postavim code, drndalo me ovo gore jer je shizeo sa 0xDA dok nisam stavio (byte)0xDA ...


Attached Files Thumbnail(s)

Reply
#17
Bahh, prerano sam se ponadao, nece moci ovako kako sam zamislio, morace sa tajmout da se radi i da se prima bajt po bajt.
Gledao na osciloskopu sta se stvarno desava i sad ima slucaja da je spojio dva paketa u jedan bez ikakve pauze, pa onda pauza cca 60ms pa stigne druga povorka ...

Pogledao sam da slucajno nisu koristili flow-control, u igri je FT232RQ i nista nije drugo povezano osim RXD i TXD ...
Reply
#18
Miki,
pada mi na pamet ideja da umjesto jedne poruke napravis dvije.
Prva poruka tipa start, start, broj_bajtova_iduce_poruke, CRC, stop.
E sad prijemnik ceka bas broj_bajtova_iduce_poruke, pa onda spaja, razdvaja, provjerava,....
Cerka se nesto igrala na poslu oko USB pa ako bude mogla pomoci vici.
Reply
#19
@veselinovic

(03-30-2020, 08:33 PM)mikikg Wrote: Nemam uticaj na taj USB uredjaj, to je neki specifican modul sa svojim firmware. Po tom pitanju ne mogu nista da menjam, samo mogu da se "snalazim" sa moje strane u Java code-u.

Bas je nezahvalna situacija, nisam pametan sta da radim, valjalo bi da se drzim JAVA coda i Android API-a zbog kompatibilnosti. Druga opcija je da predjem na nizi nivo tj C/C++ ali to mi je jos sve drasticno kompleksnije.

Ehh, kad se setim da se to na STM32 resava sa jednom funkcijom od 15-ak linija C coda i jednim HW (idle) interaptom i radi besprekorno ...
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)