🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: be.comp.programming
7 messages
7 total messages Started by Philip Paeps Mon, 15 May 2006 07:41
Vertraagde read() op serial port
#733
Author: Philip Paeps
Date: Mon, 15 May 2006 07:41
30 lines
1993 bytes
Voor de verandering heb ik eens een probleem. :-)

Ik moet communiceren met een serial device dat een beetje onnozel is: het
spreekt geen software flow control en mijn hardware beschikt niet over de
nodige draadjes voor hardware flow control (en dat kan ik niet makkelijk
veranderen).

Nu moet ik daar wel een "asynchroon" protocol over spreken.  Met andere
woorden, ik write() nu iets en het device stuurt data terug, maar ik wil die
pas binnen een paar seconden/minuten read()en.  Zonder flow control kan ik me
niet meteen een manier verzinnen om dat te implementeren.

Een mogelijkheid zou zijn om voor mijn write() een thread af te vuren die
select() en read() in een buffer en mijn higher level "read" die buffer te
laten lezen.  Dat is echter een tamelijk dure oplossing.

Kent er iemand een manier om dit met de normale POSIX serial interface te
regelen?

Platform is Linux 2.4 op ARM, als dat wat uitmaakt.

 - Philip

-- 
Philip Paeps                              Please don't email any replies
philip@paeps.cx                               I follow the newsgroup.

  "How's he in the mysterious senses department?"
  	-- Gaspode the wonder dog
  	   (Terry Pratchett, Moving Pictures)
Re: Vertraagde read() op serial port
#734
Author: Bart Friederichs
Date: Mon, 15 May 2006 09:22
12 lines
1496 bytes
Philip Paeps wrote:

> Een mogelijkheid zou zijn om voor mijn write() een thread af te vuren die
> select() en read() in een buffer en mijn higher level "read" die buffer te
> laten lezen.  Dat is echter een tamelijk dure oplossing.

Waarom niet gewoon die data meteen lezen en in een buffer zetten, zonder
thread? Als je de data nodig hebt, lees je m uit het buffer.

Of zie ik het nu veel te simpel?

Bart
Re: Vertraagde read() op serial port
#735
Author: Philip Paeps
Date: Mon, 15 May 2006 09:45
26 lines
2114 bytes
Bart Friederichs <bf@tbwb.nl> wrote:
> Philip Paeps wrote:
> > Een mogelijkheid zou zijn om voor mijn write() een thread af te vuren die
> > select() en read() in een buffer en mijn higher level "read" die buffer te
> > laten lezen.  Dat is echter een tamelijk dure oplossing.
>
> Waarom niet gewoon die data meteen lezen en in een buffer zetten, zonder
> thread? Als je de data nodig hebt, lees je m uit het buffer.
>
> Of zie ik het nu veel te simpel?

Je ziet het een beetje te simpel. ;-)  Mijn write() moet onmiddellijk returnen
terwijl het device waar ik mee praat mogelijk pas binnen een paar seconden
antwoord geeft (en de read() komt mogelijk een paar minuten later pas).

Momenteel even aan't onderzoeken hoe duur de thread-oplossing precies is, en
valt precies nog wel mee.  Maar ik vind het nogal ugly. *grin*

 - Philip

-- 
Philip Paeps                              Please don't email any replies
philip@paeps.cx                               I follow the newsgroup.

  BOFH Excuse #272:
    Netscape has crashed
Re: Vertraagde read() op serial port
#736
Author: Leon Zandman
Date: Mon, 15 May 2006 17:14
54 lines
3776 bytes
> Ik moet communiceren met een serial device dat een beetje onnozel is: het
> spreekt geen software flow control en mijn hardware beschikt niet over de
> nodige draadjes voor hardware flow control (en dat kan ik niet makkelijk
> veranderen).

Ik heb nu een paar jaar ervaring met het aansturen van apparatuur via 
een seriele aansluitingen (RS232) en heb eigenlijk nog nooit een 
apparaat gehad dat flow control gebruikte!

> Nu moet ik daar wel een "asynchroon" protocol over spreken.  Met andere
> woorden, ik write() nu iets en het device stuurt data terug, maar ik wil die
> pas binnen een paar seconden/minuten read()en.  Zonder flow control kan ik me
> niet meteen een manier verzinnen om dat te implementeren.

