Soros port alacsonyszintű kezelése

Sziasztok!

Van egy Brymen BM817 típusú true RMS multiméterem immáron 3 éve. Ennek van egy optikai RS232 illesztője. Az interface működik, VirtualBox-ban futó Windows XP-n a hozzá adott programot életre tudtam kelteni.

Ugyanakkor azt szeretném, hogy tudjak Linux alól kommunikálni a műszerrel. Ehhez kellene a soros, RS232 portot viszonylag alacsony szinten kezelni. Ennek az egyik oka, hogy a handshake vonalakból szerzi a tápot az illesztő, amelyik a fototranzisztorral vett jeleket a PC soros portjának RxD lába felé küldi. Ebből tehát látszik, hogy a handshake vonalak állapotát nekem kellene beállítani. (A kapcsolat egyébként duplex. Talán half. :) )

A kommunikációs protokoll dokumentációja a műszerhez adott CD-n megtalálható. A formátum 9600 baud, 8n1. Ugyanakkor van benne némi időzítés, a doksi például az inicializálásnál ír egy ilyen szekvenciát:

1. Initiate COM port
2. Wait for 100 ms
3. Set RTS = 1
4. Wait for 100 ms
3. Set RTS = 0
4. Wait for 100 ms
5. Set RTS = 1
6. Set (baud rate, parity, data bit, stop bit) = (9600, N, 8,1)
7. Locate 22 RXD buffers
8. Clear RXD buffers
9. Clear TXD buffers

Érzésből úgy gondolom, a 100 ms-ot nem kell, nagyon pontosan tartani.

Ennek megvalósításához a glibc mely függvényeivel kerüljek közelebbi kapcsolatba?

Hozzászólások

Már régen írtam ilyet, de termios.h tcgetattr() tcsetattr() tcflush() függvényekre és a termios struktúrára biztosan szükséged lesz. (Remélem, jól emlékszem!) Még beugrik halványan valami cfsetispeed() és cfsetospeed() is.

Ha van türelmed, akkor megköszönöm. Ma már nem, de elküldöm a doksit privátban. Nem hosszú, nem is bonyolult. Mikrokontrollerre megírnám könnyedén assembly-ben, ugyanakkor C-ben nem vagyok gyakorlott. Persze, megküzdenék vele, de jó látni egy-egy megoldást, ötletet.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Linuxban nem egy túl bonyolult feladvány. Nagyon jó leírása van és a példaprogramokkal akár el is indulhatsz:
http://tldp.org/HOWTO/Serial-Programming-HOWTO/

FLAME: Nagyon utálom azokat a megoldásokat ahol a soros vagy a printer portot használják ilyen módon, kispórolva néhány alkatrészt - bár, különösen 10-15 éve ez szokvány megoldás volt még én is rákényszerültem. Manapság, én azt javasolnám, hogy egy soros-USB átalakítót iktatnék be - így USB -n kellene kommunikálni (ugyan ez is egy soros portként lesz kezelve) és korrektül ki lehet nyerni a fototranzisztorokhoz szükséges tápot, pl. egy ilyesmit vennék alapul:
http://pinouts.ru/Converters/usb_serial_adapter_pinout.shtml
Van ennél egyszerűbb kivitel is erre, de most hirtelenjében ezt találtam.

* Én egy indián vagyok. Minden indián hazudik.

A műszer adott, soros porton kommunikál. Helyesebben szólva optikai módon, ami a galvanikus leválasztás miatt szükségszerű, hiszen egy ilyen műszerrel rácsatlakozhatunk a 0.4 kV-os hálózatra is például. Az aktív táplálás körülményes, mert kellemetlen lenne még egy tápegység is a soros illesztő mellé, így marad a gányolás.

Az USB-RS232 átalakító jó gondolat, a táplálás is megoldott, ugyanakkor eléggé ágyúval verébre.

Neked is köszönöm a linket. Ha ennyi segítség után nem tudom megírni, azt hiszem, elmegyek a gazdaboltba kisásóért, s elásom magam. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Éppen elkezdeném csinálni, erre máris elakadtam. Egy példában látom az alábbit:


#define EINTR_RETRY(expression) \
    ({ \
        long int _result; \
        do _result = (long int) (expression); \
        while (_result == -1L && errno == EINTR); \
        _result; \
    })

int
open_port (char *port_name)
{
  int fd;

  fd = EINTR_RETRY (open (port_name, O_RDWR | O_NOCTTY | O_NONBLOCK));
  if (fd == -1)
    {
      perror ("open_port: Unable to open port");
    }
  else
    fcntl (fd, F_SETFL, 0);

  return (fd);
}

