Sign in Join

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

Mailing lists / fpc-pascal / 2009-11

Access to RS232 ports with fpc

30 messages · 16 people · –

Reply by email Subscribe to this list Your subscription

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

Holger Bruns

Hello,

I am new to this list. For programming the serial ports on a linux system, I tried to use the "serial" unit. i don't understand the declaration for "buffer" in the function below, because no type is declared for "buffer". How can I read a character from the selected serial port? This is the part of the serial unit I am talking about:

  function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt):
LongInt;
    begin
    Result := fpRead(Handle, Buffer, Count);
  end;

I hope so far, you can help me out with an advice.

Best regards, Holger

Reply by email

Jürgen Hestermann
to Holger Bruns
Show quoted text 7 lines
function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt; begin Result := fpRead(Handle, Buffer, Count); end; i don't understand the declaration for "buffer" in the function below, because no type is declared for "buffer".

I believe that the type is irrelevant, you can use whatever you want. I think that it's just used by fpRead to buffer data. You only provide the space for the buffer but you don't need to read it directly. It seems that Count has to be the size of the buffer. But I am just guessing....

Reply by email

Holger Bruns
to Jürgen Hestermann
Show quoted text 13 lines
> function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): > LongInt; > begin > Result := fpRead(Handle, Buffer, Count); > end; > i don't understand the declaration for "buffer" in the function > below, because no type is declared for "buffer". I believe that the type is irrelevant, you can use whatever you want. I think that it's just used by fpRead to buffer data. You only provide the space for the buffer but you don't need to read it directly. It seems that Count has to be the size of the buffer. But I am just guessing....

My hope was to read more than guessing. As I pointed out, the "buffer" seems not to be filled with incoming data from the selected serial port. Hence I cannot read just this data, and serread seems to be faulty. For this reason I ask for an advice. I need to look on working sample code to use this function in a working manner. In my example, serread replies only, what has been written with serwrite right before. Not even serflush, executed right after serwrite, can solve this problem to me.

Holger

Reply by email

Martin
to Holger Bruns
Holger Bruns wrote 22 lines
Jürgen Hestermann schrieb: >> function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): >> LongInt; >> begin >> Result := fpRead(Handle, Buffer, Count); >> end; >> i don't understand the declaration for "buffer" in the function >> below, because no type is declared for "buffer". > > I believe that the type is irrelevant, you can use whatever you want. > I think that it's just used by fpRead to buffer data. You only > provide the space for the buffer but you don't need to read it > directly. It seems that Count has to be the size of the buffer. But I > am just guessing.... My hope was to read more than guessing. As I pointed out, the "buffer" seems not to be filled with incoming data from the selected serial port. Hence I cannot read just this data, and serread seems to be faulty. For this reason I ask for an advice. I need to look on working sample code to use this function in a working manner. In my example, serread replies only, what has been written with serwrite right before. Not even serflush, executed right after serwrite, can solve this problem to me.
var foo;
const foo;

are hidden pointer types.
That is foo would contain a pointer, but you never see this. You never have to get the address of something, and you never have to dereference it.

As for using this:

SerRead(Handle, Buffer, 0)

Buffer must be the first byte of a block of memory

you can do:
var buffer: Array of byte;
SetLength(Buffer, 1000);
SerRead(Handle, Buffer[0], 1000);

NOTE the [0] index you supply the first byte of your buffer. FPC is internally taking the address of this first bytes, and then 1000 bytes from this address on will be used

----
Example 2

var buffer: ^Byte; // bointer to byte
Buffer = GetMem.....; // buffer contains the address of your memory
SerRead(Handle, Buffer^, 1000); // again ^ dereference it

----
Example 3
There are case where the [0] or ^ is optional, but you need to understand a lot how fpc allocates memory

var buffer: Array [0..999] of byte;
SerRead(Handle, Buffer, 1000); // you can do buffer[0] too

-------

The most common fault is, that people forget to specify [0] or ^ and that leads to errors.

The below is WRONG:
var buffer: ^Byte; // bointer to byte
Buffer = GetMem.....; // buffer contains the address of your memory
SerRead(Handle, Buffer, 1000); // missing ^