Zolang je niets read() op die seriel poort blijft de data meestal wel 
staan, dus je kunt in theorie gewoon na een paar minuten alsnog het 
antwoord opvragen. Maar er zijn natuurlijk betere oplossingen.

> Een mogelijkheid zou zijn om voor mijn write() een thread af te vuren die
> select() en read() in een buffer en mijn higher level "read" die buffer te
> laten lezen.  Dat is echter een tamelijk dure oplossing.

Zo doe ik het meestal wel. Alleen maak ik niet per request een nieuwe 
thread aan, maar heb ik een algemene receive-thread beschikbaar. Soms 
laat ik deze continu de seriel poort in de gaten houden en soms activeer 
ik 'm pas nadat ik iets verzonden heb. Deze receive-thread stopt dan de 
ontvangen data in een buffer. Eventueel kun je de receive thread nog wat 
extra logica meegeven, zodat 'ie kan bekijken of de data inderdaad is 
wat je verwacht had. Want als dat niet zo is, dan kun je het direct 
weggooien/negeren.

Vervolgens hangt het van het communicatieprotocol af wat je met die data 
in de buffer doet. Je kunt de buffer gewoon in z'n geheel beschikbaar 
stellen aan je main-thread. Als je de zaken goed synchroniseert 
(kritieke sectie/mutex o.i.d.) dan moet dat geen probleem zijn. Je kunt 
ook de receive-thread laten kijken of de data in de buffer aan bepaalde 
voorwaarden voldoet, zoals bijv. kijken of er een terminator-character 
aanwezig is. Indien dit het geval is, dan kun je het relevante stuk uit 
de buffer middels een event/message aan je main thread presenteren.

Groeten,

Leon Zandman



> 
> Kent er iemand een manier om dit met de normale POSIX serial interface te
> regelen?
> 
> Platform is Linux 2.4 op ARM, als dat wat uitmaakt.
> 
>  - Philip
> 
Re: Vertraagde read() op serial port
#742
Author: Philip Paeps
Date: Mon, 15 May 2006 19:51
70 lines
4594 bytes
Leon Zandman <usenet@wirwar.com> wrote:
> Philip Paeps <philip+usenet@paeps.cx> wrote:
> > Ik moet communiceren met een serial device dat een beetje onnozel is: het
> > spreekt geen software flow control en mijn hardware beschikt niet over de
> > nodige draadjes voor hardware flow control (en dat kan ik niet makkelijk
> > veranderen).
>
> Ik heb nu een paar jaar ervaring met het aansturen van apparatuur via een
> seriele aansluitingen (RS232) en heb eigenlijk nog nooit een apparaat gehad
> dat flow control gebruikte!

Ik heb altijd wel xon/xoff kunnen gebruiken.  Het is wel lang geleden dat ik
nog iets met normale hardware flow control ben tegengekomen.

> > Nu moet ik daar wel een "asynchroon" protocol over spreken.  Met andere
> > woorden, ik write() nu iets en het device stuurt data terug, maar ik wil
> > die pas binnen een paar seconden/minuten read()en.  Zonder flow control
> > kan ik me niet meteen een manier verzinnen om dat te implementeren.
>
> Zolang je niets read() op die seriel poort blijft de data meestal wel staan,
> dus je kunt in theorie gewoon na een paar minuten alsnog het antwoord
> opvragen. Maar er zijn natuurlijk betere oplossingen.

Dat dacht ik ook.  Jammer genoeg blijkt dat op mijn platform niet het geval te
zijn.  Even getest met een quick&dirty test applicatie.  Nu zijn op de CPU die
ik gebruik de UARTs wel duidelijk als een "afterthought" aangehackt dus dit
verbaast me in het geheel niet.  Bij gelegenheid nog eens in de device driver
duiken om te zien of er nog wat schort, maar ik ben die code al lang moe. ;-)

> > Een mogelijkheid zou zijn om voor mijn write() een thread af te vuren die
> > select() en read() in een buffer en mijn higher level "read" die buffer te
> > laten lezen.  Dat is echter een tamelijk dure oplossing.
>
> Zo doe ik het meestal wel. Alleen maak ik niet per request een nieuwe thread
> aan, maar heb ik een algemene receive-thread beschikbaar.

Zo heb ik dit nu ge�mplementeerd.  Dit spaart me ook een paar context switchen
voor open()/close() per request.  Het maakt het buffer-management een beetje
lastiger, maar al bij al valt het tamelijk goed mee.  Ik heb nog "ergens" een
kleine 9ms latency zitten.  Die krijg ik morgen wel klein.