Azt tegyük félre, hogy abban a #define-ban talán a SIGINT-et kezelnék, s nem értem, de ez most nem is annyira fontos. Ugyanakkor az miért van, hogy megnyitja a portot - pl. /dev/ttyS0 - nonblock módban, majd ha sikerült, akkor blokkolóssá változtatja a beállítást? Nem lenne egyszerűbb az O_NONBLOCK flag elhagyása? Ha úgysem sikerül a megnyitás, akkor nem mindegy? Ha meg sikerül, akkor meg úgyis blokkolós kell, nem? Vagy itt valami egészen másról van szó?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ennek nem sok értelme. Az igazság az, hogy liboop -ot szoktam használni. A liboop kiváltja a select -es nonblock dolgokat - csak akkor hívja meg az olvasási rutint, ha van mit beolvasni és pont. Mellesleg lekezeli a különféle signalokat, biztosít timereket stb. (ha jól emlékszem a boa http szerver is ezzel működik, kicsit zavaros/hiányos a dokumentáció, de nem túl komplikált, ha már átestél a windowsos multithreaden és overlapon, no meg az iocompletion queue -n akkor egyenesen egyszerű).
A számodra a lényeg, hogy nem kanonikus és piszkálnod kell a handshaket is. A te esetedben szerintem ez akár blokkoló módban is mehet (felteszem miközben ezt a cuccot olvasod nem kell 3D szupernóva robbanásokat szimulálnod a képernyőn). Az sem kizárható, hogyha beállítod a portot utána már simán írhatod/olvashatod a /dev/ttyS0 (mondjuk) egy shell scriptből.

* Én egy indián vagyok. Minden indián hazudik.

Markásan szívás van. Csináltam valamit, ám a műszer hülyeséget válaszol. A neten meg efféle mondatokat olvasok:

It supports devices using the BC-85X or DMSC-9 rs232 interfaces but not the BC-81X cable which uses a non-rs232 serial protocol.

Persze, hogy nekem ez utóbbi kábelem van. Ugyanakkor nem igazán értem a dolgot, hiszen szétszedtem, megnéztem, mi van benne, s ezzel normális RS232 átvitelt meg lehet valósítani.

Esetleg azt tudom elképzelni, hogy maga a műszer egészen más protokoll szerint kommunikál, s a BC-85X és DMSC-9 kábelekben esetleg van egy mikrokontroller, ami megoldja az illesztést. A natúr kábelnél meg lehet, trükköznek azzal, hogy megfelelő baudrate mellett olyan bitmintát állítanak be, hogy abból kijöjjön a szükséges protokoll.

Bármennyire is lehetséges, amit írtam, mégsem tűnik ésszerűnek. A műszer intelligens eszköz, abban egy sima RS232 átvitelt implementálni nagyon egyszerű feladat lett volna. Szóval egyelőre nem tudom, mi van, s sajnos eddig a Google sem segített.

Persze, nem adom fel.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Az azért lehetett, mert a műszer 7 bites formátumban kommunikált, Te meg 8 bitet vettél, így az MSB-ben, azaz a 7-es bitben a műszer stop bitjét vetted, ami ugye 1. Ha a műszer 7n2 formátumot küldött, Te 8n1-et vettél, akkor nincs baj, mert a küldött második stop bit a vett első lesz, csak ugye az adat lesz 0x80-nal OR-olva.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ugyanakkor VirtualBox alatti Windows-ból a hozzá adott software-rel működik. A gond az, hogy nincs tároló oszcilloszkópom. Semmilyen sincs.

Valahogy ki kellene deríteni, mi történik a porton, mit csinál a Windows-os program. De hogyan?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Köszönöm. Tudom én ezt. Most épp a baudrate-tel variálok, meg csináltam olyan hexdump-ot is, amelyben fejreállítottam a bitek sorrendjét. Mindezt azért, hogy időrendben lássam a biteket, hiszen az RS232 LSB first-ös, viszont amikor ránézek egy hexadecimális számra, az MSB-t látom bal oldalon, s idővel a kisebb helyérték felé haladok. Ehhez a start és stop biteket is oda tudom képzelni. Persze nehezítés, hány bit ideig van a vonal stop bit szinten, hiszen az lenyelődik.

A lényeg tehát, hogy nagy bitrate-re állítva a vevőt megpróbálom kitalálni, milyen szélesek a vett impulzusok.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