It is wrong because buffer itself is a variable having 4 or 8 byte (32 or 64 bit platform). Buffer only contains the address of where the data is. If you pass buffer like in the example above, "SerRead" willbut the rsult into the 4 bytes of the variable itself (and then writing to random memory behind this)

Martin

Reply by email

Holger Bruns
to Martin: var foo; const foo; are hidden pointer types. That is foo would contain a pointer, but…
Show quoted text 44 lines
Holger Bruns wrote: > Jürgen Hestermann schrieb: >>> function SerRead(Handle: TSerialHandle; var Buffer; Count: >>> LongInt): LongInt; >>> begin >>> Result := fpRead(Handle, Buffer, Count); >>> end; >>> i don't understand the declaration for "buffer" in the function >>> below, because no type is declared for "buffer". >> >> I believe that the type is irrelevant, you can use whatever you >> want. I think that it's just used by fpRead to buffer data. You only >> provide the space for the buffer but you don't need to read it >> directly. It seems that Count has to be the size of the buffer. But >> I am just guessing.... > My hope was to read more than guessing. As I pointed out, the > "buffer" seems not to be filled with incoming data from the selected > serial port. Hence I cannot read just this data, and serread seems to > be faulty. For this reason I ask for an advice. I need to look on > working sample code to use this function in a working manner. In my > example, serread replies only, what has been written with serwrite > right before. Not even serflush, executed right after serwrite, can > solve this problem to me. var foo; const foo; are hidden pointer types. That is foo would contain a pointer, but you never see this. You never have to get the address of something, and you never have to dereference it. As for using this: SerRead(Handle, Buffer, 0) Buffer must be the first byte of a block of memory you can do: var buffer: Array of byte; SetLength(Buffer, 1000); SerRead(Handle, Buffer[0], 1000);

Hi Martin,

I checked this out. It works not reliable. Sometimes I get real data, sometimes the data are corrupted. I have no idea to rule out corrupted data. I also tried to use the synaser unit, which can be found on the internet. The demo code "sertest" crashes instantly.

The only way to get rid of this problem is a direct port access. But direct port access is only possible for the first 200 port addresses. A "port" array is not yet implemented, and the required higher port addresses are strictly ruled out from every use through compiled fpc programs. I do not understand this harsh policy. And I have no idea to rule this policy out. If there is any possibility to get access to all ports on the system without access error messages, please let me know. If I need to alter the compiler, is there a patch available? Or should I use gcc rather than fpc to match my ideas?

The real sad thing is, that one cannot produce software for Linux, based on the restricted free pascal compiler. I am really disappointed.

Best regards, Holger

Reply by email

Marco van de Voort
to Holger Bruns

In our previous episode, Holger Bruns said:

Show quoted text 13 lines
The only way to get rid of this problem is a direct port access. But direct port access is only possible for the first 200 port addresses. A "port" array is not yet implemented, and the required higher port addresses are strictly ruled out from every use through compiled fpc programs. I do not understand this harsh policy. And I have no idea to rule this policy out. If there is any possibility to get access to all ports on the system without access error messages, please let me know. If I need to alter the compiler, is there a patch available? Or should I use gcc rather than fpc to match my ideas? The real sad thing is, that one cannot produce software for Linux, based on the restricted free pascal compiler. I am really disappointed.

WHere is this limitation? I'm not aware that FPC has a limitation that GCC hasn't. More probably it is an OS limitation, or do you need to ask permission for higher portnumbers with ioperm.

Reply by email

Roberto Padovani
to Holger Bruns: I checked this out. It works not reliable. Sometimes I get real data, sometimes the data…

There's nothing limited within the compiler! If you have the same knowledge and expertise of Pascal and C, IMHO with gcc you will only be complicating your life.

About serial port, low level routine need some practice, but you can go quickly to the point with this component for lazarus:

http://sourceforge.net/projects/cportlaz/

You get threaded data reception and even packet parsing with automatic event fire on a specific packet pattern.
I am using it to develop hardware monitors which are running smoothly also on old fashioned hardware, so there's no packet loss or packet corruption.

R#

2009/11/2 Holger Bruns :