> Soms laat ik deze continu de seriel poort in de gaten houden en soms
> activeer ik 'm pas nadat ik iets verzonden heb.

Mmm, dat activeren en deactiveren lijkt me een goed idee.  Doe je dit met een
wait condition of met een soort pipe?

> [...]
> Als je de zaken goed synchroniseert (kritieke sectie/mutex o.i.d.) dan moet
> dat geen probleem zijn. Je kunt ook de receive-thread laten kijken of de
> data in de buffer aan bepaalde voorwaarden voldoet, zoals bijv. kijken of er
> een terminator-character aanwezig is. Indien dit het geval is, dan kun je
> het relevante stuk uit de buffer middels een event/message aan je main
> thread presenteren.

Synchronizatie zit redelijk goed in elkaar.  Het protocol is echter by design
tamelijk 'liberaal' op vlak van data -- eigenlijk is het helemaal mijn zaak
niet hoe de data er uit ziet.  Ik moet ze unmangled uit de poort sleuren en
unmangled mijn applicatie doorduwen.

Thanks voor de tips!

 - Philip

-- 
Philip Paeps                              Please don't email any replies
philip@paeps.cx                               I follow the newsgroup.

  The most important item in an order will no longer
  be available.
Re: Vertraagde read() op serial port
#743
Author: Leon Zandman
Date: Mon, 15 May 2006 22:21
22 lines
2385 bytes
> Mmm, dat activeren en deactiveren lijkt me een goed idee.  Doe je dit met een
> wait condition of met een soort pipe?

Ik ontwikkel voornamelijk op Win32-platforms en dan gebruik ik meestal 
zogenaamde events. Dit zijn synchronisatie-objecten die je in een 
signaled of unsignaled state kunt zetten. Vervolgens kun je ze gebruiken 
in wait-functies, zoals bijv. 
WaitForSingleObject()/WaitForMultipleObjects(). Zie:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/event_objects.asp

Ik verstuur dan bijv. iets via de seriele poort en vervolgens signal ik 
het event. Mijn receive-thread loop zit dan te wachten tot dit event 
gesignaled wordt en als dat zo is komt 'ie in actie, doet z'n werk en 
zet het event weer als unsignaled en gaat weer wachten. Vrij standaard 
allemaal. In mijn ervaring heeft Linux, althans de POSIX API, niet zulke 
geavanceerde mogelijkheden. Maar er zal vast wel een soortgelijke 
oplossing te vinden zijn.

Groeten,

Leon Zandman
Re: Vertraagde read() op serial port
#745
Author: Nico Coesel
Date: Tue, 16 May 2006 18:41
29 lines
2492 bytes
Leon Zandman <usenet@wirwar.com> wrote:

>> Mmm, dat activeren en deactiveren lijkt me een goed idee.  Doe je dit met een
>> wait condition of met een soort pipe?
>
>Ik ontwikkel voornamelijk op Win32-platforms en dan gebruik ik meestal 
>zogenaamde events. Dit zijn synchronisatie-objecten die je in een 
>signaled of unsignaled state kunt zetten. Vervolgens kun je ze gebruiken 
>in wait-functies, zoals bijv. 
>WaitForSingleObject()/WaitForMultipleObjects(). Zie:
>
>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/event_objects.asp
>
>Ik verstuur dan bijv. iets via de seriele poort en vervolgens signal ik 
>het event. Mijn receive-thread loop zit dan te wachten tot dit event 
>gesignaled wordt en als dat zo is komt 'ie in actie, doet z'n werk en 
>zet het event weer als unsignaled en gaat weer wachten. Vrij standaard 
>allemaal. In mijn ervaring heeft Linux, althans de POSIX API, niet zulke 
>geavanceerde mogelijkheden. Maar er zal vast wel een soortgelijke 
>oplossing te vinden zijn.

Onder Posix Unix kun je een seriele poort een 'signal' laten genereren
zodra er data is. Je kunt dan met de signal handler (een soort
software interrupt) de data uitlezen. Met een semafoor kun je de
binnenkomende data dan weer synchroniseren met de applikatie.

-- 
Reply to nico@nctdevpuntnl (punt=.)
Bedrijven en winkels vindt U op www.adresboekje.nl
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads