My problem: I want to open a serial device in a GP-Program to read and write to it in changing order. I look for a way that allowes to do (non blocking) read AND write to one single file-variable assigned to eg /dev/ttySx. So far I have found the "CanRead-function" in the manual which serves perfect for the non blocking job! But still I have to use two file-variables, one opened with reset, one opened with rewrite, and both symbolically linked to the desired serial file eg. /dev/ttySx. And it works, reading from the first when "CanRead" is true and writing to the latter whenever it is necessary.
Having read almost all portions of the GNU Pascal Manual nevertheless could not find a solution to use only one file-variable.
What is behind it? I do have an awful lot of programs from old TP3-times doing exactly that using "aux" and a home made "CanRead" equivalent.
I dare to ask and will even be full of thanks if I get just the answer "rtfm, THERE"
Thanks to all who keep the GPC working,
Mathias Uhle
PS.: To keep this mail short I just add: a wonderful Compiler, great!
Mathias Uhle wrote:
My problem: I want to open a serial device in a GP-Program to read and write to it in changing order. I look for a way that allowes to do (non blocking) read AND write to one single file-variable assigned to eg /dev/ttySx. So far I have found the "CanRead-function" in the manual which serves perfect for the non blocking job! But still I have to use two file-variables, one opened with reset, one opened with rewrite, and both symbolically linked to the desired serial file eg. /dev/ttySx. And it works, reading from the first when "CanRead" is true and writing to the latter whenever it is necessary.
Having read almost all portions of the GNU Pascal Manual nevertheless could not find a solution to use only one file-variable.
The following should work (I works on ordinary file):
program do_rw; var f : file of char; c : char; begin reset(f, '/dev/ttyS0'); write(f, 'b'); read(f, c); writeln(c); end .
The crucial point is that I use "file of char" (one can use other typed files, but for serial port using anything bigger then byte is going to loose). AFAICS bidirectional access to non-disk text files is not supported.
Waldek Hebisch wrote:
Mathias Uhle wrote:
My problem: I want to open a serial device in a GP-Program to read and write to it in changing order. I look for a way that allowes to do (non blocking) read AND write to one single file-variable assigned to eg /dev/ttySx. So far I have found the "CanRead-function" in the manual which serves perfect for the non blocking job!
Indeed. Of course, there's also CanWrite for non-blocking writing, and the more powerful (but also more complicated to use) IOSelect, to check for both things at once, possibly on several files at once, and optionally with a timeout (in order to avoid busy waiting).
But still I have to use two file-variables, one opened with reset, one opened with rewrite, and both symbolically linked to the desired serial file eg. /dev/ttySx. And it works, reading from the first when "CanRead" is true and writing to the latter whenever it is necessary.
Having read almost all portions of the GNU Pascal Manual nevertheless could not find a solution to use only one file-variable.
The following should work (I works on ordinary file):
program do_rw; var f : file of char; c : char; begin reset(f, '/dev/ttyS0'); write(f, 'b'); read(f, c); writeln(c); end .
The crucial point is that I use "file of char" (one can use other typed files, but for serial port using anything bigger then byte is going to loose). AFAICS bidirectional access to non-disk text files is not supported.
You could try the TextMode variable. The (BP compatible) default FileMode_Reset_ReadWrite enables the behaviour as Waldek explained. Adding FileMode_Text_Reset_ReadWrite should do the same for text files, but due to the special handling of line breaks in text files, you might really prefer file of char (or BP compatible untyped files with a block size of 1 and using a 4th argument to BlockRead/BlockWrite).
Frank
Hello Waldek and Frank
Thank you for your suggestions and help. Meanwhile I did some experiments starting with your suggestions and found a rather simple" solution:
Inside the Pascal Program two files (either "of char" or "text") are declared, eg. comin, comout : file of char; These are both assigned to the same serial device, no need for any links etc.
Hope the rest will - for those who are interested - became clear by the added testprogram.
Thanks again, Mathias Uhle
program ttyeng;
(* Testprogram for reading and writing from/to a serial device (RS232C). To be able to read and write simultaneously from/to eg. /dev/ttySx two different filevariables are declared. Both are assigned to the same device and opened usung reset and rewrite resp. And, to make things further clear and easy, properties of the device are set using Execute(cmdline); The function "CanRead" is used to test whether a character is available or not. "CanWrite" could similarly be used to test if a character may be written, if that is necessary.
M. Uhle 19.12.2005 17h45 *)
const CMDline = 'stty' (* Commandname *) +' -F /dev/ttyUSB1'(* devicename: USB to serial *) +' raw' (* Modus raw *) +' -echo'(* No Echo!*) +' 9600' (* Baudrate *) ;
var comin,comout : text; {file of char;} xch,lc : char; b,xchda : boolean;
(* Some external Declarations from GPC-Manual .........*) type GPC_FDR = Anyfile; Cinteger = integer; function CanRead(var f:GPC_FDR):boolean; attribute(name='_p_CanRead'); external; Function Execute(const CMDline : string):integer; attribute(iocritical, name = '_p_Execute');external; procedure Sleep(Seconds : Cinteger); external name '_p_Sleep'; procedure SleepMicroseconds(Microseconds : Cinteger); external name '_p_SleepMicroSeconds'; (* End of the external Declaratios from GPC-Manual .............*)
begin (* -- Main---- Main---- Main---- Main---- Main---- Main---- Main--*)
if Execute(CMDline) =0 then writeln('Device correctly set') else writeln('Error: Setting device failed!');
assign(comin,'com'); reset(comin); (* Setup comin for reading *)
assign(comout,'com'); rewrite(comout); (* Setup comout for writing *) lc:='A'; repeat {} sleepMicroseconds(1000000); write(comout,lc); lc:=succ(lc); if lc>'Z' then lc:='A';
(* Testprogram on second machine will echo character *)
repeat xchda:=canread(comin); write('.'); (* funny: just that one can see, that the program did not go home to mess its maker!*) until xchda;
read(comin,xch); write(ord(xch):4); until false; end. (* -- Main---- Main---- Main---- Main---- Main---- Main---- Main--*)
Am Sonntag 18 Dezember 2005 03:47 schrieben Sie:
Waldek Hebisch wrote:
Mathias Uhle wrote:
My problem: I want to open a serial device in a GP-Program to read and write to it in changing order. I look for a way that allowes to do (non blocking) read AND write to one single file-variable assigned to eg /dev/ttySx. So far I have found the "CanRead-function" in the manual which serves perfect for the non blocking job!
Indeed. Of course, there's also CanWrite for non-blocking writing, and the more powerful (but also more complicated to use) IOSelect, to check for both things at once, possibly on several files at once, and optionally with a timeout (in order to avoid busy waiting).
But still I have to use two file-variables, one opened with reset, one opened with rewrite, and both symbolically linked to the desired serial file eg. /dev/ttySx. And it works, reading from the first when "CanRead" is true and writing to the latter whenever it is necessary.
Having read almost all portions of the GNU Pascal Manual nevertheless could not find a solution to use only one file-variable.
The following should work (I works on ordinary file):
program do_rw; var f : file of char; c : char; begin reset(f, '/dev/ttyS0'); write(f, 'b'); read(f, c); writeln(c); end .
The crucial point is that I use "file of char" (one can use other typed files, but for serial port using anything bigger then byte is going to loose). AFAICS bidirectional access to non-disk text files is not supported.
You could try the TextMode variable. The (BP compatible) default FileMode_Reset_ReadWrite enables the behaviour as Waldek explained. Adding FileMode_Text_Reset_ReadWrite should do the same for text files, but due to the special handling of line breaks in text files, you might really prefer file of char (or BP compatible untyped files with a block size of 1 and using a 4th argument to BlockRead/BlockWrite).
Frank