Show quoted text 73 lines
Martin schrieb: > > Holger Bruns wrote: >> >> Jürgen Hestermann schrieb: >>>> >>>> function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): >>>> LongInt; >>>>   begin >>>>   Result := fpRead(Handle, Buffer, Count); >>>>   end; >>>> i don't understand the declaration for "buffer" in the function below, >>>> because no type is declared for "buffer". >>> >>> I believe that the type is irrelevant, you can use whatever you want. I >>> think that it's just used by fpRead to buffer data. You only provide the >>> space for the buffer but you don't need to read it directly. It seems that >>> Count has to be the size of the buffer. But I am just guessing.... >> >> My hope was to read more than guessing. As I pointed out, the "buffer" >> seems not to be filled with incoming data from the selected serial port. >> Hence I cannot read just this data, and serread seems to be faulty. For this >> reason I ask for an advice. I need to look on working sample code to use >> this function in a working manner. In my example, serread replies only, what >> has been written with serwrite right before. Not even serflush, executed >> right after serwrite, can solve this problem to me. > > var foo; > const foo; > > are hidden pointer types. > That is foo would contain a pointer, but you never see this. You never > have to get the address of something, and you never have to dereference it. > > As for using this: > > SerRead(Handle, Buffer, 0) > > Buffer must be the first byte of a block of memory > > you can do: > var buffer: Array of byte; > > SetLength(Buffer, 1000); > SerRead(Handle, Buffer[0], 1000); > Hi Martin, I checked this out. It works not reliable. Sometimes I get real data, sometimes the data are corrupted. I have no idea to rule out corrupted data. I also tried to use the synaser unit, which can be found on the internet. The demo code "sertest" crashes instantly. The only way to get rid of this problem is a direct port access. But direct port access is only possible for the first 200 port addresses. A "port" array is not yet implemented, and the required higher port addresses are strictly ruled out from every use through compiled fpc programs. I do not understand this harsh policy. And I have no idea to rule this policy out. If there is any possibility to get access to all ports on the system without access error messages, please let me know. If I need to alter the compiler, is there a patch available? Or should I use gcc rather than fpc to match my ideas? The real sad thing is, that one cannot produce software for Linux, based on the restricted free pascal compiler. I am really disappointed. Best regards, Holger _______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Jonas Maebe
to Holger Bruns: I checked this out. It works not reliable. Sometimes I get real data, sometimes the data…

Holger Bruns wrote on Mon, 02 Nov 2009:

Show quoted text 10 lines
Martin schrieb: > you can do: > var buffer: Array of byte; > > SetLength(Buffer, 1000); > SerRead(Handle, Buffer[0], 1000); I checked this out. It works not reliable. Sometimes I get real data, sometimes the data are corrupted. I have no idea to rule out corrupted data.

You have to check the result of the serread routine. Since it returns the result of the fpread call, "man 2 read" will tell you what those results mean. In short,
a) result >= 0: actual number of bytes read (the 1000 you pass is just a maximum)
b) result < 0: an error occurred

Jonas

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Reply by email

Frank Peelo
to Holger Bruns: My hope was to read more than guessing. As I pointed out, the "buffer" seems not to be…
Show quoted text 7 lines
function SerRead(Handle: TSerialHandle; var Buffer; Count: LongInt): LongInt; begin Result := fpRead(Handle, Buffer, Count); end; i don't understand the declaration for "buffer" in the function below, because no type is declared for "buffer".

Untyped parameters date back to early TurboPascal.

http://www.freepascal.org/docs-html/ref/refsu48.html

Variable and constant parameters can be untyped. In that case the variable has no type, and hence is incompatible with all other types. However, the address operator can be used on it, or it can be can passed to a function that has also an untyped parameter. If an untyped parameter is used in an assigment, or a value must be assigned to it, a typecast must be used.

This can be used when you create a variable to use as a block of memory, for a buffer. The size of the buffer has to be known to the function, so it would typically be passed in as a parameter.

I'd guess the reason for adding these to the language is that the caller has to have a variable to pass, so you are less likely to pass an invalid pointer, i.e. one which has not been set to point at allocated memory.

FP

Reply by email