(Metex 14 Byte ASCII)
It looks like the DMM uses RTS and DTR to power the serial port. DTR needs to be set to +12 volts and RTS must be set to -12 volts.
The port should be configured for(8,N,1) at 9600 baud.
Take a reading by sending a "D" character to the DMM and then read characters from the serial port until a carriage return is found.
The format of the returned data is a 13 character line terminated by a carriage return.
Byte) 12345678901234
Ex.1) DC-1.9999 V CR
Ex.2) 1.9999MohmCR

Különben igazán megdögölhetnének, ezt találtam a doksiban:

5) COMMUNICATION PROTOCOL
5-1)
The meter and the BC-81x optical adapter cable DOES NOT use standard RS232 communication protocol in order to achieve a cost effective hardware solution. The meter and the BC-81x cable actually use synchronous SCI (Serial Communication Interface) like SSP (Synchronous Serial Port) format to simulate the RS232 format. A non-standard baud rate 3906.25bps is being used, and with different number of data bits on transmission and reception. Self-developed communication protocol and 32 low-level control commands are being used. Users are NOT recommended to develop application software under this protocol since it will be a few day seminar to fully explain the protocol details and the technique used to assure data transmission integrity.
5-2) For advanced meter users who wanted to develop their own software for custom applications, it is recommended to use the meter with our another cable BC-85x. The BC-85x cable has a microprocessor embedded inside, and will transform the meter non-standard SCI protocol to standard RS232 protocol output. Custom software development will then be much easier.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"a cost effective"
Kinek? Vagy nagyon hülyék vagy nagyon szemetek. De inkább az utóbbi. Egyedi protokoll.... Én is összekarmolnám magamat.

SSP-hez hasonlító protokoll RS232-n átnyomva. Arról a 32 db. parancsról van valami leírásod, vagy ezeket csak a fejtágítón lehetne megszerezni jó pénzért?

