Fórum Root.cz
Hlavní témata => Hardware => Téma založeno: JmJ 08. 02. 2011, 09:16:15
-
Zdravim,
mel jsem ted touhu komunikovat po RS485 pomoci apliakce v C napsane pro Linux. Jde o poloduplexni prenos, kde se smer komunikace prepina jednim signalem. Obycejne se pouzije prevodnik RS232/RS485 a hybe se se signalem RTS na RS232. Problem je v tom, ze toto vyzaduje extremne presne casovani. Vystavit RTS, odvysilat data a do 2 ms po _odejiti_ posledniho bytu shodit RTS.
Programove na urovni apliakce se nam toto nedarilo. Googlim jsem a nasel jsem, ze posledni jadra maji mit podporu pro RS485 na urovni ovladace. Existuje nova struktura v serial.h, ktera nastavuje parametry pro praci s RTS atd. Nahodil jsem do Debianu jadro 2.6.37, bohuzel pri pokusu o ioctl dojde k jeho selhani.
Nejsem tak sbehli ve vecech kolem jadra, nedokaza jsem se dopatrat jestli ta podbora v jadre tedy je, nebo jestli se musi jadro kompilovat atd. Jsem zmaten.
Zaroven pokud ma nekdo z vas fintu, jak RS485 ovladat rucne z aplikace, tak sem s ni :-)
-
My pouzivame fintu ze prevodnik zapina a vypina vysilac automaticky a zatim jsme nezaznamenali jediny problem.
-
My pouzivame fintu ze prevodnik zapina a vypina vysilac automaticky a zatim jsme nezaznamenali jediny problem.
my mame hw, ktery je soucasti mini zakladove desky a ten tuto moznost nema. musi se hybat s rts signalem. bohuzel.
-
Co tam mezi to strčit nějaké Arduino. Je to sice další práce s HW, ale vyřeší to problém s přesným časováním
-
Co tam mezi to strčit nějaké Arduion. Je to sice další práce s HW, ale vyřeší to problém s přesným časováním
cilem operace je zlevnit vyrobu, tedy odstranit pouziti dalsich hw prvku.
-
A nestačí prostě jen zapnout RTS/CTS handshakinkg? To by se podle popisu mělo chovat podobně (pokud převodník nebudí CTS, tak ho ještě proklemovat s RTS)...
-
2 msec su problem na linuxe? To je nejaka embedded doska alebo nadupany intel?
-
A nestačí prostě jen zapnout RTS/CTS handshakinkg? To by se podle popisu mělo chovat podobně (pokud převodník nebudí CTS, tak ho ještě proklemovat s RTS)...
prevodnik CTS nebudi, coz je prave problem, nebot neni mozne proklemovat RTS s CTS, protoze prvodnik je nekde v nejakem svabu na malickem mainboardu. Mozna by nekdo prisel na to, ktere nozicky ktereho svabu spojit, ovsem toto neni akceptovatelne reseni vzhledem k tomu, ze na cely system jsou kladeny vysoke naroky na stabilitu a take na znovupouzitelnost.
-
2 msec su problem na linuxe? To je nejaka embedded doska alebo nadupany intel?
mala ludra. hlavne je problem v tom, ze nevime jak zjistit, kdy skutecne odesel posledni byte, abychom mohli zmenit stav RTS. nekteri to resi treba tim, ze zpetne ctou co poslali, ovsem i tak reakce driveru na zmenu RTS je docela promenna. a staci malo a uz se ztraci odpoved od druhe strany.
-
Napsat si vlastni jaderny ovladac, vypnout na UARTu fifo a mit to plne podkontrolou, ale pocitat s tim, ze jedno cele CPU padne na aktivni cekani, proste nebude schopno planovat jine ulohy behem prenosu. Nevim, jake v tomhle ma moznosti Linux, ale v DOS by to nebyl problem.
-
Takže jestli tomu správně rozumím, používá se standardní sériový port na PC (RS-232C). Tím je PC připojené k externímu převodníku RS-232<->RS-485 u kterého se směr přepíná pomocí RTS.
To jsem v Linuxu ještě neimplementoval, ale Win API umí nastavit sériový port tak, že se RTS překlopí okamžitě po odvysílání kompletního posledního bytu zprávy. A tato možnost je ve v API od Win NT (na Win 98 to zlobilo - špatně napsaný driver, který Microsoft nikdy neopravil, takže ti co měli přístup k MS DDK si to opravovali sami...).
Předpokládám že Linux drivery to budou umět, takže doporučuji projít podrobně aktuální API. Pokud ne, vzít použitý driver a tuto funkci tam doplnit...
-
Ještě doplnění - letmým nahlédnutím do include/linux/serial.h vidím:
/*
* Serial interface for controlling RS485 settings on chips with suitable
* support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your
* platform. The set function returns the new state, with any unsupported bits
* reverted appropriately.
*/
struct serial_rs485 {
__u32 flags; /* RS485 feature flags */
#define SER_RS485_ENABLED (1 << 0)
#define SER_RS485_RTS_ON_SEND (1 << 1)
#define SER_RS485_RTS_AFTER_SEND (1 << 2)
#define SER_RS485_RTS_BEFORE_SEND (1 << 3)
__u32 delay_rts_before_send; /* Milliseconds */
__u32 delay_rts_after_send; /* Milliseconds */
__u32 padding[5]; /* Memory is cheap, new structs
are a royal PITA .. */
};
Třeba by to pomohlo...
-
A ještě něco s příklady je na http://www.armbedded.eu/node/322
-
Ano, jak jsem psal v prvni prispevku, o te strukture vim, stejne tak jako jsou tam definovany konstanty pro RS485. jenze kdyz pouziju IOCTL pro nastaveni RS485, tak je navratova hodnota -1. Nedari se.
A proto jsem se ptal na to, jestli nekdo vi, jak to s tou podporou v jadre je. To me hlavne zajima. Ano, i tu stranku s ukazkou znam.
To chovani u winodws, ktere nastavi/shodi RTS po odvysilani se myslim menuje RTS_TOGGLE ci tak nejak a to linux dle vseho nema.
Googlili kolem toho 2 pomerne rozumni lide, kazdy tak 5 hodin. Proto se ptam jiz na konkretni veci. Nechci si psat vlastni ovladac, chci pouzit neco, co je jiz hotovo. Pripadne zvladnout ovladani z vlastni aplikace.
-
Tak se podívej do zdrojáku od driveru, který pro sériový port používáš, jak a jestli je ten ioctl implementovaný...
Pokud není, budeš potřebovat buď jiný driver, jeho modifikaci a nebo HW který to už v driveru má...
-
2 msec su problem na linuxe? To je nejaka embedded doska alebo nadupany intel?
mala ludra. hlavne je problem v tom, ze nevime jak zjistit, kdy skutecne odesel posledni byte, abychom mohli zmenit stav RTS. nekteri to resi treba tim, ze zpetne ctou co poslali, ovsem i tak reakce driveru na zmenu RTS je docela promenna. a staci malo a uz se ztraci odpoved od druhe strany.
S tim ctenim odeslaneho jsme to kdysi taky pouzivali a celkem to fungovalo. Jedinej problem byl s tim ze se musel nastavit trigger prijimaciho bafru na 1 byte. Jinak posila seriovej brouk interupty az po nejakym timeoutu a to byl problem.
Jeste by slo zapinat a vypinat RTS rucne. Vypinalo by se presnym casovacem po dobe (pocet bytu * 10/BAUDRATE). I staricke 386 s jadrem 2.4 stacily plnit vysialci bafr a k prodlevam mezi vysilanymi byty nedochazelo. Jeste by to slo posychrovat prectenim posledniho prijateho resp vyslaneho bytu.
-
Trocha grepování ve zdrojácích 2.6.37:
- ioctl TIOC{S,G}RS485 je podporován pouze ovladačem atmel_serial (CONFIG_SERIAL_ATMEL) a crisv10.c (CONFIG_ETRAX_SERIAL)
- sériové ovladače implementují funkci tx_empty(), kterou sériový subsystém (serial_core.c) používá pro struct tty_operations.wait_until_sent (ta se volá např. přes ioctl TCSETSW2) -- takže ten TCSETSW2 je asi nejrychlejší obecný způsob
Jaký ovladač se používá pro tu komunikaci s RS485 převodníkem?