Holger Bruns
to Jonas Maebe: Holger Bruns wrote on Mon, 02 Nov 2009: You have to check the result of the serread…
Show quoted text 19 lines
Holger Bruns wrote on Mon, 02 Nov 2009: > Martin schrieb: >> you can do: >> var buffer: Array of byte; >> >> SetLength(Buffer, 1000); >> SerRead(Handle, Buffer[0], 1000); > > I checked this out. It works not reliable. Sometimes I get real data, > sometimes the data are corrupted. I have no idea to rule out > corrupted data. You have to check the result of the serread routine. Since it returns the result of the fpread call, "man 2 read" will tell you what those results mean. In short, a) result >= 0: actual number of bytes read (the 1000 you pass is just a maximum) b) result < 0: an error occurred

Thank you. I checked this out, but every incoming character is interpreted as zero, regardless of its real value.

Holger

Reply by email

Holger Bruns
to Felipe Monteiro de Carvalho: It may be useful to know that there is a serial communication example using Synaser here:…
Show quoted text 5 lines
It may be useful to know that there is a serial communication example using Synaser here: http://wiki.lazarus.freepascal.org/Hardware_Access#Serial_Communication

Yes, thank you. I checked this out. The procedure reccvbyte, as used in this manner:

 Write(IntToHex(ser.RecvByte(1000), 2), ' ');

reads every incoming character as zero. Simply, is does not work.

It's much easier to use then using the lower level routines yourself.

I try to implement a direct port access. If this also leads to access errors, I should give it up. Embarassing.

Holger

Reply by email

Jonas Maebe
to Holger Bruns

Holger Bruns wrote on Mon, 02 Nov 2009:

Show quoted text 12 lines
Felipe Monteiro de Carvalho schrieb: > It may be useful to know that there is a serial communication example > using Synaser here: > > http://wiki.lazarus.freepascal.org/Hardware_Access#Serial_Communication > Yes, thank you. I checked this out. The procedure reccvbyte, as used in this manner: Write(IntToHex(ser.RecvByte(1000), 2), ' '); reads every incoming character as zero. Simply, is does not work.

Are you certain that your serial port is actually configured correctly? Many people have successfully used these units in the past, so it most likely seems like a configuration or usage problem.

Moreover, the serread function you posted earlier is about as low level as you can get: it directly reads bytes from a handle using a system call. If that never works, then the problem is almost certainly completely unrelated to anything FPC.

You may also want to post the complete test program that you are using, maybe there is an error somewhere.

I try to implement a direct port access. If this also leads to access errors, I should give it up. Embarassing.

Please stop complaining in virtually every reply to people trying to help you.

Jonas

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Reply by email

Holger Bruns
to Holger Bruns: Yes, thank you. I checked this out. The procedure reccvbyte, as used in this manner:…
I try to implement a direct port access. If this also leads to access errors, I should give it up. Embarassing.

Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm. This means to me, successful serial port access on higher addresses cannot yet be implemented with fpc. If this policy can be ruled out, let me know.

Holger

Reply by email

Florian Klaempfl
to Holger Bruns
Show quoted text 7 lines
Holger Bruns schrieb: > I try to implement a direct port access. If this also leads to access > errors, I should give it up. Embarassing. Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm. This means to me, successful serial port access on higher addresses cannot yet be implemented with fpc. If this policy can be ruled out, let me know.

This has nothing to do with fpc. Maybe you should read the ioperm man page and you might start to understand things.

Reply by email

Jonas Maebe
to Holger Bruns: Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm.…

Holger Bruns wrote on Mon, 02 Nov 2009:

Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm. This means to me, successful serial port access on higher addresses cannot yet be implemented with fpc. If this policy can be ruled out, let me know.

fpioperm directly passes whatever parameters you give it to the Linux kernel. If the kernel refuses you access to those ports, there is nothing FPC can do about that.

Jonas

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Reply by email

Holger Bruns
to Florian Klaempfl: This has nothing to do with fpc. Maybe you should read the ioperm man page and you might…
Show quoted text 16 lines
Holger Bruns schrieb: > Holger Bruns schrieb: > >> I try to implement a direct port access. If this also leads to access >> errors, I should give it up. Embarassing. >> > Accessing ports is limited to ports < 03ffh, more ports cannot be > released with fpioperm. This means to me, successful serial port access > on higher addresses cannot yet be implemented with fpc. If this policy > can be ruled out, let me know. > This has nothing to do with fpc. Maybe you should read the ioperm man page and you might start to understand things.