Hát ez az, hogy nincs semmi infó. :( A different number of data bits vajon azt jelenti, hogy hol ennyi, hol annyi, vagy a szokásos 8 bithez képest konstans más? Gyanítom, az előbbi, de attól falnak megyek.

Én is csináltam saját protokollt szerkentyűkhöz, de az az ámokfutás még sohasem jutott eszembe, hogy az adatszó szélessége változzon.

Erre a baudrate-re még csak-csak csinálok mikrokontrollerrel egy monitorozó szerkentyűt, de ezt visszafejteni nem egyszerű mulatság. Teszem azt, egy CRC-ről eldönteni, hogy az valóban CRC, mely adatok - byte-ot már nem is merek írni - kerülnek beleszámításba, milyen algoritmussal. Szóval picit elment a kedvem tőle.

A bitrate-et legalább megmondták.

Szerk.: Különben lesz.rnám, hogy cost effective, ha a köcsögök legalább kiadták volna a protokoll doksiját. Akkor hamar megírnám mikrokontrollerre. De így?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A kommunikációjuk annyira vacak, hogy miközben próbálkoztam, variáltam a baudrate-eket, volt, hogy a háttérvilágítás bekapcsolódott, volt, hogy csippant a műszer, meg olyan is, hogy hülyeséget írt a kijelzőjére, sőt, szerintem újra is indult olykor.

Ezzel csak azt akarom mondani, hogy nem nagyon van csomag integritás ellenőrzés, CRC, effélék, mert ha lenne, ilyesmi aligha történhetett volna. Egyben ez esélyt ad arra, lehet, mégis meg kellene nézni bit szinten, mi történik, mert könnyen lehet, egyszerű a kommunikáció, mint a faék.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Különben a szinkron protokoll olvasásnál még rendben is volna, de a parancs kiadásakor hogyan? Ugyanis egy LED és egy fototranzisztor van az átvitelre. A szinkron átvitelhez kellene egy CLK, egy SDI, és egy SDO. Szóval furcsaság ez, de lehet, hogy magírom egy kis PIC-re, hogy küldje el, mit lát a dróton.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Egyszer találkoztam egy olyan hőmérő IC-vel (TC77) amit a gyártója úgy hírdet hogy SPI illesztője van ("SPI/ Microwire compatible interface"). Tehát elvileg duplex átvitelről van szó. A valóságban egy óra és egy adatvonallal rendelkezik. Az adatvonal pedig kétirányú. Szabad volt saját rutinokat írni az adatátvitelre.

Lehetne az adat kétirányú, de nem az, ez optikailag van csatolva. A PC felőli interface-ben van egy infravörös LED a TxD-n, egy fototranzisztor után némi erősítés, aztán megy a jel az RxD-re, s ennyi az interface. A handshake a vevő tápfeszültségét biztosítja. A kommunikáció meg kétirányú, parancsot kell adni a műszernek, az meg mesél az életéről.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ha esetleg van logikai állapotanalizátorod vagy tudsz kölcsönkérni valakitől akkor érdemes lenne ráakasztani a vonalakra egyet.

Nekem egy USB-s kamerában kellett belenyúlni és a busztól függetlenül felprogramozni a kamera áramkört. Az lehetett tudni hogy az USB-busz illesztő és a kamera IC között I2C buszos átvitel volt. Rátettünk egy állapotanalizátort és ezzel sikerült kinyomozni hogy miket kell a kamerába írni hogy képet produkáljon. (Sajna az áramkör kínai volt amiből sejthető hogy mennyi információt lehetett róla találni a neten. Adatlap nuku.)

Egy tárolószkóp elég lenne, de nincs. Valószínűleg veszek egy PIC-et, amelynek van soros interface-e, ezzel illesztem a PC-hez, aztán megnézem, hogy amikor a VirtualBox-ban futó windows-os alkalmazás kérdezi a műszert, mi történik. Lényegében kidump-olom a bitfolyamot. Nem sűrgős a dolog, magamnak kell. Reméltem, ennél hagyományosabb a dolog, utálom, ha nincs doksi, s könyékig kell túrni a bitek között, s nem tudhatod, valóban megfejtetted, vagy lesz olyan eset, amikor a pattern konstansnak hitt részei egyszer csak mégis megváltoznak valamiért. Már, ha egyáltalán sikerül megfejteni a kommunikációt. Mindenképpen gány ez így.

Különben néztem hasonló műszerek doksiját. Ne gondold, hogy valami értelmes a kommunikáció. Képesek voltak nem ASCII textként átküldeni az eredményt, hanem elkövették azt a hülyeséget, hogy a műszer LCD kijelzőjének szegmenseit küldték át. Persze, azt sem sorrendben, hogy izgalmasabb legyen. Az ilyet sohasem fogom megérteni. Ha már ott van valaki előtt a mikrokontroller, nem mindegy, hogy 50 sor kóddal többet ír, vagy sem? Sokszor nem is többet, csak mást kell írni.

Ettől a hülyeségtől eltekintve a műszerrel nagyon elégedett vagyok. Lengyelországból rendeltem a TME-n kersztül, mert itthon vagy csak becslő készüléket lehetett kapni - értsd, speckó szerint is pontatlan, igénytelen műszer -, vagy a skála másik végén Fluke, Keithley, ahol a minimális tudású műszerben is megfizeted a márkanevet, s aranyárban mérik.

Ennek a műszernek igen kellemes a specifikációja, pontos, sokmindent tud, ugyanakkor érték/ár arányban igen kedvező volt.

Szerk.: Pontosabban szólva volt itthon megfelelő specifikációjú műszer, ha nem is sok, csak drágán. Én meg árérzékeny vagyok. Csomagküldő meghozta, örültem. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"Valószínűleg veszek egy PIC-et, amelynek van soros interface-e, ezzel illesztem a PC-hez"
Egy PIC csak 8 vagy 9 bitet visz át. Ha tudod hogy hány bites a protokoll akkor összejöhet, egyébként meg cumi. Egy PIC18F2550-el jártam úgy hogy ha a Microchip leírását követve állítottam be a soros modult akkor rossz átviteli tempót kaptam. (Egy MIDI-s eszköz illesztésekor futottam bele ebbe.) Az lett a megoldás hogy a baudrate értékét nem az init vége felé hanem az elején állítottam be.

Lehet hogy az adatátvitelt csak valammi különleges extrának tartják. Valakit ráugrasztottak a témára ő meg nagy nehezen öszegörcsölt valamit ami úgy-ahogy működik. A másik lehetőség pedig az (ezt tartom valószínűbbnek) hogy szándékosan nem adták oda a fejlesztőnek a gyógyszerét. A cél az lehetett hogy találjon ki minél képtelenebb módszert az adatok átvitelére. Így a szerencsétlen vásárló kénytelen megvenni az ő "különleges" adatkábeljüket és a hozzá adott programot jó pénzért.

Miért lenne cumi? Mikrokontrollerrel azt csinálok, amit akarok. Nyilván felszeletelem a stream-et, s saját protokollon jelölöm, hol a csomag eleje, vége.

Néha a PIC doksijából hiányzik, hogy valamit csak egy gépi ciklussal később tehetsz. Velem olyan volt, hogy a transmitter engedélyezése után kellett egy NOP a Tx regiszter feltöltéséig, ha jól emlékszem. Ezekre hamar rá lehet jönni, ettől függetlenül a PIC-ek doksijai nagyon jók.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A cumival arra gondoltam hogy ha netán hét bites lenne az átvitel akkor előfordulhat hogy a PIC nem fogja tudni rendesen feldolgozni. Nyolc bites módban a hét bites adás stopbitjét is adatnak veszi aztán várja a stop bitet ami helyett esetleg már a következő adatkeret start bitje jön. Kerethiba lesz és annyi.

Értelek már, de félreértettél. Leírom, mit tervezek.

A PIC soros interface-e a PC felé néz, a host Linux felé logol majd adatokat szabványos RS232 protokoll szerint.

A host Linuxon futtatok VirtualBox-ot, ebben Windows XP-t, s abban a multiméter alkalmazását. Ez bonyolít valami szabványtalan forgalmat a multiméterrel egy másik soros porton - tehát nem azon, amelyiken a PIC USART van. Ezt a megfigyelendő portot a PIC egy-egy port lábával monitorozom. Összegyűjtök valamennyi infót, aztán az USART-on keresztül, már szabványos RS232 protokollon felküldöm a host PC-nek, utána meg nézegetem a biteket, amíg kihullik a maradék hajam. :) A PIC portlábait pollingolom, ott nem igény a szabványos baudrate, ugyanakkor segítség, hogy tudom, 3906.25 baud-ra számítsak. Az USART persze nagyobb sebességgel küldi fel az adatokat, így nagyon bufferelnem sem kell majd.

