Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-11

One experience with the unit serial

17 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Holger Bruns

Hi,

one more question regarding the unit serial. I use the following function to get one single byte form a serial port, which has been open before with seropen:

function getdata(inhandle: tserialhandle; var recdata: char): longint;
begin
 fillchar(inbuffer, sizeof(inbuffer), #0);
 getdata := serread(inhandle, inbuffer[0], 1);
 recdata := inbuffer[0]
end;

I repeat this function as long as I need to read data from a serial port, byte by byte. One interesting error occurs at the 52478th byte: serread returns 0 instead of 1. How can I get it work properly?

Best regards, Holger

Reply by email

Brad Campbell
to Holger Bruns
Holger Bruns wrote 16 lines
Hi, one more question regarding the unit serial. I use the following function to get one single byte form a serial port, which has been open before with seropen: function getdata(inhandle: tserialhandle; var recdata: char): longint; begin fillchar(inbuffer, sizeof(inbuffer), #0); getdata := serread(inhandle, inbuffer[0], 1); recdata := inbuffer[0] end; I repeat this function as long as I need to read data from a serial port, byte by byte. One interesting error occurs at the 52478th byte: serread returns 0 instead of 1. How can I get it work properly?

The answer to that probably depends on a bit more information that you have provided in your question.

Is your port open blocking or non-blocking?

Are you checking the handle for readability using Select() prior to trying to read a byte from it?

Have you traced the program using strace to see what the syscall is actually returning from the kernel?

Are you sure you have data waiting for you?

Brad

Dolphins are so intelligent that within a few weeks they can train Americans to stand at the edge of the pool and throw them fish.

Reply by email

Holger Bruns
to Brad Campbell
Show quoted text 20 lines
Holger Bruns wrote: > Hi, > > one more question regarding the unit serial. I use the following > function to get one single byte form a serial port, which has been > open before with seropen: > > function getdata(inhandle: tserialhandle; var recdata: char): longint; > begin > fillchar(inbuffer, sizeof(inbuffer), #0); > getdata := serread(inhandle, inbuffer[0], 1); > recdata := inbuffer[0] > end; > > I repeat this function as long as I need to read data from a serial > port, byte by byte. One interesting error occurs at the 52478th byte: > serread returns 0 instead of 1. How can I get it work properly? The answer to that probably depends on a bit more information that you have provided in your question.

Thank you for your answer. I played with different baud rates. The sender delivers a stream of bytes. The faster a transmission rate is, the less amount of data can be received. This leds me to two conclusions: At first, there must be a queue for incoming data despite I ruled out a queue with an inbuffer with the length 1. Secondly, a timeout error appeared, the sender gave up. For now, I try to solve this problem with slower baud rates. Since iopl is still not available to fpc in its 64-bit-version, I should move to c for future port programming.

For that matter it could be interesting to know two more things: How can I call external executable code like "setserial /dev/ttySx none" and secondly, how can I use c functions like pascal functions?

Are you sure you have data waiting for you?

Yes.

Holger

Reply by email

Jonas Maebe
to Holger Bruns
Holger Bruns wrote
Since iopl is still not available to fpc in its 64-bit-version, I should move to c for future port programming.

$ man iopl
...
This call is mostly for the i386 architecture. On many other architec-
tures it does not exist or will always return an error.

Switching to C will not cause this function to magically appear in the Linux kernel on non-i386 systems.

Jonas

Reply by email

Gustavo Enrique Jimenez
to Holger Bruns: Thank you for your answer. I played with different baud rates. The sender delivers a…
Show quoted text 9 lines
Thank you for your answer. I played with different baud rates. The sender delivers a stream of bytes. The faster a transmission rate is, the less amount of data can be received. This leds me to two conclusions: At first, there must be a queue for incoming data despite I ruled out a queue with an inbuffer with the length 1. Secondly, a timeout error appeared, the sender gave up. For now, I try to solve this problem with slower baud rates. Since iopl is still not available to fpc in its 64-bit-version, I should move to c for future port programming.

Despite queues an baud rates, you must expect data loss. You will loss data in the physical layer. You have to implement some handshake to prevent it. (using google translator, excuse my english).

Gustavo

Show quoted text 16 lines
For that matter it could be interesting to know two more things: How can I call external executable code like "setserial /dev/ttySx none" and secondly, how can I use c functions like pascal functions? > > Are you sure you have data waiting for you? Yes. Holger _______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Holger Bruns
to Gustavo Enrique Jimenez
Show quoted text 18 lines
> Thank you for your answer. I played with different baud rates. The sender > delivers a stream of bytes. The faster a transmission rate is, the less > amount of data can be received. This leds me to two conclusions: At first, > there must be a queue for incoming data despite I ruled out a queue with an > inbuffer with the length 1. Secondly, a timeout error appeared, the sender > gave up. For now, I try to solve this problem with slower baud rates. Since > iopl is still not available to fpc in its 64-bit-version, I should move to c > for future port programming. > Despite queues an baud rates, you must expect data loss. You will loss data in the physical layer. You have to implement some handshake to prevent it. (using google translator, excuse my english). Gustavo

Which can be done through a direct port access and some lines of code in assembler language. The second idea I have is the use of the device files /dev/ttySx, but how can these files be used to get access to all of the registers of an uart?

Holger

Reply by email

Marco van de Voort
to Holger Bruns

In our previous episode, Holger Bruns said:

Show quoted text 6 lines
> Which can be done through a direct port access and some lines of code in assembler language. The second idea I have is the use of the device files /dev/ttySx, but how can these files be used to get access to all of the registers of an uart?

As said, ttySx is a generalization of a general serial device, not of a certain chip.

Usually parameters are set by performing IOCTLs on the handle.

http://tldp.org/HOWTO/Serial-HOWTO.html

http://www.vanemery.com/Linux/Serial/serial-console.html

and heaps more if you put "linux serial" in google.

Reply by email

Gustavo Enrique Jimenez
to Holger Bruns: Which can be done through a direct port access and some lines of code in assembler…

2009/11/19 Holger Bruns :

Show quoted text 32 lines
Gustavo Enrique Jimenez schrieb: >> >> Thank you for your answer. I played with different baud rates. The sender >> delivers a stream of bytes. The faster a transmission rate is, the less >> amount of data can be received. This leds me to two conclusions: At >> first, >> there must be a queue for incoming data despite I ruled out a queue with >> an >> inbuffer with the length 1. Secondly, a timeout error appeared, the >> sender >> gave up. For now, I try to solve this problem with slower baud rates. >> Since >> iopl is still not available to fpc in its 64-bit-version, I should move >> to c >> for future port programming. >> > > Despite queues an baud rates, you must expect data loss.  You will > loss data in the physical layer. You have to implement some handshake > to prevent it. (using google translator, excuse my english). > > > Gustavo > > Which can be done through a direct port access and some lines of code in assembler language. The second idea I have is the use of the device files /dev/ttySx, but how can these files be used to get access to all of the registers of an uart? Holger

Did you try Synaser? http://www.ararat.cz/synapse/doku.php/download . I use it on all my projects since 2006 without problems (linux, windows, etc...).

Gustavo

Reply by email

Marco van de Voort
to Gustavo Enrique Jimenez

In our previous episode, Gustavo Enrique Jimenez said:

Did you try Synaser? http://www.ararat.cz/synapse/doku.php/download . I use it on all my projects since 2006 without problems (linux, windows, etc...).

How do you use it? I'm used to TComport, and it seems that synaser, like unit serial, only supports blocking use.

Do you put it in a thread?

I need it for a link that receives and sends at random, not related moments.

Reply by email

Gustavo Enrique Jimenez
to Marco van de Voort

2009/11/19 Marco van de Voort :

Show quoted text 11 lines
In our previous episode, Gustavo Enrique Jimenez said: > Did you try Synaser? http://www.ararat.cz/synapse/doku.php/download . > I use it on all my projects since 2006 without problems (linux, > windows, etc...). How do you use it? I'm used to TComport, and it seems that synaser, like unit serial, only supports blocking use. Do you put it in a thread? I need it for a link that receives and sends at random, not related moments.

Well, never used it in a thread. Only with handshake or free-running streams. I understand now why synaser could be useless in some situations.

Gustavo

Reply by email

Henry Vermaak
to Holger Bruns: Which can be done through a direct port access and some lines of code in assembler…

2009/11/19 Holger Bruns :

Show quoted text 15 lines
Gustavo Enrique Jimenez schrieb: > > Despite queues an baud rates, you must expect data loss.  You will > loss data in the physical layer. You have to implement some handshake > to prevent it. (using google translator, excuse my english). > > > Gustavo > > Which can be done through a direct port access and some lines of code in assembler language. The second idea I have is the use of the device files /dev/ttySx, but how can these files be used to get access to all of the registers of an uart?

No, you don't need direct port access, you can use tcsetattr(). See man pages for termios and tty_ioctl (if you need to set the modem lines explicitly).

Henry

Reply by email

Paul Breneman
to Marco van de Voort: In our previous episode, Gustavo Enrique Jimenez said: How do you use it? I'm used to…
Marco van de Voort wrote 11 lines
In our previous episode, Gustavo Enrique Jimenez said: > Did you try Synaser? http://www.ararat.cz/synapse/doku.php/download . > I use it on all my projects since 2006 without problems (linux, > windows, etc...). How do you use it? I'm used to TComport, and it seems that synaser, like unit serial, only supports blocking use. Do you put it in a thread? I need it for a link that receives and sends at random, not related moments.

I've got some simple non-threaded SynaSer code in a simple FreePascal distribution here:
http://www.turbocontrol.com/simpleserial.htm

I've also used SynaSer in threads on Windows and Linux and it works there too.

Paul

www.dbReplication.com
www.TurboControl.com

Reply by email

Vinzent Höfler
to Holger Bruns: Which can be done through a direct port access and some lines of code in assembler…

Holger Bruns :

Show quoted text 6 lines
> Despite queues an baud rates, you must expect data loss. You will > loss data in the physical layer. You have to implement some handshake > to prevent it. (using google translator, excuse my english). Which can be done through a direct port access and some lines of code in assembler language.

And by configuring the device correctly (which really can get nasty sometimes). You may take a look at Synapse' source code to get an idea.

The second idea I have is the use of the device files /dev/ttySx, but how can these files be used to get access to all of the registers of an uart?

By writing a device driver. That's what works behind /dev/ttySx. Someone already did it for you, you just have to use it correctly. Believe me, I know what I'm talking about, I've been on both sides of the fence. I also successfully used serial ports ("/dev/ttyMx" for that matter, Moxa C168H multi-port devices) in a multi-threaded application written in FreePascal using Synapse.

Please, stop whining about ports, iopl, and UART registers, and using C instead - and start doing it right by reading the available documentation.

Linux is based on an operating system invented in the 60ies of the last century. That means, it does not support such modern things like direct hardware accesses, single tasking, and single users. Instead it is based on the obviously totally flawed concept of having multiple users and applications at the same time with the added overhead of task switching and all that stuff. Which also means, it has to protect things against getting garbled - like when sane, understanding and being able to learn programmers would program UARTs at the register level.

The last paragraph was pure irony, of course. Just in case, someone wondered.

Vinzent.

GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT! Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01

Reply by email

Vinzent Höfler
to Marco van de Voort: In our previous episode, Gustavo Enrique Jimenez said: How do you use it? I'm used to…

[Synapse/Synaser]

How do you use it? I'm used to TComport, and it seems that synaser, like unit serial, only supports blocking use.

call Connect, call Config, call the appropriate reading and writing subroutines (like SendString and RecvPacket)...

Do you put it in a thread?

You can, yes.

I need it for a link that receives and sends at random, not related moments.

http://synapse.ararat.cz/doc/help/synaser.TBlockSerial.html

You may use RecvPacket with a timout and run a "polling" loop.

Vinzent.

Preisknaller: GMX DSL Flatrate für nur 16,99 Euro/mtl.! http://portal.gmx.net/de/go/dsl02

Reply by email

Brad Campbell
to Holger Bruns: Thank you for your answer. I played with different baud rates. The sender delivers a…
Holger Bruns wrote
At first, there must be a queue for incoming data despite I ruled out a queue with an inbuffer with the length 1.

No, you did not rule out a queue at all, you are simply reading from it 1 byte at a time.

I'm absolutely positive you can do what you want to do by simply using the serial unit. The problem is we don't know how to help you as you keep waving about wild assertions and refuse to actually tell us what you want to do so we can help you.

How about posting your code thus far and a brief description about what you are trying to do?

Serial on linux is really not hard, and when you get it right on Linux you get it working on Mac OSX for free :)

Just stop thinking about the very low level details about what you are trying to do. Pretend the UART does not exist and you are just dealing with a device with a well defined interface.

You can open the port with, or without blocking. You can easily enable/disable hardware flow control, you can manually toggle the flow control lines, you can change the formats and data rates and you can do all this very, very easily. Just let us help you instead of telling us that it all sucks and all you need to do is access the UART directly. If you do this the *right* way, you get multi-port, USB->Serial and transparent serial network devices all for free.

Brad

Dolphins are so intelligent that within a few weeks they can train Americans to stand at the edge of the pool and throw them fish.

Reply by email

Holger Bruns
to Jonas Maebe: $ man iopl ... This call is mostly for the i386 architecture. On many other architec-…
Show quoted text 14 lines
On 19 Nov 2009, at 14:30, Holger Bruns wrote: > Since iopl is still not available to fpc in its 64-bit-version, I > should move to c for future port programming. $ man iopl ... This call is mostly for the i386 architecture. On many other architec- tures it does not exist or will always return an error. Switching to C will not cause this function to magically appear in the Linux kernel on non-i386 systems.

Hi Jonas,

this seems to work on a 64-bit-system:

#include <sys/io.h>
int
main(int argc, char *argv[])
{
unsigned char b;

    if (iopl(3) == -1)
        perror("iopl");
    b = inb(0xec00);
    printf("b=%#x\n", b);
}

It is c, but now I simply need to know how to call c functions in pascal programs. I am using a linux kernel in version 2.6.28, and for this kernel version your quotation of "man iopl" seems not to be valid.

Holger

Reply by email

Henry Vermaak
to Holger Bruns

2009/11/20 Holger Bruns :

Show quoted text 19 lines
Jonas Maebe schrieb: > > On 19 Nov 2009, at 14:30, Holger Bruns wrote: > >> Since iopl is still not available to fpc in its 64-bit-version, I should >> move to c for future port programming. > > $ man iopl > ... >      This call is mostly for the i386 architecture.  On many other > architec- >      tures it does not exist or will always return an error. > > Switching to C will not cause this function to magically appear in the > Linux kernel on non-i386 systems. It is c, but now I simply need to know how to call c functions in pascal programs. I am using a linux kernel in version 2.6.28, and for this kernel version your quotation of "man iopl" seems not to be valid.

As the man page suggests:

"This call is necessary to allow 8514-compatible X servers to run under Linux. Since these X servers require access to all 65536 I/O ports, the ioperm() call is not sufficient."

What are you trying to achieve? The way to communicate with devices in linux is to talk to the /dev nodes with read, write and ioctl. Using inb is almost always the wrong thing to do.

Henry

Reply by email