I am new to linux and wrote only small things for MS-DOS before. As far as I could read on the internet, fpc uses ioperm and iopl, and I will try to use iopl to get access to the ports I want to use. The problem is indeed the rights management, as far as I can read on several web pages, which addresses my technical problem. The rights management cannot be ruled out by an application like I intend to write. But I can deal with it, I hope so far.

My posts to this list are not written against any person. My problem is not an interpersonal problem, but a technical question, and I try to find a good answer to it.

Holger

Reply by email

Bernd Mueller
to Holger Bruns: Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm.…
Holger Bruns wrote 7 lines
Holger Bruns schrieb: > I try to implement a direct port access. If this also leads to access > errors, I should give it up. Embarassing. Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm. This means to me, successful serial port access on higher addresses cannot yet be implemented with fpc. If this policy can be ruled out, let me know.

so you must use a very special serial hardware which is located on io address higher than $3ff. Seems unlikely to me. In your former post, you tried to access io address 1000 (decimal) this is $3e8 (hexadecimal) and should be an ordinary COM3. May be you are mixing up decimal vs. hexadecimal notation.

Regards, Bernd.

Reply by email

Holger Bruns
to Bernd Mueller
Show quoted text 15 lines
Holger Bruns wrote: > Holger Bruns schrieb: >> I try to implement a direct port access. If this also leads to >> access errors, I should give it up. Embarassing. > Accessing ports is limited to ports < 03ffh, more ports cannot be > released with fpioperm. This means to me, successful serial port > access on higher addresses cannot yet be implemented with fpc. If > this policy can be ruled out, let me know. so you must use a very special serial hardware which is located on io address higher than $3ff. Seems unlikely to me. In your former post, you tried to access io address 1000 (decimal) this is $3e8 (hexadecimal) and should be an ordinary COM3. May be you are mixing up decimal vs. hexadecimal notation.

No, the "1000" means the size of a buffer, not a part address. The port address I try to use is 0xEC00, which is the base address for an UART on a PCI card. Linux sees this UART as /dev/ttyS2. Accessing the registers direcly should be easy, because 3 lines of assembler code should do this job:

function readport (portaddress: word): byte;
begin
 asm
  mov %dx, portaddress
   inb %al,%dx
  mov readport, %al
 end
end;

As long as the pascal syntax and the assembler syntax (instruction destination source) are both correct for fpc, this function should return the value of the selected port. This is all, what I try to do.

Best regards, Holger

Reply by email

Gustavo Enrique Jimenez
to Holger Bruns
Show quoted text 22 lines
No, the "1000" means the size of a buffer, not a part address. The port address I try to use is 0xEC00, which is the base address for an UART on a PCI card. Linux sees this UART as /dev/ttyS2. Accessing the registers direcly should be easy, because 3 lines of assembler code should do this job: function readport (portaddress: word): byte; begin asm  mov %dx, portaddress  inb %al,%dx  mov readport, %al end end; As long as the pascal syntax and the assembler syntax (instruction destination source) are both correct for fpc, this function should return the value of the selected port. This is all, what I try to do. Best regards, Holger

Just user synaser, http://www.synapse.ararat.cz/ . When you get the thing working, go back to the serial unit. I do SCADA with Modbus through serial port. Never had a problem.
You can't write programs in linux (or windows) like in DOS.

Gustavo

Reply by email

Marc Santhoff
to Holger Bruns: I am new to linux and wrote only small things for MS-DOS before. As far as I could read…
Holger Bruns wrote 7 lines
I am new to linux and wrote only small things for MS-DOS before. As far as I could read on the internet, fpc uses ioperm and iopl, and I will try to use iopl to get access to the ports I want to use. The problem is indeed the rights management, as far as I can read on several web pages, which addresses my technical problem. The rights management cannot be ruled out by an application like I intend to write. But I can deal with it, I hope so far.

The best things you can do are to:

- Search the web for a freely available document called: "Serial Programming Guide for POSIX Oaperating Systems"

This document shows you how to set up serial ports on Linux, the most important part when you cann open the port but not send or receive anything meaningful.

- Use the device the system gives you. ANything else is aking for trouble (IMHO).

If you can access and use the hardware port in question at all, maybe connecting a mouse or something, it will work in your fpc programs.

My posts to this list are not written against any person. My problem is not an interpersonal problem, but a technical question, and I try to find a good answer to it.