Szóval sima portlábakkal szaglászom a gyanús kommunikációt, s a kihámozott eredményt szabványosan küldöm fel a PC-nek.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Mondottam vala, hogy mielőtt nagyon felfegyverzed tárolósszkóppal magad szerintem tegyél fel egy sorosport sniffert windowsra.

Windowson nem tudsz random baudot beállítani ahogyan Linuxon sem.
Van különbség a POSIX és a Windowsos standard baudok közt ld. http://code.google.com/p/qextserialport/source/browse/src/qextserialpor… BaudrateType enum, de nem hinném, hogy ha emulált windows alól Linux hoston megy akkor valami nagyon win specifikus baudot használna. Emlékeim szerint az eszközdescriptort kéri a Virtualbox, ebből arra következtettek, hogy azon keresztül tolja a forgalmat, és nem a saját kernelmodulján keresztül.

Értelek, ezt meg is tettem. Nem lehetett kiválasztani a device-t a snifferben. Ennek sejtem az okát.

Arról lehet szó, hogy a műszerrel kommunikáló őrogramnak van egy windows-os kernel modulja. Gyanúmat erősíti, hogy telepítés után reboot-ot kért. Azért a 3906.25 baud-hoz elég vad osztást kell beállítani a baudrate generátorban, ez a standard library konstansai között nyilván nincs meg. Szóval soros snifferrel nem megyek most semmire, ezt hardware-ből kell megoldjam. Monitorozom a drótot mikrokontrollerrel, majd egy másik RS232 porton küldöm befele a host oprendszernek a biteket.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Szia!
Ezt láttad?
link
A szerző azt írja, hogy a gyártó küldött neki adatlapokat, ebben az irányban is el lehetne indulni.
Üdv: Árpi

Akkor ezt igyekszem tisztába tenni, noha ebben a topic-ban minden infó megvan hozzá.

Van kétféle kábel. Illetve talán három féle, de két csoportra oszthatók.

Ami nekem van, az buta kábel, csak fizikai szintillestést végez. Ennek a kábelnek kell egy borzalmas, szabványtalan formátumban rángatni a végét, itt 3906.25 baud a sebesség. Ez a műszer valós sebessége, hülye formátummal.

Aztán van a bc85x kábel. Abban van mikrokontroller, amely a műszer felé tudja a szörnyű protokollt borzalmas baudrate-tel, a PC felé viszont szabványos, 9600 baud, 8n1 formátumot mutat. Ennek a protokollnak a leírása megvan, viszont semmire sem megyek vele, mert nekem közvetlenül kell a műszerrel kommunikálnom.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ránéztem a rövid speckójára, ezt tényleg jó kis cuccnak tűnik (bár én nem tudom hol is kellene nekem ilyen).
Mivel már 3 éve megvan, én azért belenéznék mi is van benne - ez is sok mindenre magyarázatot adhat (értsd miért ilyen fura a kommunikáció).
A protokoll letapogatására kitalált konfigurációd jó lehet, de az biztos hogy doksi nélkül soha nem lehetsz biztos semmiben :( Én mindenképpen megpróbálnék előbb kapcsolatba lépni velük, esetleg, ha megírod a programot nekik is hasznos lehet.

* Én egy indián vagyok. Minden indián hazudik.