|
| Ustabil Com port Fra : Christian RD |
Dato : 21-05-02 19:31 |
|
Hej NG
Jeg har et problem med com porten. Har lavet et C++ program, der skriver til
com porten vha:
TransmitCommChar(hComm, sendString);
Men den skriver ret ustabilt, så den enhed jeg har koblet på opfatter nogle
gange tegnene forkert.
Jeg initialiserer oprten vha:
// OPEN THE COMM PORT.
hComm = CreateFile("com1",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
// IF THE PORT CANNOT BE OPENED, BAIL OUT.
if(hComm == INVALID_HANDLE_VALUE) {
Form1->PopupMenu7->Popup(400,300);
Application->Terminate();
}
// SET THE COMM TIMEOUTS.
GetCommTimeouts(hComm,&ctmoOld);
ctmoNew.ReadTotalTimeoutConstant = 100;
ctmoNew.ReadTotalTimeoutMultiplier = 0;
ctmoNew.WriteTotalTimeoutMultiplier = 0;
ctmoNew.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hComm, &ctmoNew);
// SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
// THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST.
// IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER
// THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING.
// ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING.
dcbCommPort.DCBlength = sizeof(DCB);
GetCommState(hComm, &dcbCommPort);
BuildCommDCB("57600,N,8,1", &dcbCommPort);
SetCommState(hComm, &dcbCommPort);
// ACTIVATE THE THREAD. THE FALSE ARGUMENT SIMPLY MEANS IT HITS THE
// GROUND RUNNING RATHER THAN SUSPENDED.
ReadThread = new TRead(false);
}
Jeg har ikke lige check på hvad alt koden gør, men er det måske fordi jeg
har nogle forkerte indstillinger?
På forhånd tak
Christian Dahm
| |
Niels Erik Danielsen (21-05-2002)
| Kommentar Fra : Niels Erik Danielsen |
Dato : 21-05-02 22:07 |
|
"Christian RD" <crda00@kom.auc.dk> wrote in message
news:ace41q$g6u$1@sunsite.dk...
> Hej NG
>
> Jeg har et problem med com porten. Har lavet et C++ program, der skriver
til
> com porten vha:
[Code deleted.]
> Men den skriver ret ustabilt, så den enhed jeg har koblet på opfatter
nogle
> gange tegnene forkert.
Hvad mener du med at den skriver ustabilt ? Hvordan dektere du det ?
Mangler der tegn, hvormange ? er der et mønster i det ?
Returnere WriteWile at den har skrevet alle tegn, du ønsker at sende ? (Det
burde den da timeout er uendelig)
Kan det tænkes at fejlen ligger i din 'enhed' ? Kan den følge med til at
modage data, eller har du UART overrun ?
Prøv evt. at sætte bitraten lidt ned for at se om det hjælper.
Denne enhed har du selv programeret den, eller er den et færdig produkt ?
Eller er data blevet ødelagt/forvansket undervejs ?
Hvis data er blevet ændret undervejs vil jeg gøtte på at der enten er ret
støj problem, eller der er et bit timings problem.
Er det noget hardware du selv har bygget ?
Er der noget system i forvanskningen ? f.eks. at et givet tegn næsten altid
bliver til et andet, eller at bit 0 bliver fortolket som et 0, eller det
foregående bit ?
Hvis du f.eks. har det problem at bit 0 tiltider bliver læst forkert, kan
det være et bit timings problem, hvor prescaleren og/eller dit x-tal er lidt
forkert.
Hvis fejlen kan forekomme på alle bit er det (og de fleste tegn læses ok) er
der ikke noget problem med sende/modtage klokken, men måske et: DC
arbejdspunkt/hysterese problem, eller et langt dårligt kabel.
Hvis du har en anden PC med to ledige porte kan du anvende de to Rx indgange
til en simpel RS232 analysator.
| |
Christian RD (22-05-2002)
| Kommentar Fra : Christian RD |
Dato : 22-05-02 09:32 |
|
"Niels Erik Danielsen" <ned@post6.tele.dk> wrote in message
news:3ceab620$0$18639$edfadb0f@dspool01.news.tele.dk...
>
> "Christian RD" <crda00@kom.auc.dk> wrote in message
> news:ace41q$g6u$1@sunsite.dk...
> > Hej NG
> >
> > Jeg har et problem med com porten. Har lavet et C++ program, der skriver
> til
> > com porten vha:
>
> [Code deleted.]
>
> > Men den skriver ret ustabilt, så den enhed jeg har koblet på opfatter
> nogle
> > gange tegnene forkert.
>
> Hvad mener du med at den skriver ustabilt ? Hvordan dektere du det ?
> Mangler der tegn, hvormange ? er der et mønster i det ?
> Returnere WriteWile at den har skrevet alle tegn, du ønsker at sende ?
(Det
> burde den da timeout er uendelig)
> Kan det tænkes at fejlen ligger i din 'enhed' ? Kan den følge med til at
> modage data, eller har du UART overrun ?
> Prøv evt. at sætte bitraten lidt ned for at se om det hjælper.
> Denne enhed har du selv programeret den, eller er den et færdig produkt ?
Ja, det er en erikson Bluetooth enhed. Jeg tror ikke det er den der er noget
galt med, da jeg har prøvet med 4-5 forskellige enheder. Jeg har prøvet at
koble de 2 comporte sammen, så jeg kan læse direkte hvad jeg skriver ud.
Nogle gange skriver den 4 tegn ud, venter lidt (½-2 sek ca.)og skriver nogle
flerer, hvor andre gange skriver den hele strengen ud på engang. Tror det er
noget med den måde jeg skriver til porten på.
>
>
> Eller er data blevet ødelagt/forvansket undervejs ?
> Hvis data er blevet ændret undervejs vil jeg gøtte på at der enten er ret
> støj problem, eller der er et bit timings problem.
> Er det noget hardware du selv har bygget ?
> Er der noget system i forvanskningen ? f.eks. at et givet tegn næsten
altid
> bliver til et andet, eller at bit 0 bliver fortolket som et 0, eller det
> foregående bit ?
> Hvis du f.eks. har det problem at bit 0 tiltider bliver læst forkert, kan
> det være et bit timings problem, hvor prescaleren og/eller dit x-tal er
lidt
> forkert.
> Hvis fejlen kan forekomme på alle bit er det (og de fleste tegn læses ok)
er
> der ikke noget problem med sende/modtage klokken, men måske et: DC
> arbejdspunkt/hysterese problem, eller et langt dårligt kabel.
>
>
> Hvis du har en anden PC med to ledige porte kan du anvende de to Rx
indgange
> til en simpel RS232 analysator.
>
>
>
>
>
>
>
>
| |
Thomas Lykkeberg (22-05-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 22-05-02 07:22 |
|
On Tue, 21 May 2002 20:31:03 +0200, "Christian RD" <crda00@kom.auc.dk>
wrote:
>Hej NG
>
>Jeg har et problem med com porten. Har lavet et C++ program, der skriver til
>com porten vha:
>
>TransmitCommChar(hComm, sendString);
>
>Men den skriver ret ustabilt, så den enhed jeg har koblet på opfatter nogle
>gange tegnene forkert.
Hvis du gøre noget der ligner følgende...
const char string[] = "Test af COM port";
int i;
for(i = 0;string[i] != '\x0';i++)
{
TransmitCommChar(hComm,string[i]);
}
ja, så kontrollerer du ikke om TransmitCommChar() rent faktisk får
sendt din karakter, men de bliver bare "blæst" ned mod driveren og den
vil helt sikkert smide nogen af dem væk, hvis det gpr for hurtigt og
returnerer FALSE. Brug WriteFile() til at sende "klumper" af data med,
og opret så en event object som venter på at TX bufferen bliver tømt,
så du kan sende en ny "klump" data. Jeg har burgt den metode før, uden
problemer. Her brugte jeg (som det ser ud som om du også gør) 2
Threads, en til Read og en til Write.
/Thomas
| |
Rasmus Kaae (22-05-2002)
| Kommentar Fra : Rasmus Kaae |
Dato : 22-05-02 19:16 |
|
>
> Hvis du gøre noget der ligner følgende...
>
> const char string[] = "Test af COM port";
> int i;
>
> for(i = 0;string[i] != '\x0';i++)
> {
> TransmitCommChar(hComm,string[i]);
> }
>
> ja, så kontrollerer du ikke om TransmitCommChar() rent faktisk får
> sendt din karakter, men de bliver bare "blæst" ned mod driveren og den
> vil helt sikkert smide nogen af dem væk, hvis det gpr for hurtigt og
> returnerer FALSE. Brug WriteFile() til at sende "klumper" af data med,
> og opret så en event object som venter på at TX bufferen bliver tømt,
> så du kan sende en ny "klump" data. Jeg har burgt den metode før, uden
> problemer. Her brugte jeg (som det ser ud som om du også gør) 2
> Threads, en til Read og en til Write.
Moderne pc'er (stortset alt efter 486) har en fifo-buffer på uart'en så den
burde ligger i bufferen, desuden har driveren nok også en mindre buffer.
| |
Thomas Lykkeberg (22-05-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 22-05-02 19:49 |
|
On Wed, 22 May 2002 20:15:38 +0200, "Rasmus Kaae"
<macaw@WHATEVERMAKESYOUHAPPYhotmail.com> wrote:
>Moderne pc'er (stortset alt efter 486) har en fifo-buffer på uart'en så den
>burde ligger i bufferen, desuden har driveren nok også en mindre buffer.
Det er rigtigt, 16550'eren (UART'en i PC'ere i dag) har en 16 byte
FIFO både i TX og RX, driverens buffere skal man selv sætte op med et
Win32 API kald, hvis man ikke vil nøjes med de buffer størrelser som
er sat op som default i driveren.
Men problemet er hvis man sender karaktere til COM porten ved hjælp af
TransmitCommChar() API'en, vil den placerer karateren foran alle andre
"ventende" karakterer i bufferen, modsat af WriteFile(), og yderligere
kald til denne funktion er ikke "tilladt" før end denne karakter rent
faktisk er sendt. Disse kan ikke sendes lige så hurtigt som man
"putter" nye karakterer ned i bufferen. Dette vil forårsage et buffer
overrun, som resultere i at funktionen TransmitCommChar() returnerer
FALSE. Hvis man så ikke reagerer på dette, men blot fortsætter
ufortrødent med at sende karakterer, ja så vil man jo mangle data i
den "anden ende".
/Thomas
| |
Bjarne Laursen (22-05-2002)
| Kommentar Fra : Bjarne Laursen |
Dato : 22-05-02 21:24 |
|
Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> wrote:
>Jeg har burgt den metode før, uden
>problemer. Her brugte jeg (som det ser ud som om du også gør) 2
>Threads, en til Read og en til Write.
Det går fint i win98 men på winNT er det ikke tilladt. Man skal bruge
samme tread. (ingen fejlmelding).
-Bjarne
| |
Mogens Hansen (23-05-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 23-05-02 05:53 |
|
"Bjarne Laursen" <bl@pyramidedata.dk> wrote
> Det går fint i win98 men på winNT er det ikke tilladt. Man skal bruge
> samme tread. (ingen fejlmelding).
Ved du hvorfor ?
Har du et link til en forklaring ?
Venlig hilsen
Mogens Hansen
| |
Bjarne Laursen (23-05-2002)
| Kommentar Fra : Bjarne Laursen |
Dato : 23-05-02 10:01 |
|
"Mogens Hansen" <mogens_h@dk-online.dk> wrote:
>> Det går fint i win98 men på winNT er det ikke tilladt. Man skal bruge
>> samme tread. (ingen fejlmelding).
>
>Ved du hvorfor ?
Hmm, jeg har været ved at søge lidt jeg. Jeg mener forklaringen er
her:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwbgen/html/msdn_serial.asp
Fra oventående link:
"Nonoverlapped I/O is very straightforward, though it has limitations.
An operation takes place while the calling thread is blocked. Once the
operation is complete, the function returns and the thread can
continue its work. This type of I/O is useful for multithreaded
applications because while one thread is blocked on an I/O operation,
other threads can still perform work. It is the responsibility of the
application to serialize access to the port correctly. If one thread
is blocked waiting for its I/O operation to complete, all other
threads that subsequently call a communications API will be blocked
until the original operation completes. For instance, if one thread
were waiting for a ReadFile function to return, any other thread that
issued a WriteFile function would be blocked."
Man kan altså ikke have en tråd til at vente på input, samtidig med at
en anden tråd sender. Men under win98 kan man altså, det har jeg
prøvet.
-Bjarne
| |
Thomas Lykkeberg (23-05-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 23-05-02 17:39 |
|
On Thu, 23 May 2002 11:01:28 +0200, Bjarne Laursen
<bl@pyramidedata.dk> wrote:
>"Nonoverlapped I/O is very straightforward, though it has limitations.
>An operation takes place while the calling thread is blocked. Once the
>operation is complete, the function returns and the thread can
>continue its work. This type of I/O is useful for multithreaded
>applications because while one thread is blocked on an I/O operation,
>other threads can still perform work. It is the responsibility of the
>application to serialize access to the port correctly. If one thread
>is blocked waiting for its I/O operation to complete, all other
>threads that subsequently call a communications API will be blocked
>until the original operation completes. For instance, if one thread
>were waiting for a ReadFile function to return, any other thread that
>issued a WriteFile function would be blocked."
>
>Man kan altså ikke have en tråd til at vente på input, samtidig med at
>en anden tråd sender. Men under win98 kan man altså, det har jeg
>prøvet.
Jeg tror du mistolker denne API beskrivelse. Det der blot står er at
hvis man i tråd A sætter sig til at vente på at en I/O operation (read
eller write) ja, så kan man ikke udføre andre I/O operationer i eks.
vis tråd B, C osv., før denne (originale) I/O operation i tråd A er
færdig. Det betyder ikke at man ikke kan have flere tråde som udfører
I/O operationer på den samme COM port.
Dette gælder jo kun for Non-Overlapped I/O. Det er også derfor
Microsoft har implementeret Overlapped I/O til netop at udføre
"parallele" I/O operationer.
Så alt i alt vil jeg mene at du tager fejl, når su siger at man ikke
kan have 2 tråde til at udføre henholdsvis I/O read og write i
Windows, uanset version (9x/NT/2K/Me).
/Thomas
| |
Bjarne Laursen (23-05-2002)
| Kommentar Fra : Bjarne Laursen |
Dato : 23-05-02 22:57 |
|
Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> wrote:
>Jeg tror du mistolker denne API beskrivelse. Det der blot står er at
>hvis man i tråd A sætter sig til at vente på at en I/O operation (read
>eller write) ja, så kan man ikke udføre andre I/O operationer i eks.
>vis tråd B, C osv., før denne (originale) I/O operation i tråd A er
>færdig. Det betyder ikke at man ikke kan have flere tråde som udfører
>I/O operationer på den samme COM port.
Ok, men når man laver to tråde så er det vel netop meningen at tråd-A
skal kunne stå og vente på input samtidig med at tråd-B sender.
Jeg lavede i hvert fald engang sådan et program til en kunde, og
testede det til fuld tilfredshed på min win98. Da kunden så fik det
virkede det ikke. Fordi han brugte winNT.
-Bjarne
| |
Thomas Lykkeberg (24-05-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 24-05-02 07:15 |
|
On Thu, 23 May 2002 23:57:08 +0200, Bjarne Laursen
<bl@pyramidedata.dk> wrote:
>Jeg lavede i hvert fald engang sådan et program til en kunde, og
>testede det til fuld tilfredshed på min win98. Da kunden så fik det
>virkede det ikke. Fordi han brugte winNT.
Netop, her skulle være brugt Overlapped I/O. Den UART som sidder i
PC'ere (16550 lign.) er 100% full-duplex, så det skulle altså være
muligt..
Jeg benytter selv Windows 2000 / Win9x til min udvikling, og her skal
man tage de samme hensyn som man skal mellem Win9x og WinNT.
Her er et lille uddrag fra API beskrivelsen til CreateFile().
--SNIP--
FILE_FLAG_OVERLAPPED:
Instructs the system to initialize the object, so that operations that
take a significant amount of time to process return ERROR_IO_PENDING.
When the operation is finished, the specified event is set to the
signaled state.
When you specify FILE_FLAG_OVERLAPPED, the file read and write
functions must specify an OVERLAPPED structure. That is, when
FILE_FLAG_OVERLAPPED is specified, an application must perform
overlapped reading and writing.
When FILE_FLAG_OVERLAPPED is specified, the system does not maintain
the file pointer. The file position must be passed as part of the
lpOverlapped parameter (pointing to an OVERLAPPED structure) to the
file read and write functions.
This flag also enables more than one operation to be performed
simultaneously with the handle (a simultaneous read and write
operation, for example).
--SNIP--
Du må have anvendt et eller andet i din kode som gjorde at den ikke
kunne køre under WinNT. Det er nu også rimelig sandsynligt idet WinNT
skal håndteres en del anderledes end Win9x. Har selv begået denne fejl
adskillige gange. Her skal man læse grundigt i Win32 API
beskrivelserne. o)
/Thomas
| |
Bjarne Laursen (24-05-2002)
| Kommentar Fra : Bjarne Laursen |
Dato : 24-05-02 08:55 |
|
Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> wrote:
>Du må have anvendt et eller andet i din kode som gjorde at den ikke
>kunne køre under WinNT.
Ja, jeg brugte nonoverlapped I/O. Lige som den oprindelige spørger.
Det er jo også langt det letteste.
-Bjarne
| |
snusken (02-06-2002)
| Kommentar Fra : snusken |
Dato : 02-06-02 10:52 |
|
til win 2000 og winXP skal man benytte, som Bjarne skriver WriteFile i
stedet for TransmitCommChar+Sleep. Jeg har fundet en komponent til C++
Builder, (v.5 og 6) som løser problemet.
- Erik
Bjarne Laursen <bl@pyramidedata.dk> skrev i en
nyhedsmeddelelse:36sreusbapha1j60uqedj8oej9j37slvau@4ax.com...
> Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> wrote:
>
> >Du må have anvendt et eller andet i din kode som gjorde at den ikke
> >kunne køre under WinNT.
> Ja, jeg brugte nonoverlapped I/O. Lige som den oprindelige spørger.
> Det er jo også langt det letteste.
> -Bjarne
| |
Morten Dall (03-06-2002)
| Kommentar Fra : Morten Dall |
Dato : 03-06-02 22:13 |
|
hvad heder den komponent ? hvor kan man downloade den ? eller kan du maile
den , eller ligge den i en bin gruppe ?
mvh Morten
"snusken" <snusken@mail.com> skrev i en meddelelse
news:3cf9eab7$0$8947$edfadb0f@dspool01.news.tele.dk...
> til win 2000 og winXP skal man benytte, som Bjarne skriver WriteFile i
> stedet for TransmitCommChar+Sleep. Jeg har fundet en komponent til C++
> Builder, (v.5 og 6) som løser problemet.
> - Erik
> Bjarne Laursen <bl@pyramidedata.dk> skrev i en
> nyhedsmeddelelse:36sreusbapha1j60uqedj8oej9j37slvau@4ax.com...
> > Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> wrote:
> >
> > >Du må have anvendt et eller andet i din kode som gjorde at den ikke
> > >kunne køre under WinNT.
> > Ja, jeg brugte nonoverlapped I/O. Lige som den oprindelige spørger.
> > Det er jo også langt det letteste.
> > -Bjarne
>
>
>
>
| |
|
|