Target System: PowerPC, AdaMULTI v1.8.9b, VxWorks 5.4
How do I redirect the standard output? I'd like to redirect it to device
"/null"
Attempts:
Open (DevNull, Append_File, "/null");
Open (DevNull, "/null", "/null");
just cause Status_Error, i.e. the device is already "open". So how can
I then "Set_Output (DevNull);" without having the device object in
File_Type form?..
I hope you don't mind that I add a question here :-)
It is about the same subject:
Is it possible to say that one task shall have one std output and another
task a different std output?
Eg. that two task (in the same Ada-program) can have std output to different
Xterm windows in Linux.
Frank
No, the Ada Io packages are not task save, or aware. You can't even
reliably write form two tasks to the same file with out imposing
your own explicit locking protocol, such as using a protected
object or a handler task.
> This time with a subject... :-)
>
> Target System: PowerPC, AdaMULTI v1.8.9b, VxWorks 5.4
>
> How do I redirect the standard output? I'd like to redirect it to device
> "/null"
Normally this is done from the command line, when you launch your
executable. What OS are you on?
> Attempts: Open (DevNull, Append_File, "/null"); Open (DevNull,
> "/null", "/null");
>
> just cause Status_Error, i.e. the device is already "open". So how can
> I then "Set_Output (DevNull);" without having the device object in
> File_Type form?..
You can use Ada.Text_IO.Set_Output to set the _current_ output to some
file. But it has to be an open file, and you haven't gotten there yet.
Backing up a bit, why do you want to do this? I can guess that you
want to turn off some debugging output. It is _far_ better to define a
Debug_IO package, with a Boolean or Integer debug enabled variable.
Then have a style guide that says "Ada.Text_IO is _forbidden_ in
delivered code; use Debug_IO if you need debug output".
--
-- Stephe
> "Martin Dowie" <martin...@gecm.com> writes:
>
> > This time with a subject... :-)
> >
> > Target System: PowerPC, AdaMULTI v1.8.9b, VxWorks 5.4
> >
> > How do I redirect the standard output? I'd like to redirect it to device
> > "/null"
>
> Normally this is done from the command line, when you launch your
> executable. What OS are you on?
Duh; VxWorks! My brain is _not_ in high-power mode.
Anyway, I don't know how to redirect in VxWorks, but I _think_ it uses
the Posix shell redirection:
adacode > /dev/nul
>
>
>
> > Attempts: Open (DevNull, Append_File, "/null"); Open (DevNull,
> > "/null", "/null");
> >
> > just cause Status_Error, i.e. the device is already "open". So how can
> > I then "Set_Output (DevNull);" without having the device object in
> > File_Type form?..
>
> You can use Ada.Text_IO.Set_Output to set the _current_ output to some
> file. But it has to be an open file, and you haven't gotten there yet.
>
> Backing up a bit, why do you want to do this? I can guess that you
> want to turn off some debugging output. It is _far_ better to define a
> Debug_IO package, with a Boolean or Integer debug enabled variable.
> Then have a style guide that says "Ada.Text_IO is _forbidden_ in
> delivered code; use Debug_IO if you need debug output".
>
> --
> -- Stephe
--
-- Stephe
On the other hand, it is possible to open each device (Xterm) as a
separate file, and write to that file in only one task. If this does
not meet your needs then consider creating one or more tasks whose
role is to output data. You could design those tasks to take their
input data either from an entry using the classical Ada rendezvous,
or using a protected object as a communication buffer. Tasks
requiring output would simply call the entry on the task or the
protected object to "output" their data. The task actually writing
to the Xterm would respond to the data and perform the required
actions.
Jim Rogers
Colorado Springs, Colorado USA
On older vxWorks at least, writes to a file descriptor tied to the null
device always return
an error status so my compiler was seeing that and raising an exception on
all output.
I ended up having to create a null device driver that always returned good
status for writes.
"Martin Dowie" <martin...@gecm.com> wrote in message
news:3ad31759$1...@pull.gecm.com...
We did something rather similar to this with our vxWorks program. We wrote a
"Log" package that takes in messages in a task-safe manner (using a queue to
prevent priority inversions), slaps a time stamp and severity level on them,
then outputs them to standard IO and to a log file. The standard IO part can be
turned off at runtime by tweaking a global variable (in vxWorks all exported
globals can be modified at the command line). Individual developers and
*strongly* discuraged from using Text_IO directly.
When using a RTOS, I'd expect everyone to develop something along these lines.
You can't deal with the random crashes and priority inversions that would be
caused by unrestrained IO calls in a real-time application.
---
T.E.D. homepage - http://www.telepath.com/dennison/Ted/TED.html
home email - mailto:denn...@telepath.com
I have also had problems redirecting Ada.Text_Io on the same platform.
When I use the applicable VxWorks calls, ioGlobalStdSet or ioTaskStdSet,
my printf's from C programs are redirected, but Ada.Text_Io seems to
be unaffected. In my case, I'm trying to redirect IO to an open
socket.
The solution I'm toying with is making an Ada interface to printf.
Is there a better way to get Ada IO to respond to calls to the
above VxWorks functions?
One thing you might try, Martin, is to re-direct to "/null/0".
Cheers,
Mark
No, while VxWorks is based on Unix, it does not have a similar shell.
The general way to redirect IO in VxWorks is with ioGlobalStdSet (or
ioTaskStdSet for task-specific IO redirection).
Mark
In our 'real' development code this is exactly what will be done (we have
a Project.Text_IO package which is the same for all projects, and we
slap on whatever the OS provides in the way of 'Simple_IO' via the body,
or 'null'ed for production)
This is for testing and timing purposes.
So far, from what simple tests we've run each character seems to be
taking about 10ms to display via serial and 0.03ms via ethernet - does this
sound reasonable to everyone?.. :-)
--
Try:
int fd = open("/null",O_RDWR,0);
if(fd != ERROR)
{
ioGlobalStdSet(STD_IN,fd);
ioGlobalStdSet(STD_OUT,fd);
ioGlobalStdSet(STD_ERR,fd);
}
Regards,
Graham Baxter
Freelance Software Engineer
gba...@NOSPAM.bcs.org.uk
> > Backing up a bit, why do you want to do this? I can guess that you
> > want to turn off some debugging output. It is _far_ better to define a
> > Debug_IO package, with a Boolean or Integer debug enabled variable.
> > Then have a style guide that says "Ada.Text_IO is _forbidden_ in
> > delivered code; use Debug_IO if you need debug output".
>
> In our 'real' development code this is exactly what will be done (we have
> a Project.Text_IO package which is the same for all projects, and we
> slap on whatever the OS provides in the way of 'Simple_IO' via the body,
> or 'null'ed for production)
>
> This is for testing and timing purposes.
Hmm, another requirement I use is "test and time what you fly". It is
easier to use Project.Text_IO from the start, than to change to it
later.
Also, packages should be testable without editing; use child packages to
get access to private stuff.
> So far, from what simple tests we've run each character seems to be
> taking about 10ms to display via serial and 0.03ms via ethernet -
> does this sound reasonable to everyone?.. :-)
Hmm. Assuming 9600 baud serial link, 9 bits per character (with
parity), that's about 1 ms per character. So you seem to have a
significant tasking overhead in the serial implementation.
--
-- Stephe
I don't know precisely, but you should definitely ask your Ada vendor
how to do it. If you are using GNAT, look at the source for Text_IO
and see what they are doing.
Interfacing to printf is _not_ easy. 'puts' is a better C function to
call, if you have to resort to that.
--
-- Stephe
we tried a version which imported printf - and it was exactly the same
throughput...
we use the nulled version for debugging only when it hits the target (if
the bug can be spotted appropiately using it) and the non-nulled
version primarily for host work.
All formal integration/system tests are done using the null-ed version.
> Also, packages should be testable without editing; use child packages to
> get access to private stuff.
absolutely, hence our use of a "Project.Text_IO" which can be null-ed.
> Hmm. Assuming 9600 baud serial link, 9 bits per character (with
> parity), that's about 1 ms per character. So you seem to have a
> significant tasking overhead in the serial implementation.
yup :-(
And in return to the community here is the Ada equivilant we will
be using (feel free to add your own comments :-)
-- vxworks.ads
--------------
with Interfaces.C;
package VxWorks is
subtype A_Status is Interfaces.C.Int;
use type A_Status;
Ok : constant A_Status := 0;
Error : constant A_Status := -1;
end VxWorks;
-- vxworks-iolib.ads
--------------------
with Interfaces.C;
with Interfaces.C.Strings;
package VxWorks.ioLib is
O_RDONLY : constant := 16#0000#;
O_WRONLY : constant := 16#0001#;
O_RDWR : constant := 16#0002#;
O_CREAT : constant := 16#0200#;
subtype A_File is Interfaces.C.Int;
function Open (Name : Interfaces.C.Strings.Chars_Ptr;
Flags : Interfaces.C.Int;
Mode : Interfaces.C.Int) return A_File;
function Close (File : A_File) return A_Status;
STD_IN : constant A_File := 0;
STD_OUT : constant A_File := 1;
STD_ERR : constant A_File := 2;
function ioGlobalStdGet (StdFd : A_File) return A_File;
procedure ioGlobalStdSet (StdFd : A_File;
NewFd : A_File);
function ioTaskStdGet (TaskId : Interfaces.C.Int := 0;
StdFd : A_File) return A_File;
procedure ioTaskStdSet (TaskId : Interfaces.C.Int := 0;
StdFd : A_File;
NewFd : A_File);
private
pragma Import (C, Open, "open");
pragma Import (C, Close, "close");
pragma Import (C, ioGlobalStdGet, "ioGlobalStdGet");
pragma Import (C, ioGlobalStdSet, "ioGlobalStdSet");
pragma Import (C, ioTaskStdGet, "ioTaskStdGet");
pragma Import (C, ioTaskStdSet, "ioTaskStdSet");
end VxWorks.ioLib;
-- text.ads
------------
package Text is
procedure Send_Outputs_To_Null_Device;
procedure Return_Outputs_To_Standard_Devices;
end Text;
-- text.adb
------------
with Interfaces.C.Strings;
with VxWorks;
with VxWorks.ioLib;
package body Text is
Null_Device,
Standard_Output,
Standard_Error : VxWorks.ioLib.A_File;
procedure Send_Outputs_To_Null_Device is
use type VxWorks.ioLib.A_File;
begin
Null_Device := VxWorks.ioLib.Open (Name =>
Interfaces.C.Strings.New_String ("/null"),
Flags => VxWorks.ioLib.O_RDWR,
Mode => 0);
if Null_Device = VxWorks.Error then
return;
end if;
Standard_Output := VxWorks.ioLib.ioGlobalStdGet (StdFd =>
VxWorks.ioLib.STD_OUT);
Standard_Error := VxWorks.ioLib.ioGlobalStdGet (StdFd =>
VxWorks.ioLib.STD_ERR);
VxWorks.ioLib.ioGlobalStdSet (StdFd => VxWorks.ioLib.STD_OUT,
NewFd => Null_Device);
VxWorks.ioLib.ioGlobalStdSet (StdFd => VxWorks.ioLib.STD_ERR,
NewFd => Null_Device);
end Send_Outputs_To_Null_Device;
procedure Return_Outputs_To_Standard_Devices is
Status : VxWorks.A_Status;
begin
VxWorks.ioLib.ioGlobalStdSet (StdFd => VxWorks.ioLib.STD_OUT,
NewFd => Standard_Output);
VxWorks.ioLib.ioGlobalStdSet (StdFd => VxWorks.ioLib.STD_ERR,
NewFd => Standard_Error);
Status := VxWorks.ioLib.Close (File => Null_Device);
end Return_Outputs_To_Standard_Devices;
end Text;
-- test.adb
-----------
with Ada.Real_Time; use Ada.Real_Time;
with Ada.Text_IO; use Ada.Text_IO;
with Text;
procedure Test is
procedure Display (Item : String; Result : out Duration) is
Start_Time,
End_Time : Time;
begin
Start_Time := Clock;
for I in 1 .. 10_000 loop
Put (Item => Item);
end loop;
End_Time := Clock;
Result := To_Duration (TS => End_Time - Start_Time);
end Display;
Times : array (Natural range 1 .. 10) of Duration;
Test_String : constant String := "1234567890";
begin
Text.Send_Outputs_To_Null_Device;
for Index in Times'Range loop
Test (Item => Test_String (1 .. Index),
Result => Times (Index));
end loop;
Text.Return_Outputs_To_Standard_Devices;
for Index in Times'Range loop
Put_Line (Integer'Image (Index) & " Time =" & Duration'Image (Times
(Index)));
end loop;
end Display;
"Graham Baxter" <gba...@NOSPAM.bcs.org.uk> wrote in message
news:3AD42861...@NOSPAM.bcs.org.uk...
Mark
"Martin Dowie" <martin...@gecm.com> wrote in message
news:3ad59c42$1...@pull.gecm.com...
You can't set the "default" Text_IO output file to
two different files at the same time. However, you
could use the "Task Attribute" feature of Ada 95 to
give each task a File_Access attribute, and do all your
output through that. Then each task could have its own,
without having to explicitly pass it to every routine
under the sun.
>
> Frank
--
-Tucker Taft s...@avercom.net http://www.averstar.com/~stt/
Chief Technology Officer, AverCom Corporation (A Titan Company)
Burlington, MA USA (AverCom was formerly the Commercial Division of AverStar:
http://www.averstar.com/services/ebusiness_applications.html)