Some more examples (shortened from real code for showing the principle):

sDefaultPort: string = '/dev/cuaa0'; { this would be /dev/ttyS2 for you }

fPort = sDefaultPort;
{ Init }
fCom := SerOpen(fPort);
if (fCom > -1) then begin
  SerSetParams(fCom, 1200, 7, NoneParity, 2, []);
end else begin
  writeln('Metex: failed to open port');
  n := GetLastOSError;
end
{ Reading }
var
  inbuf: array[0..14] of char;
begin
  fillchar(inbuf, sizeof(inbuf), #0);
  res := SerRead(fCom, inbuf[0], 14); { last figure would be 1000 for you, bytes to read }
  if (res < 0) then
    { signal error }
...

That way I use serial ports successfully on FreeBSD and Windows.

HTH,
Marc

Marc Santhoff

Reply by email

Vinzent Höfler
to Holger Bruns: Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm.…

Holger Bruns :

Accessing ports is limited to ports < 03ffh, more ports cannot be released with fpioperm. This means to me, successful serial port access on higher addresses cannot yet be implemented with fpc.

Or any other compiler, for that matter, because this is a system restriction. Plus, it's Linux-only, it's i386-only, it's pure legacy and thus should not even be used anymore.

If this policy can be ruled out, let me know.

If you want to access ports directly, compile for DOS or write a device driver.

Vinzent.

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

Reply by email

Holger Bruns
to Marc Santhoff: The best things you can do are to: - Search the web for a freely available document…
Show quoted text 27 lines
sDefaultPort: string = '/dev/cuaa0'; { this would be /dev/ttyS2 for you } fPort = sDefaultPort; { Init } fCom := SerOpen(fPort); if (fCom > -1) then begin SerSetParams(fCom, 1200, 7, NoneParity, 2, []); end else begin writeln('Metex: failed to open port'); n := GetLastOSError; end { Reading } var inbuf: array[0..14] of char; begin fillchar(inbuf, sizeof(inbuf), #0); res := SerRead(fCom, inbuf[0], 14); { last figure would be 1000 for you, bytes to read } if (res < 0) then { signal error } ... That way I use serial ports successfully on FreeBSD and Windows.

This helps a lot. Thank you. This was the example I was looking for. My fault was the declaration of inbuffer: array of char, and I guess, I did not understand how to deal with hidden pointers. Now I've got this idea from you and hope so far, I can move on.

Best regards, Holger

Reply by email

Brad Campbell
to Holger Bruns: I checked this out. It works not reliable. Sometimes I get real data, sometimes the data…
Holger Bruns wrote
The real sad thing is, that one cannot produce software for Linux, based on the restricted free pascal compiler. I am really disappointed.

That's an interesting assertion.
I use serial.pp on i386 Linux, x86_64 Linux, PPC OSX & Intel OSX flawlessly. I use synaser on Win32.

I suspect you might be doing something wrong, but with the complete lack of information provided about what you are doing and how you are doing it there is just no way to help you.

Why not try attaching your test code that is failing so we can help you get it working?

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
Why not try attaching your test code that is failing so we can help you get it working?

Done. My fault was the following declaration:

var inbuffer: array of char;

This is a better declaration:

var inbuffer: array[0..10] of char;

Now I got my code working. Hidden pointers are new to me. Therefore I felt in trouble with it. Secondly, it appears to be necessary to use the fpc compiler as "root", not simply as a user, I guess.

Best regards, Holger

Reply by email

Tomas Hajny
to Holger Bruns
Holger Bruns wrote 16 lines
Brad Campbell schrieb: > > Why not try attaching your test code that is failing so we can help > you get it working? Done. My fault was the following declaration: var inbuffer: array of char; This is a better declaration: var inbuffer: array[0..10] of char; Now I got my code working. Hidden pointers are new to me. Therefore I felt in trouble with it. Secondly, it appears to be necessary to use the fpc compiler as "root", not simply as a user, I guess.

The compiler may be certainly run under other users (well, at least if installed properly), but access to ports requires root privileges as far as I know.

Tomas

Reply by email

Henry Vermaak
to Holger Bruns: Done. My fault was the following declaration: var inbuffer: array of char; This is a…

2009/11/3 Holger Bruns :

in trouble with it. Secondly, it appears to be necessary to use the fpc compiler as "root", not simply as a user, I guess.

You need permissions to access any files on linux. Device nodes are files, too. This is what it looks like on debian:

ls -l /dev/ttyS*
crw-rw---- 1 root dialout 4, 64 2009-11-03 13:27 /dev/ttyS0 crw-rw---- 1 root dialout 4, 65 2009-11-03 13:27 /dev/ttyS1 crw-rw---- 1 root dialout 4, 66 2009-11-03 13:27 /dev/ttyS2 crw-rw---- 1 root dialout 4, 67 2009-11-03 13:27 /dev/ttyS3

This means that I need to be part of the dialout group (or root) to be able to read/write to these files. You can see the group information in /etc/group.

Henry

Reply by email

Marc Santhoff
to Tomas Hajny: The compiler may be certainly run under other users (well, at least if installed…
Tomas Hajny wrote 21 lines
On Tue, November 3, 2009 02:33, Holger Bruns wrote: > Brad Campbell schrieb: >> >> Why not try attaching your test code that is failing so we can help >> you get it working? > > Done. My fault was the following declaration: > > var inbuffer: array of char; > > This is a better declaration: > > var inbuffer: array[0..10] of char; > > Now I got my code working. Hidden pointers are new to me. Therefore I > felt in trouble with it. Secondly, it appears to be necessary to use the > fpc compiler as "root", not simply as a user, I guess. The compiler may be certainly run under other users (well, at least if installed properly), but access to ports requires root privileges as far as I know.

No it doesn't if the access rights are set properly.

1. make all users of the program members of a special group (e.g. dialers)

2. as root change the ownership of the tty device node to that group

At my desk:

$ cat /etc/group|grep dialer
dialer:*:68:marc

$ ls -l /dev/cua*
crw-rw---- 1 uucp dialer 0, 71 3 Nov 14:36 /dev/cuad0 crw-rw---- 1 uucp dialer 0, 72 3 Nov 14:36 /dev/cuad0.init crw-rw---- 1 uucp dialer 0, 73 3 Nov 14:36 /dev/cuad0.lock crw-rw---- 1 uucp dialer 0, 77 3 Nov 14:36 /dev/cuad1 crw-rw---- 1 uucp dialer 0, 78 3 Nov 14:36 /dev/cuad1.init crw-rw---- 1 uucp dialer 0, 79 3 Nov 14:36 /dev/cuad1.lock

As you can see I'm allowed to attach my dmm and open the serial port for reading it's measurements without being root or using sudo.

I don't know wheter todays Lunix systems have static device nodes seen here for ttys or if they are created dynamically and the rights have to be set in some configuration file - consult your systems docs or a good tutorial or book an those questions.

Try at the console:

$ man chown
$ man group
$ man ttys

at least on FreeBSD this manual pages exist and are very informative.

Have fun,
Marc

Marc Santhoff

Reply by email

Henry Vermaak
to Marc Santhoff

2009/11/3 Marc Santhoff :

Show quoted text 5 lines
I don't know wheter todays Lunix systems have static device nodes seen here for ttys or if they are created dynamically and the rights have to be set in some configuration file - consult your systems docs or a good tutorial or book an those questions.

The permissions are handled by udev on most modern distributions:

rgrep tty.*dialout /lib/udev/*
/lib/udev/rules.d/91-permissions.rules:SUBSYSTEM=="tty", GROUP="dialout" /lib/udev/rules.d/91-permissions.rules:KERNEL=="iseries/vtty*", GROUP="dialout"

Henry

Reply by email

Marco van de Voort
to Vinzent Höfler: Holger Bruns : Or any other compiler, for that matter, because this is a system…

In our previous episode, "Vinzent H�fler" said:

Show quoted text 8 lines
> Accessing ports is limited to ports < 03ffh, more ports cannot be > released with fpioperm. This means to me, successful serial port access > on higher addresses cannot yet be implemented with fpc. Or any other compiler, for that matter, because this is a system restriction. Plus, it's Linux-only, it's i386-only, it's pure legacy and thus should not even be used anymore.

No, it should work on FreeBSD too.

But of course I wholeheartedly agree that this should be done over devices.

Reply by email