comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Elaboration code, aggregates
@ 2021-03-28 19:41  1% Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2021-03-28 19:41 UTC (permalink / raw)


In June 2020, Luke A. Guest was having trouble with getting the compiler
to place constant data into the data section without elaboration code.
https://groups.google.com/g/comp.lang.ada/c/B2NA-qjCJuM/m/4ykywZWZAgAJ

During preliminary work for FSF GCC 11, I found that this ARM interrupt
vector (which used to compile happily without needing elaboration code)
no longer would:
https://github.com/simonjwright/cortex-gnat-rts/blob/master/stm32f4/adainclude/startup.adb#L231

   Vectors : array (-14 .. Ada.Interrupts.Names.FPU_IRQ) of Handler :=
     (-9 .. -6 | -4 .. -3 => null,                      -- reserved
      -14                 => Dummy_Handler'Access,      -- NMI
      -13                 => HardFault_Handler'Access,  -- HardFault
      -12                 => Dummy_Handler'Access,      -- MemManagement
      -11                 => Dummy_Handler'Access,      -- BusFault
      -10                 => Dummy_Handler'Access,      -- UsageFault
      -5                  => SVC_Handler'Access,        -- SVCall
      -2                  => PendSV_Handler'Access,     -- PendSV
      -1                  => SysTick_Handler'Access,    -- SysTick
      others              => IRQ_Handler'Access)
     with
       Export,
       Convention         => Ada,
       External_Name      => "isr_vector";
   pragma Linker_Section (Vectors, ".isr_vector");

and Arduino Due clock startup ddn't:
https://github.com/simonjwright/cortex-gnat-rts/blob/master/arduino-due/adainclude/startup-set_up_clock.adb#L48

   PMC_Periph.CKGR_MOR := (KEY      => 16#37#,
                           MOSCXTEN => 1,     -- main crystal oscillator enable
                           MOSCRCEN => 1,     -- main on-chip rc osc. enable
                           MOSCXTST => 8,     -- startup time
                           others   => <>);

On investigating, it turns out that FSF GCC 11 **AND** GNAT CE 2020 have
lost the ability to assign aggregates as a whole; instead, they assign
the record components one-by-one.

The reason for the Arduino Due failure is that the PMC hardware requires
that each write to the CKGR_MOR register contain that value of KEY! so
the sequence is

read the register (KEY is always returned as 0)
overwrite the KEY field
write the register back
read the register, KEY is 0
overwrite the MOSCXTEN field
write the register back, KEY is 0 so inoperative
etc (including the 'others => <>' components).

Bug report raised:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99802

^ permalink raw reply	[relevance 1%]

* Re: Ada in command / control systems
  2019-02-26 22:10  0%             ` lyttlec
@ 2019-02-26 22:39  0%               ` Niklas Holsti
  0 siblings, 0 replies; 76+ results
From: Niklas Holsti @ 2019-02-26 22:39 UTC (permalink / raw)


On 19-02-27 00:10 , lyttlec wrote:
> On 2/26/19 10:50 AM, Simon Wright wrote:
>> "J-P. Rosen" <rosen@adalog.fr> writes:
>>
>>> Le 25/02/2019 à 20:21, russ lyttle a écrit :
>>
>>>> Some items need to be specified to be
>>>> allocated to EEPROM, some to RAM, etc.
>>> You can do that with address clauses.
>>
>> The compiler will straightforwardly distinguish between text, read-only,
>> read-write, and bss.
>>
>> If you need more, you can (GNAT) use pragma Linker_Section: for
>> interrupt vectors for an STM32F4,
>>
>>    Vectors : array (-14 .. Ada.Interrupts.Names.FPU_IRQ) of Handler :=
>>      (-9 .. -6 | -4 .. -3 => null,                      -- reserved
>>       -14                 => Dummy_Handler'Access,      -- NMI
>>       -13                 => HardFault_Handler'Access,  -- HardFault
>>       -12                 => Dummy_Handler'Access,      -- MemManagement
>>       -11                 => Dummy_Handler'Access,      -- BusFault
>>       -10                 => Dummy_Handler'Access,      -- UsageFault
>>       -5                  => SVC_Handler'Access,        -- SVCall
>>       -2                  => PendSV_Handler'Access,     -- PendSV
>>       -1                  => SysTick_Handler'Access,    -- SysTick
>>       others              => IRQ_Handler'Access)
>>      with
>>        Export,
>>        Convention         => Ada,
>>        External_Name      => "isr_vector";
>>    pragma Linker_Section (Vectors, ".isr_vector");
>>
>> and then use the linker script to place that section appropriately.
>>
> The "use linker script" part is where I am having difficulty with gnat
> targeting a PC. Haven't tried the STM32F4 yet.
> All I've found so far, including tutorial on AdaCore, apply only to
> Windows and produce errors in Linux.

Simon is talking about targeting embedded, bare metal platforms, where 
things like placing certain data or code in EEPROM, or at certain 
addresses, make sense. For an OS like Windows or Linux on a PC, usually 
there is no EEPROM (accessible to an application), and all special 
addreses (such as I/O control registers) are reserved for OS use.

> For example the  advice to  use
> "-Xlinker -Wl --stack = ..." is Windows only.

Yes, the way you set the stack size of the Ada environment task is 
different for each host OS (there was some discussion of this on 
comp.lang.ada a while ago, and it was agreed that a portable, standard 
method should be defined for Ada, such as using Pragma Storage_Size in 
the main subprogram).

For Linux, I believe the environment stack size is not set when linking 
the program, but through the shell "ulimit" command when starting the 
program.

> We may have to give up and switch back to using Makefile, which
> probably isn't such a bad idea anyway.

I don't see how a Makefile would help with the stack-size setting. It 
should be possible to pass all required command-line switches and 
arguments through GPS and gprbuild.

I would recommend using a Makefile only if you must run some other tools 
in connection with the build. If your build uses only gprbuild or 
gnatmake, stick with the GNAT project file, or just with the gnatmake 
environment variables (ADA_INCLUDE_PATH, ADA_OBJECTS_PATH).

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[relevance 0%]

* Re: Ada in command / control systems
  2019-02-26 15:50  1%           ` Simon Wright
@ 2019-02-26 22:10  0%             ` lyttlec
  2019-02-26 22:39  0%               ` Niklas Holsti
  0 siblings, 1 reply; 76+ results
From: lyttlec @ 2019-02-26 22:10 UTC (permalink / raw)


On 2/26/19 10:50 AM, Simon Wright wrote:
> "J-P. Rosen" <rosen@adalog.fr> writes:
> 
>> Le 25/02/2019 à 20:21, russ lyttle a écrit :
> 
>>> Some items need to be specified to be
>>> allocated to EEPROM, some to RAM, etc.
>> You can do that with address clauses.
> 
> The compiler will straightforwardly distinguish between text, read-only,
> read-write, and bss.
> 
> If you need more, you can (GNAT) use pragma Linker_Section: for
> interrupt vectors for an STM32F4,
> 
>    Vectors : array (-14 .. Ada.Interrupts.Names.FPU_IRQ) of Handler :=
>      (-9 .. -6 | -4 .. -3 => null,                      -- reserved
>       -14                 => Dummy_Handler'Access,      -- NMI
>       -13                 => HardFault_Handler'Access,  -- HardFault
>       -12                 => Dummy_Handler'Access,      -- MemManagement
>       -11                 => Dummy_Handler'Access,      -- BusFault
>       -10                 => Dummy_Handler'Access,      -- UsageFault
>       -5                  => SVC_Handler'Access,        -- SVCall
>       -2                  => PendSV_Handler'Access,     -- PendSV
>       -1                  => SysTick_Handler'Access,    -- SysTick
>       others              => IRQ_Handler'Access)
>      with
>        Export,
>        Convention         => Ada,
>        External_Name      => "isr_vector";
>    pragma Linker_Section (Vectors, ".isr_vector");
> 
> and then use the linker script to place that section appropriately.
> 
The "use linker script" part is where I am having difficulty with gnat
targeting a PC. Haven't tried the STM32F4 yet.
All I've found so far, including tutorial on AdaCore, apply only to
Windows and produce errors in Linux. For example the  advice to  use
"-Xlinker -Wl --stack = ..." is Windows only.
 We may have to give up and switch back to using Makefile, which
probably isn't such a bad idea anyway.


^ permalink raw reply	[relevance 0%]

* Re: Ada in command / control systems
  @ 2019-02-26 15:50  1%           ` Simon Wright
  2019-02-26 22:10  0%             ` lyttlec
  0 siblings, 1 reply; 76+ results
From: Simon Wright @ 2019-02-26 15:50 UTC (permalink / raw)


"J-P. Rosen" <rosen@adalog.fr> writes:

> Le 25/02/2019 à 20:21, russ lyttle a écrit :

>> Some items need to be specified to be
>> allocated to EEPROM, some to RAM, etc.
> You can do that with address clauses.

The compiler will straightforwardly distinguish between text, read-only,
read-write, and bss.

If you need more, you can (GNAT) use pragma Linker_Section: for
interrupt vectors for an STM32F4,

   Vectors : array (-14 .. Ada.Interrupts.Names.FPU_IRQ) of Handler :=
     (-9 .. -6 | -4 .. -3 => null,                      -- reserved
      -14                 => Dummy_Handler'Access,      -- NMI
      -13                 => HardFault_Handler'Access,  -- HardFault
      -12                 => Dummy_Handler'Access,      -- MemManagement
      -11                 => Dummy_Handler'Access,      -- BusFault
      -10                 => Dummy_Handler'Access,      -- UsageFault
      -5                  => SVC_Handler'Access,        -- SVCall
      -2                  => PendSV_Handler'Access,     -- PendSV
      -1                  => SysTick_Handler'Access,    -- SysTick
      others              => IRQ_Handler'Access)
     with
       Export,
       Convention         => Ada,
       External_Name      => "isr_vector";
   pragma Linker_Section (Vectors, ".isr_vector");

and then use the linker script to place that section appropriately.


^ permalink raw reply	[relevance 1%]

* Re: Ada.Interrpts.Names
  2019-01-29 13:09  1%   ` Ada.Interrpts.Names Simon Wright
@ 2019-01-29 14:31  1%     ` Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2019-01-29 14:31 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Your best bet, I'd've thought, would be to write a very simple program
> just to catch that signal (i.e. a PO interrupt handler) using the raw
> integer and see if it works. If it doesn't, you'd probably have a long
> row to hoe. If it does, you can consider whether it's worth the pain of
> editing Ada.Interrupts.Names, otherwise, in your code, (e.g.)
>
>    SIGRTMIN : constant Ada.Interrupts.Interrupt_ID := 42; -- or whatever

There may, of course, be some interaction of these signals with the Ada
RTS that explains why they're omitted from Ada.Interrupts.Names.


^ permalink raw reply	[relevance 1%]

* Re: Ada.Interrpts.Names
  @ 2019-01-29 13:09  1%   ` Simon Wright
  2019-01-29 14:31  1%     ` Ada.Interrpts.Names Simon Wright
  0 siblings, 1 reply; 76+ results
From: Simon Wright @ 2019-01-29 13:09 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> lyttlec <lyttlec@removegmail.com> writes:
>
>> Under Ubuntu Linux kill -l lists interrupts including SIGRTMIN and
>> SIGRTMAX. However, gnat a-intnam.ads does not have these, nor does the
>> Ada ARM toolchain. Is there a way to use these interrupts?
>
> Looks as though Interrupt_ID is visibly a numeric type, so you could
> just use the number (so long as it's less than (what on Darwin is)
> System.OS_Interface.Max_Interrupt). Whether the RTS will actually
> respond to the signal in a useful way is another matter. Again,
> System.OS_Interface should offer a clue.

Via mail (better to use the newsgroup!) you said

> I tried that and the program in Chap.4 of "Building Parallel,
> Embedded, and Real-Time Applications with Ada" compiles.  The question
> is whether or not that is the only thing required to get a meaningful
> response?
> The "C" process is quiet complex.
> In Ada it looks like it might be as simple as editing a-intnam.ads,
> s-osinte.ads, and s-linux.ads. Or a lot more complex, like the methods
> for AVR-Ada.

I don't know, because I don't run Linux as my main development
environment.

Your best bet, I'd've thought, would be to write a very simple program
just to catch that signal (i.e. a PO interrupt handler) using the raw
integer and see if it works. If it doesn't, you'd probably have a long
row to hoe. If it does, you can consider whether it's worth the pain of
editing Ada.Interrupts.Names, otherwise, in your code, (e.g.)

   SIGRTMIN : constant Ada.Interrupts.Interrupt_ID := 42; -- or whatever


^ permalink raw reply	[relevance 1%]

* Re: Ada.Real_Time.Time_Last
  @ 2017-11-19 10:50  1%                 ` Niklas Holsti
  0 siblings, 0 replies; 76+ results
From: Niklas Holsti @ 2017-11-19 10:50 UTC (permalink / raw)


On 17-11-19 00:20 , Robert A Duff wrote:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
>
>> For various reasons, the developers of the Ada language have seen fit to
>> define in the RM some standard, predefined types for which they have
>> wanted to state the nature of the type, but not its full definition. For
>> example, we have, in package System,
>>
>>    subtype Any_Priority is Integer range implementation-defined;
>
> Yes, and Any_Priority'Last is a static expression.

Hm, I found no explicit statement on that in the RM. I assume it follows 
from the pragma Pure in package System, yes? On the other hand, there is 
an explicit requirement that Default_Bit_Order be static (RM 13.7(35/2)).

> Would it be static in your proposal?

I guess so; in this example, the proposal would only move the actual 
range expression to the private part, so I assume pragma Pure would have 
the same effect (enforce staticness) in the full declaration of the 
semi-private type.

> Programmers need to know the priority range in order to
> write pragmas Priority.  So in what sense is this
> "private" information?

Do you write, unportably:

    pragma Priority (42);

or do you write, as I do:

    Background_Prio : constant Priority := Priority'First;
    One_Herz_Prio   : constant Priority := Background_Prio + 1;
    etc.

and then write

    pragma Priority (Background_Prio);
    etc.?

>> This would enable all discrete-type operations on the Item type, but
>> would hide (keep private) what sort of discrete type it is, as well as
>> the names of the enumeration literals, if it is implemented as an
>> enumerated type. The RM defines just such a type in Ada.Interrupts:
>>
>>    type Interrupt_Id is implementation-defined;
>>
>> with the explanation (RM C.3.2(13)) "The Interrupt_Id type is an
>> implementation-defined discrete type used to identify interrupts."
>
> If Interrupt_Id is an enumeration type (not true for GNAT), you don't
> want to hide the names of the interrupts from clients.  If there's a
> Gizmo_Device_Interrupt, then clients want to attach handlers to that  by
 > name.

The RM defines the package Ada.Interrupts.Names for that (RM C.3.2(26)); 
it contains a set of definitions of constant Interrupt_Id objects, where 
both the names and values of those objects are "implementation-defined". 
This proposal would not change that, but these constants would probably 
become deferred constants, with their actual values in a private part.

For sure, this proposal is not going to remove all 
"implementation-defined" text from the RM. In my mind, that is not the 
goal of the proposal; the goal is to give packages more control over the 
amount of information they publish about their private types. For 
example, I have had cases where I wanted to publish the ability to use a 
private type as an array index type, without revealing much more about 
the type. The RM is only a good source of examples of types which 
should, perhaps, be semi-private in this sense.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[relevance 1%]

* Interrupts & Ravenscar
@ 2017-10-12 15:16  2% Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2017-10-12 15:16 UTC (permalink / raw)


Interrupt handlers are specified as protected procedures, e.g.

   protected PO is
      ...
   private
      ...
      procedure Handler
      with Attach_Handler => Ada.Interrupts.Names.Foo_Interrupt;
   end PO;

declared at library level.

What should happen if I also write in the same partition

   protected Other_PO is
      ...
   private
      ...
      procedure Handler
      with Attach_Handler => Ada.Interrupts.Names.Foo_Interrupt;
   end Other_PO;

I'm specifically concerned with the Ravenscar profile. My
cortex-gnat-rts raises PE when the second PO is initialized; AdaCore's
ravenscar-full-stm32f4 doesn't - last in wins.

I found this because an AdaCore library had already declared a handler
for a particular interrupt, and I needed to implement my own
behaviour. In this case, I could ensure that my handler was used by the
proper elaboration pragmas. In other circumstances, e.g. attaching the
wrong interrupt, there might be long and tedious debugging sessions.

The ARM doesn't address this issue (aside from it being illegal in
Ravenscar to use any subprogram from Ada.Interrupts, which means that
the only control you have is via the elaboration order).

I would like to see PE being raised; would this be a suitable candidate
for an implementation restriction?


^ permalink raw reply	[relevance 2%]

* how to use "in out" for the "self" parameter in a function in a protected object?
@ 2017-09-16 20:47  2% Frank Buss
  0 siblings, 0 replies; 76+ results
From: Frank Buss @ 2017-09-16 20:47 UTC (permalink / raw)


I have a function in a protected object, which needs to change a 
variable, but I get this error:

   actual for "Self" must be a variable

I assume the reason is, that the implicit "self" parameter for my 
function is declared as "in" and not "in out". How can I change it to 
"in out"?

Below is the code. The function "Available" for example works, but the 
function "Read" causes the error when compiling. Both are accessing the 
FIFO variable, "Available" only with a call where the variable is used 
as an "in" parameter, but for "Read" I call a function where it is 
passed as an "in out" parameter.


with Interfaces; use Interfaces;
with Ada.Interrupts; use Ada.Interrupts;
with Ada.Interrupts.Names; use Ada.Interrupts.Names;
with STM32.USARTs; use STM32.USARTs;
with Ringbuffers;

package Serial_IO is

    package FIFO_Package is new Ringbuffers(256, Unsigned_8);
    subtype FIFO is FIFO_Package.Ringbuffer;

    protected type Serial_Port_Controller
    is

       procedure Init (Baud_Rate: Baud_Rates);

       function Available return Boolean;

       function Read return Unsigned_8;

       procedure Write (Data : Unsigned_8);

    private
       procedure Interrupt_Handler;
       pragma Attach_Handler (Interrupt_Handler, USART1_Interrupt);

       Input : FIFO;
       Output: FIFO;
       Initialized : Boolean := False;
    end Serial_Port_Controller;

    Serial : Serial_Port_Controller;

end Serial_IO;





-- 
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss

^ permalink raw reply	[relevance 2%]

* Re: Precondition on protected entry
  2016-10-11 17:02  1% Precondition on protected entry Simon Wright
@ 2016-10-12 16:07  2% ` Stephen Leake
  0 siblings, 0 replies; 76+ results
From: Stephen Leake @ 2016-10-12 16:07 UTC (permalink / raw)


On Tuesday, October 11, 2016 at 3:29:47 PM UTC-5, Simon Wright wrote:
> I have this (Ravenscar, STM32F4) code:
> 

I modified it slightly to compile with Windows GNAT GPL 2016:

with Ada.Interrupts.Names;
with System;
package Timer_Handler is
   protected Timer_Handler
   with Interrupt_Priority => System.Interrupt_Priority'Last
   is
      entry Wait
      with Pre => Running;
      procedure Start_Waiting (For_Interval : Duration)
      with Pre => For_Interval <= 0.010_000 and not Running;
      function Running return Boolean;
   private
      procedure Handler
      with
        Attach_Handler => Ada.Interrupts.Names.SIGFPE;
      Triggered : Boolean := False;
      Is_Running : Boolean := False;
   end Timer_Handler;
end Timer_Handler;

package body Timer_Handler is

   protected body Timer_Handler is

      entry Wait
        when Standard.True
      is
      begin
         null;
      end Wait;

      procedure Start_Waiting
        (For_Interval : Duration)
      is
      begin
         null;
      end Start_Waiting;

      function Running return Boolean is
      begin
         return Is_Running;
      end Running;

      procedure Handler
      is
      begin
         null;
      end Handler;

   end Timer_Handler;

end Timer_Handler;
 
gnatmake timer_handler.adb

no errors.

So this looks like a problem with the cross target only?

^ permalink raw reply	[relevance 2%]

* Precondition on protected entry
@ 2016-10-11 17:02  1% Simon Wright
  2016-10-12 16:07  2% ` Stephen Leake
  0 siblings, 1 reply; 76+ results
From: Simon Wright @ 2016-10-11 17:02 UTC (permalink / raw)


I have this (Ravenscar, STM32F4) code:

   protected Timer_Handler
   with Interrupt_Priority => System.Interrupt_Priority'Last - 1
   is
      entry Wait
      with Pre => Running;
      procedure Start_Waiting (For_Interval : Duration)
      with Pre => For_Interval <= 0.010_000 and not Running;
      function Running return Boolean;
   private
      procedure Handler
      with
        Attach_Handler => Ada.Interrupts.Names.TIM8_TRG_COM_TIM14_Interrupt;
      Triggered : Boolean := False;
      Is_Running : Boolean := False;
   end Timer_Handler;

and GNAT GPL 2016 says

    19.    protected Timer_Handler
    20.    with Interrupt_Priority => System.Interrupt_Priority'Last - 1
    21.    is
    22.       entry Wait
    23.       with Pre => Running;
                          |
        >>> "Running" is undefined

Is this a compiler bug, or is there something in e.g. ARM 6.1.1 that
I've missed?

^ permalink raw reply	[relevance 1%]

* GNAT bug with protected procedure interrupt handler
@ 2016-06-25  2:40  1% Daniel King
  0 siblings, 0 replies; 76+ results
From: Daniel King @ 2016-06-25  2:40 UTC (permalink / raw)


I'm working on a project using GNAT GPL 2016 and AdaCore's ravenscar-sfp-stm32f4 runtime and I am encountering GNAT bugs when using the Attach_Handler aspect/pragma on a protected procedure.

More specifically, given the following (trivial) code:

    with Ada.Interrupts.Names;
    with System;

    package IRQ_Test
    is
       protected type IRQ_Test_Type
       is
          procedure Handle_IRQ
            with Attach_Handler => Ada.Interrupts.Names.RTC_Interrupt;
       end IRQ_Test_Type;
    end IRQ_Test;

I encounter the following GNAT bug message:

    +===========================GNAT BUG DETECTED==============================+
    | GPL 2016 (20160515-49) (arm-eabi) Program_Error sem_type.adb:814 explicit raise|
    | Error detected at irq_test.ads:6:4                                       |
    | Please submit a bug report by email to report@adacore.com.               |
    | GAP members can alternatively use GNAT Tracker:                          |
    | http://www.adacore.com/ section 'send a report'.                         |
    | See gnatinfo.txt for full info on procedure for submitting bugs.         |
    | Use a subject line meaningful to you and us to track the bug.            |
    | Include the entire contents of this bug box in the report.               |
    | Include the exact command that you entered.                              |
    | Also include sources listed below.                                       |
    | Use plain ASCII or MIME attachment(s).                                   |
    +==========================================================================+

    Please include these source files with error report
    Note that list may not be accurate in some cases,
    so please double check that the problem can still
    be reproduced with the set of files listed.
    Consider also -gnatd.n switch (see debug.adb).

    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/arch/system.ads
    /home/dan/projects/ada/stm32test/irq_test.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/ada.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/a-interr.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-interr.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-taskin.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/a-unccon.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/s-stoele.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/s-parame.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-tasinf.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-taspri.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-osinte.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-multip.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/s-bb.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-arch/s-bbpara.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/interfac.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/bsp/i-stm32.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/bsp/i-stm32-rcc.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/i-bit_types.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/bsp/s-stm32.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/bsp/s-bbbopa.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/bsp/s-bbmcpa.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/bsp/i-stm32-pwr.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-bbthre.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-bbcppr.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-bbtime.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-bbinte.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-bcprmu.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-bbthqu.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-bbbosu.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-taprob.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-mufalo.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-musplo.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/s-tposen.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-common/a-taside.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/gnarl-bsp/a-intnam.ads
    /usr/gnat/arm-eabi/lib/gnat/ravenscar-sfp-stm32f4/common/s-unstyp.ads

If I omit the Attach_Handler line on my original example then there are no errors.

Has anyone else seen this problem, or are able to reproduce it? Have you found a workaround?

Daniel


^ permalink raw reply	[relevance 1%]

* ANN: Cortex GNAT RTS 20160522
@ 2016-05-22 14:20  1% Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2016-05-22 14:20 UTC (permalink / raw)


Available at
https://sourceforge.net/projects/cortex-gnat-rts/files/20160522/

This release includes GNAT Ada Run Time Systems (RTSs) based
on FreeRTOS (http://www.freertos.org) and targeted at boards with
Cortex-M3, -M4, -M4F MCUs (Arduino Due from http://www.arduino.org,
the STM32F4-series evaluation boards from STMicroelectronics at
http://www.st.com).

In each case, the board support for the RTS (configuration for size
and location of Flash, RAM; clock initialization; interrupt naming) is
in $RTS/adainclude. Support for the on-chip peripherals is also
included, in Ada spec files generated by SVD2Ada
(https://github.com/AdaCore/svd2ada).

The Ada source is either original or based on FSF GCC (mainly 4.9.1,
some later releases too).

(1) arduino-due is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the Arduino Due.

    See arduino-due/COPYING* for licensing terms.

    On-chip peripheral support in atsam3x8e/.

    Tests in test-arduino-due/.

(2) stm32f4 is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F4-DISC* board.

    See stm32f4/COPYING* for licensing terms.

    On-chip peripheral support in stm32f40x/.

    Tests in test-stm32f4/.

(3) stm32f429i is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F429I-DISC* board.

    See stm32f429i/COPYING* for licensing terms.

    On-chip peripheral support in stm32f429x/.

    Tests in test-stm32f429i/.

In this release,

* There is no longer any dependence on the STMicroelectronics'
  STM32Cube package.

* The support for on-chip peripherals is limited to the
  SVD2Ada-generated spec files. The AdaCore 'bareboard' software
  (currently https://github.com/AdaCore/bareboard, but a name change
  is under consideration) supports the STM32 line.

* Tasking no longer requires an explicit start
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/5/).

* Locking in interrupt-handling protected objects no longer inhibits
  all interrupts, only those of equal or lower priority
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/18/).

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 1%]

* ANN: Cortex GNAT RTS 20160314
@ 2016-03-14 17:42  1% Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2016-03-14 17:42 UTC (permalink / raw)


At https://sourceforge.net/projects/cortex-gnat-rts/files/20160314/.

This release includes

* an RTS for the Arduino Due, arduino-due, and a minimal BSP,
  arduino-due-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i-disco-rtos, based on
  STMicroelectronics' STM32Cube package and FreeRTOS, and a
  corresponding partial BSP, stm32f429i-disco-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i, based on FreeRTOS, with
  a set of peripheral definition packages created by SVD2Ada.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 1%]

* ANN: Cortex GNAT RTS 20160207
@ 2016-02-07 22:45  1% Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2016-02-07 22:45 UTC (permalink / raw)


This release is at Sourceforge[1].

This release includes an RTS for the Arduino Due, arduino-due, and a
minimal BSP, arduino-due-bsp.

For the STM32F429I-DISCO, there is one RTS, stm32f429i-disco-rtos, and
one BSP, stm32f429i-disco-bsp.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

* FreeRTOS is configured to detect stack overflow (if it is detected,
  the RTS loops inside vApplicationStackOverflowHook()).

The standard packages included (there are more,
implementation-specific, ones) are:

   Ada
   Ada.Containers
   Ada.Containers.Bounded_Hashed_Maps
   Ada.Containers.Bounded_Vectors
   Ada.Exceptions
   Ada.IO_Exceptions
   Ada.Interrupts
   Ada.Interrupts.Names
   Ada.Iterator_Interfaces
   Ada.Real_Time
   Ada.Streams
   Ada.Synchronous_Task_Control
   Ada.Tags
   Ada.Task_Identification
   Interfaces
   Interfaces.C
   Interfaces.C.Strings
   System
   System.Assertions
   System.Address_To_Access_Conversions
   System.Storage_Elements
   GNAT
   GNAT.Source_Info

The software is supplied built with for debugging (-g) and with suitable
optimisation (-Og), using GNAT GPL 2015 on Mac OS X (it should work
out of the box with a Linux-hosted GNAT GPL 2015 cross-compiler, but
will need recompiling for another compiler version).

[1] https://sourceforge.net/projects/cortex-gnat-rts/files/20160207/


^ permalink raw reply	[relevance 1%]

* Re: GNAT GPL 2015 Troubles
  2015-06-23 14:07  0%           ` Stephen Leake
@ 2015-06-23 17:07  0%             ` Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2015-06-23 17:07 UTC (permalink / raw)


Stephen Leake <stephen_leake@stephe-leake.org> writes:

> Simon Wright <simon@pushface.org> writes:
>
>> "RasikaSrinivasan@gmail.com" <RasikaSrinivasan@gmail.com> writes:
>>
>>> navigation did not work for me. i browsed and found the files but it
>>> is not ideal. A strong vote for your point about use clauses as well.
>>
>> For RTS components (e.g. Ada.Interrupts.Names.EXTI0_IRQ) I end up in the
>> native RTS. In spite of having the correct GPR loaded.
>
> "gnat list" is used to get the system library; testing with GNAT GPL
> 2014:
>
> with a project file foo.gpr containing
>
>    package Builder is
>       for Default_Switches ("ada") use ("--RTS=sjlj");
>    end Builder;
>
> 'gnat list -v -P foo.gpr' returns the wrong system library.
>
> 'gnat list -v --RTS=sjlj' returns the correct system library.
>
> So the solution is to change gnat-core.el gnat-get-paths-1 to pass
> --RTS=... to 'gnat list', but in a general way.
>
> We could add a project variable 'runtime' (or 'rts'?), with default
> value "zcx".
>
> The gnat tools don't accept --RTS=zcx (at least not with a default
> install), so we have to check for that special case at each use.

Given AdaCore's intention to stop gnat make supporting projects, I
suppose it's hardly surprising that gnat list doesn't understand the
full syntax of projects.

GCC 5.1.0 and GNAT GPL 2015 behave the same way as you report.

I'd prefer 'runtime' (or 'rts') to have default value nil. Or am I
thinking of the corresponding elisp custom setting?

^ permalink raw reply	[relevance 0%]

* Re: GNAT GPL 2015 Troubles
  2015-06-21 16:21  1%         ` Simon Wright
@ 2015-06-23 14:07  0%           ` Stephen Leake
  2015-06-23 17:07  0%             ` Simon Wright
  0 siblings, 1 reply; 76+ results
From: Stephen Leake @ 2015-06-23 14:07 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> "RasikaSrinivasan@gmail.com" <RasikaSrinivasan@gmail.com> writes:
>
>> navigation did not work for me. i browsed and found the files but it
>> is not ideal. A strong vote for your point about use clauses as well.
>
> For RTS components (e.g. Ada.Interrupts.Names.EXTI0_IRQ) I end up in the
> native RTS. In spite of having the correct GPR loaded.

"gnat list" is used to get the system library; testing with GNAT GPL
2014:

with a project file foo.gpr containing

   package Builder is
      for Default_Switches ("ada") use ("--RTS=sjlj");
   end Builder;

'gnat list -v -P foo.gpr' returns the wrong system library.

'gnat list -v --RTS=sjlj' returns the correct system library.

So the solution is to change gnat-core.el gnat-get-paths-1 to pass
--RTS=... to 'gnat list', but in a general way.

We could add a project variable 'runtime' (or 'rts'?), with default
value "zcx".

The gnat tools don't accept --RTS=zcx (at least not with a default
install), so we have to check for that special case at each use.


-- 
-- Stephe

^ permalink raw reply	[relevance 0%]

* Re: GNAT GPL 2015 Troubles
  @ 2015-06-21 16:21  1%         ` Simon Wright
  2015-06-23 14:07  0%           ` Stephen Leake
  0 siblings, 1 reply; 76+ results
From: Simon Wright @ 2015-06-21 16:21 UTC (permalink / raw)


"RasikaSrinivasan@gmail.com" <RasikaSrinivasan@gmail.com> writes:

> navigation did not work for me. i browsed and found the files but it
> is not ideal. A strong vote for your point about use clauses as well.

For RTS components (e.g. Ada.Interrupts.Names.EXTI0_IRQ) I end up in the
native RTS. In spite of having the correct GPR loaded.

> Simon Another question - do you have any examples that work with AHB2?
> i am not able get the AHB2 peripherals to work at all.

No, only AHB1, sorry. Aside from RCC, that is, and I'm only using the
STM32Cube interface for that.

> also - is there a way you can write up the process of setting up a zfp
> for say TMSC123 or some other such Cortex core?

ZFP should be easy enough per se, the problem would be the board setup
and clock configuration; the clock configuration seems to be
manufacturer-specific?

Would Maciej's book help?

http://www.lulu.com/shop/maciej-sobczak/ada-and-spark-on-arm-cortex-m/paperback/product-22195745.html
http://inspirel.com/articles/Ada_On_Cortex.html


^ permalink raw reply	[relevance 1%]

* GNAT GPL 2015 Troubles
@ 2015-06-20 18:38  1% RasikaSrinivasan
    0 siblings, 1 reply; 76+ results
From: RasikaSrinivasan @ 2015-06-20 18:38 UTC (permalink / raw)


all

I upgrade my gnat to GPL 2015 on windows. I use both the Windows native version as well as the ARM elf hosted on Windows. gnat GPL 2014 worked just fine in this configuration except for some minor issues. 

Several things are no longer working for me and I am at a loss to find the best way to fix it:

a. Used to be able to ask GPS for help with predefined packages like so :

   From GPS, Help \ GNAT runtime \ Ada \ Text_io 

     - this would give me the spec for the package and I could browse the spec

   I am no longer able to do this. In particular this is a problem for
   packages like Ada.Interrupts.Names 

b. It would appear that intellisense for predefined packages don't work anymore.

c. I don't have to specify the location of the profile for ARM targets (this is great) but I am not sure which profile the system is using. browsing the directories there appear to be 2 ravenscar profiles being installed.

Seeking some pointers on any of the above.

thanks, srini


^ permalink raw reply	[relevance 1%]

* Re: longest path through a task
  2015-05-28 17:52  1%         ` Simon Wright
@ 2015-05-28 18:12  0%           ` jan.de.kruyf
  0 siblings, 0 replies; 76+ results
From: jan.de.kruyf @ 2015-05-28 18:12 UTC (permalink / raw)


On Thursday, May 28, 2015 at 7:52:55 PM UTC+2, Simon Wright wrote:

> 
> I have been accused of terseness, sorry

It is an occupational disease, ask my wife.


> This is a Ravenscar runtime; the C interrupt handler has to invoke the
> Ada handler, which was registered by the Ada runtime when it saw a PO
> like
> 
>    protected Button
>    with
>      Interrupt_Priority => System.Interrupt_Priority'First
>    is
>       entry Wait_For_Trigger;
>    private
>       Triggered : Boolean := False;
>       procedure Handler;
>       pragma Attach_Handler (Handler, Ada.Interrupts.Names.EXTI0_IRQ);
>    end Button;
> 
> and I started timing in Button.Handler.
> 
> The corresponding task called Button.Wait_For_Trigger and I ended timing
> immediately on return.

Thanks, I think I remember coming to 5 usecs from glancing through the code, so it is even worse than that.

According to the gnat ravenscar profile they need that extra code layer to do things with locks and threads, but I could not tell you what anymore. I just cut my losses as explained above.

Here is the link to Matteo's page with the research papers on the subject.

http://inf.ethz.ch/personal/corti/

cheers,

j.



^ permalink raw reply	[relevance 0%]

* Re: longest path through a task
  @ 2015-05-28 17:52  1%         ` Simon Wright
  2015-05-28 18:12  0%           ` jan.de.kruyf
  0 siblings, 1 reply; 76+ results
From: Simon Wright @ 2015-05-28 17:52 UTC (permalink / raw)


jan.de.kruyf@gmail.com writes:

> On Thursday, May 28, 2015 at 6:37:28 PM UTC+2, Simon Wright wrote:
>
>> 
>> > I dumped the multithread stuff and made a single-thread / multitask
>> > runtime (slow in Ada unfortunately, but not as slow as multi-threading
>> > and interrupts. The Ravenscar runtime tries to be everything for
>> > everybody).
>> 
>> Just did some measurements (clumsily) using the Cortex-M4 counter as in
>> [1], and from entering the Ada handler to the triggered task starting to
>> execute averaged at 1200 cycles (6.7 us) with -Og, 1070 cycles (5.9 us)
>> with -O2. There is some code in the C handler to redirect to the Ada
>> handler: see [2], starting at line 236.
>> 
>> I wrote the C handling using weak symbols, so there's no reason (that I
>> can see) why an interrupt that needed better performance shouldn't hook
>> in directly, avoiding the Ada RTS; not so obvious how it would then
>> communicate with the rest of the code.
>> 
>> [1] http://stackoverflow.com/a/19124472
>> [2]
>> https://sourceforge.net/p/stm32f4-gnat-rts/code/ci/default/tree/stm32f429i-disco-rtos/src/stm32f4xx_it.c
>
> I lost you a bit here Simon, your thinking is way ahead of your
> fingers :) I guess. or I am not familiar with your terminology. (more
> than likely)

I have been accused of terseness, sorry

> Is this interrupt latency? or software interrupt latency? 
> Are you running multi threaded? are you triggering a task in this
> thread to run in that thread?
> Is this including your C runtime?

This is a Ravenscar runtime; the C interrupt handler has to invoke the
Ada handler, which was registered by the Ada runtime when it saw a PO
like

   protected Button
   with
     Interrupt_Priority => System.Interrupt_Priority'First
   is
      entry Wait_For_Trigger;
   private
      Triggered : Boolean := False;
      procedure Handler;
      pragma Attach_Handler (Handler, Ada.Interrupts.Names.EXTI0_IRQ);
   end Button;

and I started timing in Button.Handler.

The corresponding task called Button.Wait_For_Trigger and I ended timing
immediately on return.

^ permalink raw reply	[relevance 1%]

* Re: GNAT stm34f4 zfp question.
  @ 2015-03-18 17:58  1%         ` Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2015-03-18 17:58 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> And even then I'm concerned about multiplexed GPIO interrupts; as I
> understand it, there is only one EXTI0 interrupt, corresponding to pin
> 0 on any GPIO, so if you need more than one pin 0 interrupt you'll
> need to manage all of them in one super-handler, or arrange to chain
> handlers (which I don't think AdaCore's RTS supports??)

Somewhat clearer about this now!

There are 16 GPIO-related interrupt lines, corresponding to the 16 bits
in a GPIO register.

Each line is associated with one GPIO (the default is GPIOA).

Each line can have interrupts enabled (and/or events???)

Lines 0..4 have their own interrupts, EXTI0_IRQ to EXTI4_IRQ.

Lines 5..9 are multiplexed to one interrupt, EXTI9_5_IRQ.

Lines 10..15 are multiplexed to one interrupt, EXTI15_10_IRQ.

So pin PC11 (GPIOC, bit 11), which is one of the unassigned pins on the
STM32F429I Disco, can be interrupt-enabled (in which case no other
GPIO's pin 11 can be interrupt-enabled) and will generate
EXTI15_10_IRQ. If interrupts are required on lines 10, 12, 13, 14, or 15
(which can each be associated with different GPIOs) then the handler for
EXTI15_10_IRQ will have to determine which is which.

At the moment I'm toying with mechanical translation of the STMCube
stm32f429xx.h (using -fdump-ada-spec and a sed script), and have the
code below, which is fairly ugly, rather like the C equivalent. I could
copy AdaCore's design (not the code, of course!) which handles multi-bit
fields much better, but I'm looking for a mechanical translation at this
stage.

with Ada.Interrupts.Names;
with Interfaces;
with System;
with stm32f429xx_h; use stm32f429xx_h;
package body Button is

   --  We're going to use a pin on the left-hand side of the board:
   --  P1/44 is PC11.

   protected B
   with
     Interrupt_Priority => System.Interrupt_Priority'First is
      entry Wait_For_Trigger;
   private
      Triggered : Boolean := False;
      procedure Handler;
      pragma Attach_Handler (Handler, Ada.Interrupts.Names.EXTI15_10_IRQ);
   end B;

   procedure Wait_For_Button_Release is
   begin
      B.Wait_For_Trigger;
   end Wait_For_Button_Release;

   protected body B is
      entry Wait_For_Trigger when Triggered is
      begin
         Triggered := False;
      end Wait_For_Trigger;

      procedure Handler is
         use type Interfaces.Unsigned_32;
      begin
         if (EXTI.PR and EXTI_PR_PR11) /= 0 then
            Triggered := True;
            EXTI.PR := EXTI_PR_PR11;  -- clear the interrupt by *writing* 1
         else
            raise Program_Error with "unexpected interrupt";
         end if;
      end Handler;
   end B;

   procedure Initialize is
      use type Interfaces.Unsigned_32;
   begin
      --  First, we need to enable GPIOC's clock.
      RCC.AHB1ENR := RCC.AHB1ENR or RCC_AHB1ENR_GPIOCEN;

      --  Don't need to configure bit 11 as an input, because that's
      --  the default.

      --  Don't need to configure OTYPER, because the pin is an input.

      --  Don't need to configure OSPEEDR, because the pin is an input.

      --  Configure PUPDR for pull-up (AdaCore have no-pull?)
      declare
         Pull_Register : Interfaces.Unsigned_32;
      begin
         Pull_Register := GPIOC.PUPDR;
         Pull_Register := Pull_Register and not GPIO_PUPDR_PUPDR11;
         Pull_Register := Pull_Register or GPIO_PUPDR_PUPDR11_0;
         GPIOC.PUPDR := Pull_Register;
      end;

      --  Enable SYSCFG's clock.
      RCC.APB2ENR := RCC.APB2ENR or RCC_APB2ENR_SYSCFGEN;

      --  Then, configure SYSCFG_EXTICR3[12:15] (pin 11) for GPIOC.
      declare
         Exti_Register : Interfaces.Unsigned_32;
      begin
         Exti_Register := SYSCFG.EXTICR (2);  -- C indexing!
         Exti_Register := Exti_Register and not SYSCFG_EXTICR3_EXTI11;
         Exti_Register := Exti_Register or SYSCFG_EXTICR3_EXTI11_PC;
         SYSCFG.EXTICR (2) := Exti_Register;
      end;

      --  Then, configure EXTI on pin 11 for rising-edge (button-release)
      EXTI.RTSR := EXTI.RTSR or EXTI_RTSR_TR11;
      --  and enable interrupts on pin 11.
      EXTI.IMR := EXTI.IMR or EXTI_IMR_MR11;
   end Initialize;

begin
   Initialize;
end Button;


^ permalink raw reply	[relevance 1%]

* Re: gnat ARM - predefined packages
  @ 2015-01-28 17:30  1%                 ` RasikaSrinivasan
  0 siblings, 0 replies; 76+ results
From: RasikaSrinivasan @ 2015-01-28 17:30 UTC (permalink / raw)


Eventually I found the file (spec for Ada.Interrupts.Names) on my system. It is not in the directory tree where I usually expect. There is a dir called "gnat" in the tree and there is an adainclude and adalib under that. This is where I found the RTS and the specific file.

I don't have the exact dir spec now but I can dig it up later in the night.

It would appear that several other such commands also search in the wrong places. For example the pretty print command from GPS did not work because it could not locate several required specs. (I had with'ed Ada.Real_Time). 

I suspect this will work better with the next GPL version - as indicated in the reply I received from adacore.

cheers, srini

^ permalink raw reply	[relevance 1%]

* Re: gnat ARM - predefined packages
  2015-01-27 16:09  2% gnat ARM - predefined packages RasikaSrinivasan
  2015-01-27 16:49  0% ` Bob Duff
@ 2015-01-27 16:49  0% ` Simon Wright
    1 sibling, 1 reply; 76+ results
From: Simon Wright @ 2015-01-27 16:49 UTC (permalink / raw)


"RasikaSrinivasan@gmail.com" <RasikaSrinivasan@gmail.com> writes:

> Some clarifications please:
>
> I am using gnat for ARM - having reasonable success with the STM32F4
> discovery board.

There's the RTS that AdaCore provide with their cross compiler, which
includes packages like STM32F4.GPIO, and the RTS that I've been working
on. I think you're using the former.

> I would like to know:
>
> - The example project contains an import as follows:
>
> -- file: registers.ads
>     GPIOD : GPIO_Register with ... ;
>     pragma Import(Ada,GPIOD) ;
>
>     where is this object GPIOD getting imported from?

The actual code is

   GPIOD : GPIO_Register with
     Volatile,
     Address => System'To_Address (GPIOD_Base);
   pragma Import (Ada, GPIOD);

(GPIO_Register comes from package STM32F4.GPIO: I'm surprised that
AdaCore use 'use' like this, it's quite unnecessary here).

The point of the pragma Import is to prevent any initialization that the
compiler might do on the object. I don't think that there is any in this
case, but consider an access variable: the default initialization is to
set it to null, which you certainly don't want to do to a hardware
register unless you ask for it.

>     I am looking to use GPIOB and GPIOC. how can i import those?

exactly as GPIOD; the corresponding _Base declarations are in package
STM32F4.

> - the spec of Ada.Interrupts.Names so I know how to attach new
> interrupt handlers. (Example project provides
> Ada.Interrupts.Names.EXTIO_Interrrupt)

This is a-intnam.ads in your RTS's adainclude/ directory.

If you're looking at AdaCore's RTS, there's an _extremely_ misleading
comment about Interrupt_ID 0 being reserved (well, I was misled; it
probably doesn't matter to you).

> - Is it possible to install native gnat on the same Windows system and
> produce executables for both the native and the ARM targets?

I can't speak for GNAT GPL on Windows, but it would be completely normal
to have the native compiler installed first, then install the
cross-compiler on top of it (THEY MUST BE THE SAME VERSION). In fact
don't you need to? does the cross compiler include all the tools,
e.g. gprbuild, GPS?

> - Is it possible to use packages such as Ada.Containers in the
> embedded target?

Probably not; the AdaCore RTS doesn't support controlled types, my RTS
doesn't (yet) include controlled types or allocators or streams, nor
does it allow dispatching (so no classwide types).

^ permalink raw reply	[relevance 0%]

* Re: gnat ARM - predefined packages
  2015-01-27 16:09  2% gnat ARM - predefined packages RasikaSrinivasan
@ 2015-01-27 16:49  0% ` Bob Duff
  2015-01-27 16:49  0% ` Simon Wright
  1 sibling, 0 replies; 76+ results
From: Bob Duff @ 2015-01-27 16:49 UTC (permalink / raw)


"RasikaSrinivasan@gmail.com" <RasikaSrinivasan@gmail.com> writes:

> - the spec of Ada.Interrupts.Names so I know how to attach new interrupt
> handlers. (Example project provides Ada.Interrupts.Names.EXTIO_Interrrupt)

Look at the file a-intnam.ads in the adainclude directory of your
compiler installation.  For example, on my native linux machine,
I have lib/gcc/x86_64-pc-linux-gnu/4.9.3/adainclude/a-intnam.ads.
Yours will have a similar-but-different name.

> - Is it possible to install native gnat on the same Windows system and produce
> executables for both the native and the ARM targets?

Yes, you can install as many versions of GNAT as you like.

- Bob

^ permalink raw reply	[relevance 0%]

* gnat ARM - predefined packages
@ 2015-01-27 16:09  2% RasikaSrinivasan
  2015-01-27 16:49  0% ` Bob Duff
  2015-01-27 16:49  0% ` Simon Wright
  0 siblings, 2 replies; 76+ results
From: RasikaSrinivasan @ 2015-01-27 16:09 UTC (permalink / raw)


Some clarifications please:

I am using gnat for ARM - having reasonable success with the STM32F4 discovery board.

I would like to know:

- The example project contains an import as follows:

-- file: registers.ads
    GPIOD : GPIO_Register with ... ;
    pragma Imp\x10oft(Ada,GP\x10IOD) ;

    where is this object GPIOD getting imported from?
    I am looking to use GPIOB and GPIOC. how can i import those?
   
- the spec of Ada.Interrupts.Names so I know how to attach new interrupt handlers. (Example project provides Ada.Interrupts.Names.EXTIO_Interrrupt)

- Is it possible to install native gnat on the same Windows system and produce executables for both the native and the ARM targets?

- Is it possible to use packages such as Ada.Containers in the embedded target?

thanks for pointers.

srini


^ permalink raw reply	[relevance 2%]

* Use of expression function in protected type
@ 2015-01-20 22:34  1% Simon Wright
  0 siblings, 0 replies; 76+ results
From: Simon Wright @ 2015-01-20 22:34 UTC (permalink / raw)


Is it permissible to use an expression function as the completion of a
protected function? (GNAT thinks so).

   protected Button
   is
      function Current_Index return Interval_Index;
   private
      Index : Interval_Index := 0;
      procedure Handler;
      pragma Attach_Handler (Handler, Ada.Interrupts.Names.EXTI0_IRQ);
   end Button;

and then

   protected body Button is
      function Current_Index return Interval_Index is (Index); -- <<<<<<<<
      procedure Handler is
      begin
         HAL_GPIO_EXTI_IRQHandler (16#0001#);
         Index := Index + 1;
      end Handler;
   end Button;

ARM 6.1(30) distinguishes an expression_function_declaration from a
subprogram_declaration.

6.8(4) allows an expression_function_declaration to be a completion.

9.4(8) says a protected_operation_item can be, inter alia, a
subprogram_declaration or a subprogram body. (subprogram_declaration?
how can that be?)

^ permalink raw reply	[relevance 1%]

* Re: ACCESS TO SYSTEM VARIABLES
  @ 2011-03-09 18:59  2%         ` Emile8
  0 siblings, 0 replies; 76+ results
From: Emile8 @ 2011-03-09 18:59 UTC (permalink / raw)


On 8 mar, 18:13, Emile8 <pocchiola.y...@gmail.com> wrote:
> On 7 mar, 22:32, "Peter C. Chapin" <PCha...@vtc.vsc.edu> wrote:
>
> > On Mon, 7 Mar 2011, Emile8 wrote:
> > > It is not a very elegant solution and I should look also at how the
> > > Ada version of ncurses manages to get the same informations.
>
> > When the terminal is resized the programs running in it receive a Unix
> > signal (SIGWINCH?). By default that signal is ignored. However, one can
> > install a signal handler for it and then presumably call into the system
> > (some terminal API) to ask for the new sizes.
>
> > I could probably figure out how to do this in C, but I'm not familiar with
> > how Ada on Unix deals with Unix signals.
>
> > Peter
>
> You are right, the approach by a user handler attached to the relevant
> UNIX signal is certainly the good approach to cope with terminal
> modifications. I am looking at some documentation to understand how to
> proceed with these handles in Ada (Rosetta Code ans Big Online Book of
> Linux Ada to begin).
>
> Thank you.

Your suggestion to use a handler on SIGWINCH works fine with the
following Ada package which has simply to be imported by the
application which uses a terminal. The Ansi_Tty_Control package
provides :
   -The N_Columns and N_Lines variables which keep trace of the
terminal size.
   -The Dim_Terminal procedure which reads the terminal sizes

Window resizing and terminal police size change are well detected and
new columns and lines number well reported.

Great !


--SPECIFICATION
with Ada.Interrupts.Names; use Ada.Interrupts, Ada.Interrupts.Names;
package Sigwinchhandler is
   protected Signalhandler is
      procedure Handlewindowresizing;
      pragma Attach_Handler (Handlewindowresizing, SIGWINCH);
      --      SIGWINCH (window resizing) intercepted by
      --      Handlewindowresizing
   end Signalhandler;
end Sigwinchhandler;

-- BODY
with Ada.Text_IO;      use Ada.Text_IO;
with Ansi_Tty_Control; use Ansi_Tty_Control;
package body Sigwinchhandler is
   -- Package to handle SIGWINCH Linux signals
   protected body Signalhandler is
      -- This protected type contains the signal handlers for the
applications
      procedure Handlewindowresizing is
      -- window dimensions handler
      begin
         -- Acquisition of terminal LINES and COLUMNS by bash
command :
         -- stty size > TermSize.txt (waiting for something else more
direct ...)
         Dim_Terminal;
         Put_Line ("Columns : " & Positive'Image (N_Columns));-- Here
the PROOF that it works !
         Put_Line ("Lines   : " & Positive'Image (N_Lines));
      end Handlewindowresizing;
   end Signalhandler;
end Sigwinchhandler;



^ permalink raw reply	[relevance 2%]

* Re: GNAT and SIGTERM (Linux x86_64)
  2010-10-26 16:36  0% ` Yannick Duchêne (Hibou57)
@ 2010-10-27  7:43  7%   ` Ludovic Brenta
  0 siblings, 0 replies; 76+ results
From: Ludovic Brenta @ 2010-10-27  7:43 UTC (permalink / raw)


Yannick Duchêne wrote on comp.lang.ada:
> Signal_Handler is a type, and a type does not live on its own. To make it  
> “real”, you have to instantiate an entity of that type.

Good catch.

> In few word : in Entry_Point, you forget to declare a variable of type  
> Signal_Handler.
>
> Try this :
>
>   procedure Entry_Point is
>      Shutdown_Flag : Boolean := False;
>      Handler : Signal_Handler; -- < Add this line
>   begin
>      [... remaining of you cool stuff]
>   end Entry_Point;
>
> It works :)

Or, simply remove the "type" keyword from the declaration of
Signal_Handler, i.e.

--- signals.ads before
+++ signals.ads after
@@ -6,6 +6,6 @@
 with Ada.Interrupts.Names; use Ada.Interrupts.Names;
 package Signals is
   pragma Unreserve_All_Interrupts;
-  protected type Signal_Handler is
+  protected Signal_Handler is
     procedure Handle_SIGTERM;
     pragma Attach_Handler(Handle_SIGTERM, SIGTERM);
     pragma Interrupt_State (SIGTERM, System);

--
Ludovic Brenta.
I love hand-writing unified diffs in the morning.



^ permalink raw reply	[relevance 7%]

* Re: GNAT and SIGTERM (Linux x86_64)
  2010-10-26 15:52  2% GNAT and SIGTERM (Linux x86_64) Bryan
@ 2010-10-26 16:36  0% ` Yannick Duchêne (Hibou57)
  2010-10-27  7:43  7%   ` Ludovic Brenta
  0 siblings, 1 reply; 76+ results
From: Yannick Duchêne (Hibou57) @ 2010-10-26 16:36 UTC (permalink / raw)


Le Tue, 26 Oct 2010 17:52:57 +0200, Bryan <brobinson.eng@gmail.com> a  
écrit:

> I'm trying to capture SIGTERM in a very simple test program but I'm
> running into some issues. When I execute the code (at the end of
> message), I get the following output in my terminal when I send "kill -
> SIGTERM <PID>:
>
>> ./entry_point
> SIGTERM handler is NOT reserved
> !!! SIGTERM handler is NOT attached !!!
> Terminated
>
> [...]
> --------------------------------------
> Test program source code:
> --------------------------------------
> -- Signals.ads
> with Ada.Interrupts; use Ada.Interrupts;
> with Ada.Interrupts.Names; use Ada.Interrupts.Names;
> package Signals is
>   pragma Unreserve_All_Interrupts;
>   protected type Signal_Handler is
>     procedure Handle_SIGTERM;
>     pragma Attach_Handler(Handle_SIGTERM, SIGTERM);
>     pragma Interrupt_State (SIGTERM, System);
>   end Signal_Handler;
> end Signals;
>
> -- Signals.adb
> with Ada.Text_IO; use Ada.Text_IO;
> package body Signals is
>   protected body Signal_Handler is
>     procedure Handle_SIGTERM is
>     begin
>       Put_Line( "SIGTERM caught!" );
>     end Handle_SIGTERM;
>   end Signal_Handler;
> end Signals;
>
> -- Entrypoint.adb
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Interrupts; use Ada.Interrupts;
> with Ada.Interrupts.Names; use Ada.Interrupts.Names;
> with Signals; use Signals;
>
> procedure Entry_Point is
>   Shutdown_Flag : Boolean := False;
> begin
>   if Is_Reserved(SIGTERM) then
>     Put_Line("SIGTERM handler is reserved");
>   else
>     Put_Line("SIGTERM handler is NOT reserved");
>   end if;
>
>   if Is_Attached(SIGTERM) then
>     Put_Line("SIGTERM handler is attached");
>   else
>     Put_Line("!!! SIGTERM handler is NOT attached !!!");
>   end if;
>
>   loop
>     -- do nothing
>     exit when Shutdown_Flag = True;
>   end loop;
> end Entry_Point;

Signal_Handler is a type, and a type does not live on its own. To make it  
“real”, you have to instantiate an entity of that type.

In few word : in Entry_Point, you forget to declare a variable of type  
Signal_Handler.

Try this :


  procedure Entry_Point is
     Shutdown_Flag : Boolean := False;
     Handler : Signal_Handler; -- < Add this line
  begin
     [... remaining of you cool stuff]
  end Entry_Point;

It works :)


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[relevance 0%]

* GNAT and SIGTERM (Linux x86_64)
@ 2010-10-26 15:52  2% Bryan
  2010-10-26 16:36  0% ` Yannick Duchêne (Hibou57)
  0 siblings, 1 reply; 76+ results
From: Bryan @ 2010-10-26 15:52 UTC (permalink / raw)


I'm trying to capture SIGTERM in a very simple test program but I'm
running into some issues. When I execute the code (at the end of
message), I get the following output in my terminal when I send "kill -
SIGTERM <PID>:

> ./entry_point
SIGTERM handler is NOT reserved
!!! SIGTERM handler is NOT attached !!!
Terminated

I attached the signal handler in signals.ads, but it seems the handler
is still not attached.  The sample program in the Big Book of Ada
Programming for Linux attaches the handler in the package
specification, and I tried to follow the sample program.  To make
things more interesting, If I run this same code on a Mac OS X with
GNAT, I get the following as my output:

> ./entry_point
SIGTERM handler is reserved

raised PROGRAM_ERROR : Interrupt 15 is reserved

This happens even with the Unreserve_All_Interrupts in signals.ads.
The behavior of both the Linux and the Mac binary are leading me to--
perhaps wrongly--consider that there is something I am missing with
GNAT to allow it to work with UNIX signals.

Questions:
1) Do my pragma statements need to be in the specification or the
body?
2) Do I need to pass some sort of flag to gnat to enable signals?

I would greatly appreciate any input or advice on this issue.

--------------------------------------
Test program source code:
--------------------------------------
-- Signals.ads
with Ada.Interrupts; use Ada.Interrupts;
with Ada.Interrupts.Names; use Ada.Interrupts.Names;
package Signals is
  pragma Unreserve_All_Interrupts;
  protected type Signal_Handler is
    procedure Handle_SIGTERM;
    pragma Attach_Handler(Handle_SIGTERM, SIGTERM);
    pragma Interrupt_State (SIGTERM, System);
  end Signal_Handler;
end Signals;

-- Signals.adb
with Ada.Text_IO; use Ada.Text_IO;
package body Signals is
  protected body Signal_Handler is
    procedure Handle_SIGTERM is
    begin
      Put_Line( "SIGTERM caught!" );
    end Handle_SIGTERM;
  end Signal_Handler;
end Signals;

-- Entrypoint.adb
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Interrupts; use Ada.Interrupts;
with Ada.Interrupts.Names; use Ada.Interrupts.Names;
with Signals; use Signals;

procedure Entry_Point is
  Shutdown_Flag : Boolean := False;
begin
  if Is_Reserved(SIGTERM) then
    Put_Line("SIGTERM handler is reserved");
  else
    Put_Line("SIGTERM handler is NOT reserved");
  end if;

  if Is_Attached(SIGTERM) then
    Put_Line("SIGTERM handler is attached");
  else
    Put_Line("!!! SIGTERM handler is NOT attached !!!");
  end if;

  loop
    -- do nothing
    exit when Shutdown_Flag = True;
  end loop;
end Entry_Point;



^ permalink raw reply	[relevance 2%]

* Re: How to exit a loop with keyboard input
  2010-04-12 13:59  2%   ` John McCormick
@ 2010-04-13 19:38  0%     ` Jerry
  0 siblings, 0 replies; 76+ results
From: Jerry @ 2010-04-13 19:38 UTC (permalink / raw)


On Apr 12, 6:59 am, John McCormick <mccorm...@cs.uni.edu> wrote:
> On Apr 12, 5:36 am, Jerry <lancebo...@qwest.net> wrote:
>
> > Thanks, Georg and Manuel, for testing. I'm on OS X 10.5.8 and:
>
> > MBPro:/ me$ gnat
> > GNAT 4.4.0 20080314 (experimental) [trunk revision 133226]
> > Copyright 1996-2007, Free Software Foundation, Inc.
>
> > I've tried the program on three different terminal programs with the
> > same result: it prints out 0 and waits for RETURN, then prints out 1,
> > etc. If I hit q then RETURN the loop is exited. But the loop never
> > "free-runs."
>
> > Jerry
>
> Perhaps the Asynchronous Transfer of Control mechanism would be
> appropriate.  Here is some GNAT code that runs under Windows XP in
> which the input loop is interrutpted by Ctrl-c.  The interrupt handler
> must be at the library level so I put it in its own package.
>
>    select
>       Ctrl_C_Interrupt.Wait;
>       Put_Line ("Handled Ctrl C");
>    then abort
>       loop
>          Put_Line ("Enter an integer (Ctrl C to exit)");
>          Get (Value);
>          Put (Value);
>          New_Line;
>       end loop;
>    end select;
>
> -----------------------------------------------------------
> with Ada.Interrupts.Names;
> package Ctrl_C is
>
>    protected Ctrl_C_Interrupt is
>       entry Wait;
>       procedure Handler;
>       pragma Attach_Handler (Handler, Ada.Interrupts.Names.SIGINT);
>       pragma Interrupt_Priority;
>    private
>       Received : Boolean := False;
>    end Ctrl_C_Interrupt;
> end Ctrl_C;
>
> -----------------------------------------------------------
> package body Ctrl_C is
>
>    protected body Ctrl_C_Interrupt is
>       procedure Handler is
>       begin
>          Received := True;
>       end Handler;
>
>       entry Wait when Received is
>       begin
>          Received := False;
>       end Wait;
>    end Ctrl_C_Interrupt;
>
> end Ctrl_C;
>
> John

Thanks, John.

Your solution does work (after I added pragma
Unreserve_All_Interrupts;) and I think I can adapt it to my specific
problem but it takes 100% of CPU time so I'm not sure how that would
affect my number-crunching loop. (A similar solution was suggested by
Chris on the GNAT-OSX list but I haven't tried it yet.)

Jerry



^ permalink raw reply	[relevance 0%]

* Re: How to exit a loop with keyboard input
  @ 2010-04-12 13:59  2%   ` John McCormick
  2010-04-13 19:38  0%     ` Jerry
  0 siblings, 1 reply; 76+ results
From: John McCormick @ 2010-04-12 13:59 UTC (permalink / raw)


On Apr 12, 5:36 am, Jerry <lancebo...@qwest.net> wrote:
> Thanks, Georg and Manuel, for testing. I'm on OS X 10.5.8 and:
>
> MBPro:/ me$ gnat
> GNAT 4.4.0 20080314 (experimental) [trunk revision 133226]
> Copyright 1996-2007, Free Software Foundation, Inc.
>
> I've tried the program on three different terminal programs with the
> same result: it prints out 0 and waits for RETURN, then prints out 1,
> etc. If I hit q then RETURN the loop is exited. But the loop never
> "free-runs."
>
> Jerry

Perhaps the Asynchronous Transfer of Control mechanism would be
appropriate.  Here is some GNAT code that runs under Windows XP in
which the input loop is interrutpted by Ctrl-c.  The interrupt handler
must be at the library level so I put it in its own package.

   select
      Ctrl_C_Interrupt.Wait;
      Put_Line ("Handled Ctrl C");
   then abort
      loop
         Put_Line ("Enter an integer (Ctrl C to exit)");
         Get (Value);
         Put (Value);
         New_Line;
      end loop;
   end select;

-----------------------------------------------------------
with Ada.Interrupts.Names;
package Ctrl_C is

   protected Ctrl_C_Interrupt is
      entry Wait;
      procedure Handler;
      pragma Attach_Handler (Handler, Ada.Interrupts.Names.SIGINT);
      pragma Interrupt_Priority;
   private
      Received : Boolean := False;
   end Ctrl_C_Interrupt;
end Ctrl_C;

-----------------------------------------------------------
package body Ctrl_C is

   protected body Ctrl_C_Interrupt is
      procedure Handler is
      begin
         Received := True;
      end Handler;

      entry Wait when Received is
      begin
         Received := False;
      end Wait;
   end Ctrl_C_Interrupt;

end Ctrl_C;

John




^ permalink raw reply	[relevance 2%]

* Re: Ada and (SIGTERM?)
    2009-08-06 19:57  1%     ` Jeffrey R. Carter
@ 2009-08-06 20:00  1%     ` okellogg
  1 sibling, 0 replies; 76+ results
From: okellogg @ 2009-08-06 20:00 UTC (permalink / raw)


On Aug 6, 9:30 pm, Tomek Wałkuski <tomek.walku...@gmail.com> wrote:
> Thx for replies, but... what am I doing wrong?
>
> protected type Interrupt_Handler is
>    procedure Handler;
>    pragma Attach_Handler (Handler, 15); -- is it correct for SIGTERM?

Yes, although using Ada.Interrupts.Names.SIGTERM could be more
readable.

>
>    function Quit return Boolean;
> private
>    Q : Boolean := False;
> end Interrupt_Handler;
>
> protected body Interrupt_Handler is
>    procedure Handler is
>    begin
>       Q := True;
>    end Handler;
>
>    function Quit return Boolean is
>    begin
>       return Q;
>    end Quit;
> end Interrupt_Handler;
>
> Then... somewhere Interrupt_Handler is declared and loop looks like:
>
> while not Quit loop
>    Do_Something;
> end loop;
>
> And... This does not work. What am I missing?

If you are using GNAT then perhaps you need a

   pragma Unreserve_All_Interrupts;

somewhere in a library level spec.

Just shooting from the hip here -

Oliver



^ permalink raw reply	[relevance 1%]

* Re: Ada and (SIGTERM?)
  @ 2009-08-06 19:57  1%     ` Jeffrey R. Carter
  2009-08-06 20:00  1%     ` okellogg
  1 sibling, 0 replies; 76+ results
From: Jeffrey R. Carter @ 2009-08-06 19:57 UTC (permalink / raw)


Tomek Wałkuski wrote:
> Thx for replies, but... what am I doing wrong?
> 
> protected type Interrupt_Handler is
>    procedure Handler;
>    pragma Attach_Handler (Handler, 15); -- is it correct for SIGTERM?

You probably only want a single handler for interrupt 15. So either this should 
be an object rather than a type, or it should have a discriminant to indicate 
the interrupt to handle.

Check your vendor's Ada.Interrupts.Names for the interrupts you can handle on 
your system.

> while not Quit loop
>    Do_Something;
> end loop;
> 
> And... This does not work. What am I missing?

Quit is inside an object of type Interrupt_Handler, and so must be referenced 
using dot notation:

<object>.Quit

"Does not work" is rather vague. Saying "gives me a compilation error with the 
message 'xyz'" or "raises Xyz at run time" or "causes my computer to explode" 
would make it easier to help you.

-- 
Jeff Carter
"Blessed are they who convert their neighbors'
oxen, for they shall inhibit their girth."
Monty Python's Life of Brian
83



^ permalink raw reply	[relevance 1%]

* Timing Example was Re: Interrupt handler and Ada.Real_Time.Timing_Events
  2009-05-15 16:26  2% Interrupt handler and Ada.Real_Time.Timing_Events Reto Buerki
  2009-05-15 16:54  0% ` Adam Beneschan
  2009-05-15 16:56  0% ` Ludovic Brenta
@ 2009-05-16 11:05  0% ` anon
  2 siblings, 0 replies; 76+ results
From: anon @ 2009-05-16 11:05 UTC (permalink / raw)


This is a Timeing example that uses "Ada.Real_Time.Timing_Events" package.

Now, adding an interrupt handler to this design you should wrap the interrupt 
handler within a Task routine bacuse "Ada.Real_Time.Timing_Events" uses 
tasking for its underlying algorithm, then call the Timers Shutdown routine 
once the interrupt has occurred.

--
-- generic_timers.ads
--
with Ada.Real_Time.Timing_Events ;

generic
  Multi_Events : Boolean := True ;
  Timer_Name   : String := "Generic_Timers" ;
  Interval     : in Ada.Real_Time.Time_Span ;
  with procedure Action is <> ;

package Generic_Timers is

  Timer_Error : exception ;

  procedure Activate ;
  procedure Shutdown ;

private

  The_Event : Ada.Real_Time.Timing_Events.Timing_Event ;

end Generic_Timers ;

--
-- generic_timers.adb
--
with Ada.Real_Time ;
use  Ada.Real_Time ;

package body Generic_Timers is


  protected Events is
    procedure Handler ( Event: in out Timing_Events.Timing_Event ) ;
  end Events ;

  protected body Events is
    procedure Handler ( Event: in out Timing_Events.Timing_Event ) is
      begin
        Action ;
        if Multi_Events then
          Activate ;  -- periodic timer continues
        end if ;
      end Handler ;
  end Events ;

  procedure Activate is
    use type Timing_Events.Timing_Event_Handler ;
  begin
    if Timing_Events.Current_Handler ( The_Event ) = null then
      Timing_Events.Set_Handler ( The_Event,
                                  Interval,
                                  Events.Handler'Access ) ;
    else
      raise Timer_Error with "Activation " & Timer_Name ;
    end if ;
   end Activate ;

  procedure Shutdown is
      Success : Boolean := False ;
      use type Timing_Events.Timing_Event_Handler ;
    begin
      if Timing_Events.Current_Handler ( The_Event ) /= null then
         Timing_Events.Cancel_Handler ( The_Event, Success ) ;
         if not Success then
            raise Timer_Error with "Shutdown: " & Timer_Name ;
         end if ;
      end if ;
    end Shutdown ;

end Generic_Timers ;

--
-- timers.ads
--
package Timers is

   procedure Activate ;
   procedure Shutdown ;

end Timers ;

--
-- Timers.adb
--
with Ada.Real_Time ;
with Ada.Text_IO ;

with Generic_Timers ;

package body Timers is

   use Ada ;
   use Real_Time ;
   use Text_IO ;

   ------------------------------------
   --  Define Periodic Event Timers  --
   ------------------------------------
   Periodic_Interval : constant Time_Span := Milliseconds ( 2000 ) ;
   Periodic_Timer_ID : constant String := "Periodic Timer" ;

   procedure Periodic_Action is
   begin
      Put_Line ( "Timeout: Periodic Timer" ) ;
   end Periodic_Action ;

   Package Periodic_Timer is new Generic_Timers ( True,
                                                  Periodic_Timer_ID, 
                                                  Periodic_Interval, 
                                                  Periodic_Action ) ;

   ----------------------------------
   --  Define Single Event Timers  --
   ----------------------------------
   Single_Interval : constant Time_Span := Milliseconds ( 1000 ) ;
   Single_Timer_ID : constant String := "Single Timer" ;

   procedure Single_Action is
   begin
      Put_Line ( "Timeout: Single Timer " ) ;
   end Single_Action ;

   Package Single_Timer is new Generic_Timers ( False,
                                                Single_Timer_ID,
                                                Single_Interval,
                                                Single_Action ) ;

  ----------------------------
  --  Controlling Routines  --
  ----------------------------

  procedure Activate is
   begin
      Put_Line ( "Timers: Activate" ) ;

      Periodic_Timer.Activate ;

      for Index in 0 .. 3 loop
        Single_Timer.Activate ;
        delay 7.0 ;
      end loop;
    end Activate ;

  procedure Shutdown is
    begin
      Put_Line ( "Timers: Shutdown" ) ;
      Periodic_Timer.Shutdown ;
      Single_Timer.Shutdown ;
    end Shutdown;

end Timers ;

--
-- testing.adb
--
with Ada.Exceptions ;
with Ada.Text_IO ;

with Timers ;

procedure Testing is

   use Ada ;
   use Text_IO ;

begin

   Put_Line ( "Testing : Begin" ) ;

   Timers.Activate ;
   delay 5.0 ;
   Timers.Shutdown ;
   
   Put_Line ( "Testing : End" ) ;
exception
   when Error : others =>
       Put_Line ( "Testing fails for because of ==> "
                  & Exceptions.Exception_Information ( Error ) ) ;
end Testing ;



In <guk532$u44$1@news.motzarella.org>, Reto Buerki <reet@codelabs.ch> writes:
>Hi,
>
>I hit a rather strange issue today mixing signal/interrupt handling with
>Ada.Real_Time.Timing_Events. We have a real life application where we
>use timing events but we also need a signal handler to catch signals
>from the environment (SIGTERM etc.).
>
>I wrote a small reproducer to illustrate the problem. The following
>protected object is used as an interrupt handler, which can be attached
>to a specific interrupt/signal:
>
>with Ada.Interrupts;
>
>package Handlers is
>
>   protected type Signal_Handler (Signal : Ada.Interrupts.Interrupt_ID)
>   is
>      pragma Interrupt_Priority;
>
>      entry Wait;
>   private
>      procedure Handle_Signal;
>      pragma Attach_Handler (Handle_Signal, Signal);
>
>      Occured : Boolean := False;
>   end Signal_Handler;
>
>end Handlers;
>
>package body Handlers is
>
>   protected body Signal_Handler is
>      procedure Handle_Signal is
>      begin
>         Occured := True;
>      end Handle_Signal;
>
>      entry Wait when Occured is
>      begin
>         if Wait'Count = 0 then
>            Occured := False;
>         end if;
>      end Wait;
>   end Signal_Handler;
>
>end Handlers;
>
>The handler is used like this:
>
>with Ada.Text_IO;
>with Ada.Interrupts.Names;
>
>--  Uncommenting the next line breaks interrupt handler
>--  with Ada.Real_Time.Timing_Events;
>
>with Handlers;
>
>procedure Interrupt_Problem is
>   use Ada.Interrupts;
>
>   Handler : Handlers.Signal_Handler (Signal => Names.SIGTERM);
>begin
>
>   if Is_Attached (Interrupt => Names.SIGTERM) then
>      Ada.Text_IO.Put_Line ("Attached handler to SIGTERM");
>   else
>      Ada.Text_IO.Put_Line ("Could not attach to SIGTERM!");
>      return;
>   end if;
>
>   Handler.Wait;
>   Ada.Text_IO.Put_Line ("Interrupt received ...");
>
>end Interrupt_Problem;
>
>As expected, when sending SIGTERM to the running 'Interrupt_Problem'
>process "Interrupt received ..." is displayed. So far so good.
>
>As commented in the source code, as soon as the
>Ada.Real_Time.Timing_Events package is with'ed, this mechanism breaks.
>
>The signal handler is not invoked any more when I send a SIGTERM signal
>to a running 'Interrupt_Problem' process, it just terminates without
>triggering the Handler.Wait.
>
>What could be the cause for this behavior? Is there a problem with this
>code?
>
>Thanks in advance!
>- reto




^ permalink raw reply	[relevance 0%]

* Re: Interrupt handler and Ada.Real_Time.Timing_Events
  2009-05-15 16:26  2% Interrupt handler and Ada.Real_Time.Timing_Events Reto Buerki
  2009-05-15 16:54  0% ` Adam Beneschan
@ 2009-05-15 16:56  0% ` Ludovic Brenta
  2009-05-16 11:05  0% ` Timing Example was " anon
  2 siblings, 0 replies; 76+ results
From: Ludovic Brenta @ 2009-05-15 16:56 UTC (permalink / raw)


On May 15, 6:26 pm, Reto Buerki <r...@codelabs.ch> wrote:
> Hi,
>
> I hit a rather strange issue today mixing signal/interrupt handling with
> Ada.Real_Time.Timing_Events. We have a real life application where we
> use timing events but we also need a signal handler to catch signals
> from the environment (SIGTERM etc.).
>
> I wrote a small reproducer to illustrate the problem. The following
> protected object is used as an interrupt handler, which can be attached
> to a specific interrupt/signal:
>
> with Ada.Interrupts;
>
> package Handlers is
>
>    protected type Signal_Handler (Signal : Ada.Interrupts.Interrupt_ID)
>    is
>       pragma Interrupt_Priority;
>
>       entry Wait;
>    private
>       procedure Handle_Signal;
>       pragma Attach_Handler (Handle_Signal, Signal);
>
>       Occured : Boolean := False;
>    end Signal_Handler;
>
> end Handlers;
>
> package body Handlers is
>
>    protected body Signal_Handler is
>       procedure Handle_Signal is
>       begin
>          Occured := True;
>       end Handle_Signal;
>
>       entry Wait when Occured is
>       begin
>          if Wait'Count = 0 then
>             Occured := False;
>          end if;
>       end Wait;
>    end Signal_Handler;
>
> end Handlers;
>
> The handler is used like this:
>
> with Ada.Text_IO;
> with Ada.Interrupts.Names;
>
> --  Uncommenting the next line breaks interrupt handler
> --  with Ada.Real_Time.Timing_Events;
>
> with Handlers;
>
> procedure Interrupt_Problem is
>    use Ada.Interrupts;
>
>    Handler : Handlers.Signal_Handler (Signal => Names.SIGTERM);
> begin
>
>    if Is_Attached (Interrupt => Names.SIGTERM) then
>       Ada.Text_IO.Put_Line ("Attached handler to SIGTERM");
>    else
>       Ada.Text_IO.Put_Line ("Could not attach to SIGTERM!");
>       return;
>    end if;
>
>    Handler.Wait;
>    Ada.Text_IO.Put_Line ("Interrupt received ...");
>
> end Interrupt_Problem;
>
> As expected, when sending SIGTERM to the running 'Interrupt_Problem'
> process "Interrupt received ..." is displayed. So far so good.
>
> As commented in the source code, as soon as the
> Ada.Real_Time.Timing_Events package is with'ed, this mechanism breaks.
>
> The signal handler is not invoked any more when I send a SIGTERM signal
> to a running 'Interrupt_Problem' process, it just terminates without
> triggering the Handler.Wait.
>
> What could be the cause for this behavior? Is there a problem with this
> code?

Ada.Real_Time.Timing_Events's elaboration block creates a task and
promotes it to an outer level (i.e. it is no longer dependent on a
master).  The only way to terminate this task is by sending it
SIGTERM, so the task attaches another signal handler to SIGTERM before
yours.  That handler catches the signal and does not propagate it to
any other handler.  See System.Task_Primitives.Operations.Initialize.

I'm afraid there is no way out :) maybe you can use another signal in
your task?

--
Ludovic Brenta.



^ permalink raw reply	[relevance 0%]

* Re: Interrupt handler and Ada.Real_Time.Timing_Events
  2009-05-15 16:26  2% Interrupt handler and Ada.Real_Time.Timing_Events Reto Buerki
@ 2009-05-15 16:54  0% ` Adam Beneschan
  2009-05-15 16:56  0% ` Ludovic Brenta
  2009-05-16 11:05  0% ` Timing Example was " anon
  2 siblings, 0 replies; 76+ results
From: Adam Beneschan @ 2009-05-15 16:54 UTC (permalink / raw)


On May 15, 9:26 am, Reto Buerki <r...@codelabs.ch> wrote:
> Hi,
>
> I hit a rather strange issue today mixing signal/interrupt handling with
> Ada.Real_Time.Timing_Events. We have a real life application where we
> use timing events but we also need a signal handler to catch signals
> from the environment (SIGTERM etc.).
>
> I wrote a small reproducer to illustrate the problem. The following
> protected object is used as an interrupt handler, which can be attached
> to a specific interrupt/signal:
>
> with Ada.Interrupts;
>
> package Handlers is
>
>    protected type Signal_Handler (Signal : Ada.Interrupts.Interrupt_ID)
>    is
>       pragma Interrupt_Priority;
>
>       entry Wait;
>    private
>       procedure Handle_Signal;
>       pragma Attach_Handler (Handle_Signal, Signal);
>
>       Occured : Boolean := False;
>    end Signal_Handler;
>
> end Handlers;
>
> package body Handlers is
>
>    protected body Signal_Handler is
>       procedure Handle_Signal is
>       begin
>          Occured := True;
>       end Handle_Signal;
>
>       entry Wait when Occured is
>       begin
>          if Wait'Count = 0 then
>             Occured := False;
>          end if;
>       end Wait;
>    end Signal_Handler;
>
> end Handlers;
>
> The handler is used like this:
>
> with Ada.Text_IO;
> with Ada.Interrupts.Names;
>
> --  Uncommenting the next line breaks interrupt handler
> --  with Ada.Real_Time.Timing_Events;
>
> with Handlers;
>
> procedure Interrupt_Problem is
>    use Ada.Interrupts;
>
>    Handler : Handlers.Signal_Handler (Signal => Names.SIGTERM);
> begin
>
>    if Is_Attached (Interrupt => Names.SIGTERM) then
>       Ada.Text_IO.Put_Line ("Attached handler to SIGTERM");
>    else
>       Ada.Text_IO.Put_Line ("Could not attach to SIGTERM!");
>       return;
>    end if;
>
>    Handler.Wait;
>    Ada.Text_IO.Put_Line ("Interrupt received ...");
>
> end Interrupt_Problem;
>
> As expected, when sending SIGTERM to the running 'Interrupt_Problem'
> process "Interrupt received ..." is displayed. So far so good.
>
> As commented in the source code, as soon as the
> Ada.Real_Time.Timing_Events package is with'ed, this mechanism breaks.
>
> The signal handler is not invoked any more when I send a SIGTERM signal
> to a running 'Interrupt_Problem' process, it just terminates without
> triggering the Handler.Wait.
>
> What could be the cause for this behavior?

My guess would be that when Ada.Real_Time.Timing_Events is with'ed,
this causes elaboration code for the Timing_Events package to be
executed (before Interrupt_Problem), and there must be something that
this elaboration does that interferes with the Attach_Handler
mechanism.  I can't find anything in the language definition of
Timing_Events that would cause this, so it must be a problem
particular to your Ada compiler implementation, and you should contact
the vendor, or at least let us know what compiler you're using so that
others who may have some knowledge of that particular compiler might
be able to help.


> Is there a problem with this
> code?

Yes, definitely: "occurred" is misspelled.  It has two R's.  I happen
to know this one very well because I blew this word (or another form,
like "occurrence") in my 8th-grade spelling bee by only putting one R
in it.  So you've brought up some memories here.......

                               -- Adam




^ permalink raw reply	[relevance 0%]

* Interrupt handler and Ada.Real_Time.Timing_Events
@ 2009-05-15 16:26  2% Reto Buerki
  2009-05-15 16:54  0% ` Adam Beneschan
                   ` (2 more replies)
  0 siblings, 3 replies; 76+ results
From: Reto Buerki @ 2009-05-15 16:26 UTC (permalink / raw)


Hi,

I hit a rather strange issue today mixing signal/interrupt handling with
Ada.Real_Time.Timing_Events. We have a real life application where we
use timing events but we also need a signal handler to catch signals
from the environment (SIGTERM etc.).

I wrote a small reproducer to illustrate the problem. The following
protected object is used as an interrupt handler, which can be attached
to a specific interrupt/signal:

with Ada.Interrupts;

package Handlers is

   protected type Signal_Handler (Signal : Ada.Interrupts.Interrupt_ID)
   is
      pragma Interrupt_Priority;

      entry Wait;
   private
      procedure Handle_Signal;
      pragma Attach_Handler (Handle_Signal, Signal);

      Occured : Boolean := False;
   end Signal_Handler;

end Handlers;

package body Handlers is

   protected body Signal_Handler is
      procedure Handle_Signal is
      begin
         Occured := True;
      end Handle_Signal;

      entry Wait when Occured is
      begin
         if Wait'Count = 0 then
            Occured := False;
         end if;
      end Wait;
   end Signal_Handler;

end Handlers;

The handler is used like this:

with Ada.Text_IO;
with Ada.Interrupts.Names;

--  Uncommenting the next line breaks interrupt handler
--  with Ada.Real_Time.Timing_Events;

with Handlers;

procedure Interrupt_Problem is
   use Ada.Interrupts;

   Handler : Handlers.Signal_Handler (Signal => Names.SIGTERM);
begin

   if Is_Attached (Interrupt => Names.SIGTERM) then
      Ada.Text_IO.Put_Line ("Attached handler to SIGTERM");
   else
      Ada.Text_IO.Put_Line ("Could not attach to SIGTERM!");
      return;
   end if;

   Handler.Wait;
   Ada.Text_IO.Put_Line ("Interrupt received ...");

end Interrupt_Problem;

As expected, when sending SIGTERM to the running 'Interrupt_Problem'
process "Interrupt received ..." is displayed. So far so good.

As commented in the source code, as soon as the
Ada.Real_Time.Timing_Events package is with'ed, this mechanism breaks.

The signal handler is not invoked any more when I send a SIGTERM signal
to a running 'Interrupt_Problem' process, it just terminates without
triggering the Handler.Wait.

What could be the cause for this behavior? Is there a problem with this
code?

Thanks in advance!
- reto



^ permalink raw reply	[relevance 2%]

* Re: Access procedure to pointer
  @ 2008-05-29 20:20  1%                       ` Jeffrey R. Carter
  0 siblings, 0 replies; 76+ results
From: Jeffrey R. Carter @ 2008-05-29 20:20 UTC (permalink / raw)


S�bastien wrote:
> 
> Ok I use it really often then. Sorry if I'm a bit rude but you can easly 
> find POSIX signal implementation in ada in this document.
> 
> Ok there is the Signal reference in index "See interrups".
> 
> But the first sentence of C.3 is:
> "This clause specifies the language-defined model for hardware 
> interrupts in addition to mechanisms for handling interrupts."

I agree. This is a tough area; what constitutes and interrupt is highly 
compiler- and platform-dependent. The ARM does a decent job of defining a 
platform-independent approach to interrupt handling, but is not a good source 
for solutions to platform-dependent concepts such as POSIX signals.

However, the index reference "see interrupts" should indicate that (on some 
platforms, at least) "signal" is a synonym for "interrupt" and that in those 
cases C.3 applies to them as well. From there you might discover the existence 
of Ada.Interrupts.Names, and look at its implementation for your compiler, and 
there find SIGHUP as one of the names.

Then again, the ARM is not the most easily read document, and you might not (and 
didn't). The Ada-83 RM, while less formal and precise, was much more readable, 
and Ada-83 developers often referred to it. Many of us still like to refer to 
the ARM. Other sources might be better for others. Many people use the AARM, but 
it's not really any better for your problem.

-- 
Jeff Carter
"Unix and C are the ultimate computer viruses."
Richard Gabriel
99



^ permalink raw reply	[relevance 1%]

* Re: Access procedure to pointer
  2008-05-28 21:36  2%               ` Adam Beneschan
@ 2008-05-28 23:02  0%                 ` Sebastien Morand
    0 siblings, 1 reply; 76+ results
From: Sebastien Morand @ 2008-05-28 23:02 UTC (permalink / raw)


> Right, but the reference manual doesn't say that "interrupts" are
> "Unix signals", even on a Unix-like system, which is to be expected,
> since this is a highly implementation-dependent matter and the RM
> can't be expected to speak on what "interrupts" mean in a particular
> implementation.  So the RM can't be expected to help solve Sebastien's
> problem at all.  I'd think that GNAT documentation *would* give an
> answer to this, but a quick search of the GNAT documentation that I
> found on AdaCore's site didn't say anything about what the
> "interrupts" in Ada.Interrupts refer to.  I may not have been looking
> in the right place, though.  I did find the .ads file that defines the
> Ada.Interrupts.Names spec in GNAT's runtime, and that did make it
> clear that "interrupts" are Unix (or Linux or something) signals.

Completly agree. Actually I'm not so sure I have the right link to the manual 
you all speak about :-)

There is so many packages in my adainclude directory, that make me sick not to 
know what is inside ;-)

Sebastien



^ permalink raw reply	[relevance 0%]

* Re: Access procedure to pointer
  @ 2008-05-28 21:36  2%               ` Adam Beneschan
  2008-05-28 23:02  0%                 ` Sebastien Morand
  0 siblings, 1 reply; 76+ results
From: Adam Beneschan @ 2008-05-28 21:36 UTC (permalink / raw)


On May 28, 8:26 am, Jean-Pierre Rosen <ro...@adalog.fr> wrote:
> Sébastien a écrit :>> Why don't you simply use Ada.Interrupts?
>
> > Two reasons:
> > 1) It didn't know it exists
> > 2) It's not documented, and not intuitive, no example nothing to start.
>
> > As a matter of fact, the first problem is solved ;-), if you any help
> > about the second problem, I'll be happy to use standard package instead
> > of mine.
>
> Well, it is documented in the reference manual, and a quick search for
> the word "interrupt" in the index would have put you right there...

Right, but the reference manual doesn't say that "interrupts" are
"Unix signals", even on a Unix-like system, which is to be expected,
since this is a highly implementation-dependent matter and the RM
can't be expected to speak on what "interrupts" mean in a particular
implementation.  So the RM can't be expected to help solve Sebastien's
problem at all.  I'd think that GNAT documentation *would* give an
answer to this, but a quick search of the GNAT documentation that I
found on AdaCore's site didn't say anything about what the
"interrupts" in Ada.Interrupts refer to.  I may not have been looking
in the right place, though.  I did find the .ads file that defines the
Ada.Interrupts.Names spec in GNAT's runtime, and that did make it
clear that "interrupts" are Unix (or Linux or something) signals.

                                 -- Adam



^ permalink raw reply	[relevance 2%]

* Re: Access procedure to pointer
    @ 2008-05-28 15:29  1%             ` Sébastien
  1 sibling, 0 replies; 76+ results
From: Sébastien @ 2008-05-28 15:29 UTC (permalink / raw)


> 2) It's not documented, and not intuitive, no example nothing to start.
> 
> As a matter of fact, the first problem is solved ;-), if you any help 
> about the second problem, I'll be happy to use standard package instead 
> of mine.

I answer to my own question. Here is a sample code it works fine:

    package AdaInterrupsTest is

       protected Test is
          procedure TestHandler;
          pragma Interrupt_Handler(TestHandler);
       end Test;

    end AdaInterrupsTest;

    package body AdaInterrupsTest is

       protected body Test is
          procedure TestHandler is
          begin
             Put_Line("Hello from test");
          end TestHandler;
       end Test;

    end AdaInterrupsTest;

    procedure TestAdaInterrupt is
       use AdaInterrupsTest;
       use Ada.Interrupts;
       use Ada.Interrupts.Names;
    begin
       Attach_Handler(Test.TestHandler'Access, SIGHUP);
       delay 30.0;
    end TestAdaInterrupt;

Then get the pid before the end of the delay and then kill -1 <pid> give 
me "Hello from test" on stdout

Thanks about the tip

Sebastien



^ permalink raw reply	[relevance 1%]

* Re: problem with ada.interrupts
  2005-08-10 16:01  2% problem with ada.interrupts evangeli
@ 2005-08-25 12:25  0% ` Thierry Pirot
  0 siblings, 0 replies; 76+ results
From: Thierry Pirot @ 2005-08-25 12:25 UTC (permalink / raw)


> with
>   Ada.Interrupts,
>   Ada.Interrupts.Names,
>   Ada.Text_Io;
> 
> procedure Test is
> 
>    protected Interruption_Handler is
>       procedure SIGINT_Handler;
>    end Interruption_Handler;
>    protected body Interruption_Handler is
>       procedure SIGINT_Handler is
>       begin
>          Ada.Text_Io.Put_Line("interruption");
>       end;
>    end Interruption_Handler;
> 
> begin
> 
> Ada.Interrupts.Attach_Handler(Interruption_Handler.SIGINT_Handler'Access,
>                                  Ada.Interrupts.Names.SIGINT);
>    Ada.Text_Io.Put_Line("ok");
>    delay 5.0;
> end;
> 
> 
> this compiles fine, but when i launch it, nothing happens (not even the
> put_line("ok")).
> it seems that even this little program does not terminate :
> 
> with
>   Ada.Interrupts;
> 
> procedure Test is
> begin
>    null:
> end;

(My two cents) 
How did you launch it ?  Maybe you forgot "test" is an internal shell command. 
What about 
./test
which test
help test
-- 
   Take it Easy          Don't worry            Be Happy

                           Thierry

�������o�o��������o�o��������o�o��������o�o��������o�o�������



^ permalink raw reply	[relevance 0%]

* problem with ada.interrupts
@ 2005-08-10 16:01  2% evangeli
  2005-08-25 12:25  0% ` Thierry Pirot
  0 siblings, 1 reply; 76+ results
From: evangeli @ 2005-08-10 16:01 UTC (permalink / raw)


hello
in my program i want to catch the interruption by the user, e.g.,
ctrl+c.
i looked at the RM and it seems that package ada.interrupts is designed
to do this kind of things.
so i tested this little program (my compiler is gnat 3.15p) :


with
  Ada.Interrupts,
  Ada.Interrupts.Names,
  Ada.Text_Io;

procedure Test is

   protected Interruption_Handler is
      procedure SIGINT_Handler;
   end Interruption_Handler;
   protected body Interruption_Handler is
      procedure SIGINT_Handler is
      begin
         Ada.Text_Io.Put_Line("interruption");
      end;
   end Interruption_Handler;

begin

Ada.Interrupts.Attach_Handler(Interruption_Handler.SIGINT_Handler'Access,
                                 Ada.Interrupts.Names.SIGINT);
   Ada.Text_Io.Put_Line("ok");
   delay 5.0;
end;


this compiles fine, but when i launch it, nothing happens (not even the
put_line("ok")).
it seems that even this little program does not terminate :

with
  Ada.Interrupts;

procedure Test is
begin
   null:
end;

i suspect a problem in the elaboration of package Ada.Interrupts, but i
have no idea of how to deal with it.
any idea?

Thanks for any help

Sami




^ permalink raw reply	[relevance 2%]

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  2005-06-16  8:03  1% ` Egil H. H�vik
@ 2005-06-16  9:36  0%   ` Thorsten
  0 siblings, 0 replies; 76+ results
From: Thorsten @ 2005-06-16  9:36 UTC (permalink / raw)


Hi Egil!

> Have you looked at pragma Attach_Handler?
>
> pragma Unreserve_All_Interrupts;
> protected Handler is
>    procedure Handle_SIGSEGV;
>    pragma Attach_Handler( Handle_SIGSEGV, Ada.Interrupts.Names.SIGSEGV );
> end Handler;

Yes, I also tried with a static signal handler. There is no difference
in behaviour.

I also tried with a task type insted of a protected object - which also
makes no difference.

Regards,
Thorsten




^ permalink raw reply	[relevance 0%]

* Re: Interrupt handler seems not to be called in GNAT 3.15p
  @ 2005-06-16  8:03  1% ` Egil H. H�vik
  2005-06-16  9:36  0%   ` Thorsten
  0 siblings, 1 reply; 76+ results
From: Egil H. H�vik @ 2005-06-16  8:03 UTC (permalink / raw)



> When running the program SIGSEGV is raised twice (which I can see only
> in gdb) for the same memory location and the program terminates. If I
> put a delay 5.0 (or some other time) statement just before accessing
> the memory, I also get the output of the exception handler, which
> means an exception (PROGRAM_ERROR) is raised.
>
> Can anyone give me a hint? Is this a known problem with GNAT 3.15p?
> Is it possible to handle SIGSEGV at all in this environment?


Have you looked at pragma Attach_Handler?

pragma Unreserve_All_Interrupts;
protected Handler is
   procedure Handle_SIGSEGV;
   pragma Attach_Handler( Handle_SIGSEGV, Ada.Interrupts.Names.SIGSEGV );
end Handler;


~egilhh





^ permalink raw reply	[relevance 1%]

* Catching Ctrl-C SIGINT
@ 2005-01-17 14:13  1% Christopher Broeg
  0 siblings, 0 replies; 76+ results
From: Christopher Broeg @ 2005-01-17 14:13 UTC (permalink / raw)


Hi,

I am having some trouble with protected types. I am trying to do some 
cleanup work if the user presses Ctrl-C SIGINT.
For this I wrote a little test program. The problem is getting the 
information about the raised interrupt back to the main program. I tried 
using a little task that calls a entry in a protected type:

with Catch_Interrupt;

with Ada.Text_IO;use Ada.Text_IO;
procedure Test1 is
    Stop: exception;

    task Get_Info is
       entry Stop;
    end Get_info;
    task body Get_Info is
    begin
       loop
          Catch_Interrupt.Event.wait;
      -- here comes the code that handles the interrupt received
          select
             accept Stop do
                Stop;
             end Stop;
          or
             terminate;
          end select;
       end loop;
    end Get_Info;


begin

    for i in 1 .. 5 loop
       Put(Integer'Image(i));
       delay 1.0;
    end loop;

end Test1;


the package actually doing the interrupt catching is:

with Ada.Interrupts;
with Ada.Interrupts.names;
package Catch_Interrupt is

    Sig_Int_Caught : exception;

    procedure Signal_Public;

    protected Catch_Interrupt is
       procedure Clean_up;
       pragma Unreserve_All_Interrupts;
       --pragma interrupt_Handler(Clean_Up);
       pragma Attach_Handler(Clean_Up,Ada.Interrupts.Names.SIGINT);
    end Catch_Interrupt;

    protected Event is
       entry Wait;
       procedure Signal;
    private
       Allowed : Boolean := False;
    end Event;
end Catch_Interrupt;


with Ada.Text_IO;
use Ada.Text_IO;
package body Catch_Interrupt is

    procedure Signal_Public is
    begin
       Event.Signal;
    end Signal_Public;


    protected body Catch_Interrupt is
       procedure Clean_up is
       begin
          Put_line("Interrupt SIGINT caught. sending signal ");
          Signal_public;
          Put_line("SIGNAL SENT. ");
       end Clean_Up;
    end Catch_Interrupt;

    protected body Event is
       entry Wait when allowed is
       begin
          Put_line("catch_interrupt msg: in entry wait");
       end Wait;
       procedure  Signal is
       begin
          Put_line("Signal received!!!");
          Allowed := True;
       end Signal;
    end Event;
end Catch_Interrupt;

Here the problem:
I do get the message
"Interrupt SIGINT caught. sending signal "
but the signal_public procedure never manages to send the signal. I 
don't know why. If I call the signal_public procedure from test1 it 
works, but is of course useless.

Can you give me any hints on what I am doing wrong? I am lost.

Maybe there is a better way to react upon the interrupt? But still I am 
wondering why my solution is not working.

Thanx a lot,

Chris



^ permalink raw reply	[relevance 1%]

* Catching Ctrl-C SIGINT
@ 2005-01-17 14:07  1% Christopher Broeg
  0 siblings, 0 replies; 76+ results
From: Christopher Broeg @ 2005-01-17 14:07 UTC (permalink / raw)


Hi,

I am having some trouble with protected types. I am trying to do some 
cleanup work if the user presses Ctrl-C SIGINT.
For this I wrote a little test program. The problem is getting the 
information about the raised interrupt back to the main program. I tried 
using a little task that calls a entry in a protected type:

with Catch_Interrupt;

with Ada.Text_IO;use Ada.Text_IO;
procedure Test1 is
    Stop: exception;

    task Get_Info is
       entry Stop;
    end Get_info;
    task body Get_Info is
    begin
       loop
          Catch_Interrupt.Event.wait;
      -- here comes the code that handles the interrupt received
          select
             accept Stop do
                Stop;
             end Stop;
          or
             terminate;
          end select;
       end loop;
    end Get_Info;


begin

    for i in 1 .. 5 loop
       Put(Integer'Image(i));
       delay 1.0;
    end loop;

end Test1;


the package actually doing the interrupt catching is:

with Ada.Interrupts;
with Ada.Interrupts.names;
package Catch_Interrupt is

    Sig_Int_Caught : exception;

    procedure Signal_Public;

    protected Catch_Interrupt is
       procedure Clean_up;
       pragma Unreserve_All_Interrupts;
       --pragma interrupt_Handler(Clean_Up);
       pragma Attach_Handler(Clean_Up,Ada.Interrupts.Names.SIGINT);
    end Catch_Interrupt;

    protected Event is
       entry Wait;
       procedure Signal;
    private
       Allowed : Boolean := False;
    end Event;
end Catch_Interrupt;


with Ada.Text_IO;
use Ada.Text_IO;
package body Catch_Interrupt is

    procedure Signal_Public is
    begin
       Event.Signal;
    end Signal_Public;


    protected body Catch_Interrupt is
       procedure Clean_up is
       begin
          Put_line("Interrupt SIGINT caught. sending signal ");
          Signal_public;
          Put_line("SIGNAL SENT. ");
       end Clean_Up;
    end Catch_Interrupt;

    protected body Event is
       entry Wait when allowed is
       begin
          Put_line("catch_interrupt msg: in entry wait");
       end Wait;
       procedure  Signal is
       begin
          Put_line("Signal received!!!");
          Allowed := True;
       end Signal;
    end Event;
end Catch_Interrupt;

Here the problem:
I do get the message
"Interrupt SIGINT caught. sending signal "
but the signal_public procedure never manages to send the signal. I 
don't know why. If I call the signal_public procedure from test1 it 
works, but is of course useless.

Can you give me any hints on what I am doing wrong? I am lost.

Maybe there is a better way to react upon the interrupt? But still I am 
wondering why my solution is not working.

Thanx a lot,

Chris



^ permalink raw reply	[relevance 1%]

* Catching Ctrl-C SIGINT
@ 2005-01-17 12:26  1% Christopher Broeg
  0 siblings, 0 replies; 76+ results
From: Christopher Broeg @ 2005-01-17 12:26 UTC (permalink / raw)


Hi,

I am having some trouble with protected types. I am trying to do some 
cleanup work if the user presses Ctrl-C SIGINT.
For this I wrote a little test program. The problem is getting the 
information about the raised interrupt back to the main program. I tried 
using a little task that calls a entry in a protected type:

with Catch_Interrupt;

with Ada.Text_IO;use Ada.Text_IO;
procedure Test1 is
    Stop: exception;

    task Get_Info is
       entry Stop;
    end Get_info;
    task body Get_Info is
    begin
       loop
          Catch_Interrupt.Event.wait;
	 -- here comes the code that handles the interrupt received
          select
             accept Stop do
                Stop;
             end Stop;
          or
             terminate;
          end select;
       end loop;
    end Get_Info;


begin

    for i in 1 .. 5 loop
       Put(Integer'Image(i));
       delay 1.0;
    end loop;

end Test1;


the package actually doing the interrupt catching is:

with Ada.Interrupts;
with Ada.Interrupts.names;
package Catch_Interrupt is

    Sig_Int_Caught : exception;

    procedure Signal_Public;

    protected Catch_Interrupt is
       procedure Clean_up;
       pragma Unreserve_All_Interrupts;
       --pragma interrupt_Handler(Clean_Up);
       pragma Attach_Handler(Clean_Up,Ada.Interrupts.Names.SIGINT);
    end Catch_Interrupt;

    protected Event is
       entry Wait;
       procedure Signal;
    private
       Allowed : Boolean := False;
    end Event;
end Catch_Interrupt;


with Ada.Text_IO;
use Ada.Text_IO;
package body Catch_Interrupt is

    procedure Signal_Public is
    begin
       Event.Signal;
    end Signal_Public;


    protected body Catch_Interrupt is
       procedure Clean_up is
       begin
          Put_line("Interrupt SIGINT caught. sending signal ");
          Signal_public;
          Put_line("SIGNAL SENT. ");
       end Clean_Up;
    end Catch_Interrupt;

    protected body Event is
       entry Wait when allowed is
       begin
          Put_line("catch_interrupt msg: in entry wait");
       end Wait;
       procedure  Signal is
       begin
          Put_line("Signal received!!!");
          Allowed := True;
       end Signal;
    end Event;
end Catch_Interrupt;

Here the problem:
I do get the message
"Interrupt SIGINT caught. sending signal "
but the signal_public procedure never manages to send the signal. I 
don't know why. If I call the signal_public procedure from test1 it 
works, but is of course useless.

Can you give me any hints on what I am doing wrong? I am lost.

Maybe there is a better way to react upon the interrupt? But still I am 
wondering why my solution is not working.

Thanx a lot,

Chris



^ permalink raw reply	[relevance 1%]

* Re: SIGINT problem under LINUX
  @ 2004-06-16 11:13  2% ` Jeff C,
  0 siblings, 0 replies; 76+ results
From: Jeff C, @ 2004-06-16 11:13 UTC (permalink / raw)



"Radek Kotowicz" <kor@li.pl> wrote in message
news:51bc4db.0406160129.7cb72fb8@posting.google.com...
> Hi,
>  I'm facing the following problem. I have written a signal handler for
> SIGINT and a few other signals. The program performs as expected when
> I type CTRL+C, but somehow the signal isn't handled or delivered when
> I issue `kill -s SIGINT <pid>`. There is only one process of my app
> running.
> Is there at all any way the program can infer what does the signal
> come from - I guess it cannot carry any extra info with it.
> Does anyone have any clue what the problem is?
>
> Thanx in advance,
> Radek Kotowicz
> --


Though it does not sound like the exact problem that you are seeing, it is
probably work a re-read of the GNAT RM and one of the GNAT header files to
see if you can gleen any useful information from it.


pragma Unreserve_All_Interrupts
Syntax:
          pragma Unreserve_All_Interrupts;
          Normally certain interrupts are reserved to the implementation.
Any attempt to attach an interrupt causes Program_Error to be raised, as
described in RM C.3.2(22). A typical example is the SIGINT interrupt used in
many systems for an Ctrl-C interrupt. Normally this interrupt is reserved to
the implementation, so that Ctrl-C can be used to interrupt execution.

If the pragma Unreserve_All_Interrupts appears anywhere in any unit in a
program, then all such interrupts are unreserved. This allows the program to
handle these interrupts, but disables their standard functions. For example,
if this pragma is used, then pressing Ctrl-C will not automatically
interrupt execution. However, a program can then handle the SIGINT interrupt
as it chooses.

For a full list of the interrupts handled in a specific implementation, see
the source code for the specification of Ada.Interrupts.Names in file
a-intnam.ads. This is a target dependent file that contains the list of
interrupts recognized for a given target. The documentation in this file
also specifies what interrupts are affected by the use of the
Unreserve_All_Interrupts pragma.






^ permalink raw reply	[relevance 2%]

* Signal handler blocks proteced type
@ 2004-03-25 17:05  1% Lutz Donnerhacke
  0 siblings, 0 replies; 76+ results
From: Lutz Donnerhacke @ 2004-03-25 17:05 UTC (permalink / raw)


The following test program shows a strange behavior:

A protected type with a signal handler is instantiated in order to catch a
signal. If the signal is not catched, everything works fine. If the signal
was delivered, the inner scope will not be terminated, because the protected
type can not be finalized.

Why?

Ok, there is a zombie afterwards.
\f
with Ada.Text_IO;  use Ada.Text_IO;
with Ints;

procedure t is
begin
   Put_Line("Enviroment started.");
   declare
      i : Ints.Int;
   begin
      Put_Line("Waiting.");
      delay 2.0;
      if i.Found then
         Put_Line("Catched.");
      else
         Put_Line("Nothing.");
      end if;
   end;
   Put_Line("Enviroment stopped.");
end t;
\f
Example:
$ ./t
Enviroment started.
Waiting.
Nothing.
Enviroment stopped.

$ ./t & sleep 1; kill -1 %1; sleep 3
[1] 2366
Enviroment started.
Waiting.
Catched.
$ jobs
[1]+  Running                 ./t &
$ pstree
     |-sh-+-pstree
     |    `-t---(t)

\f
with Ada.Interrupts.Names;   use Ada.Interrupts.Names;

package Ints is
   protected type Int is
      procedure Signal;
      pragma Attach_Handler(Signal, SIGHUP);
      procedure Reset;
      function Found return Boolean;
   private
      catched : Boolean := False;
   end Int;
end Ints;
\f
package body Ints is
   protected body Int is
      procedure Signal is
      begin
	 catched := True;   
      end Signal;
      
      procedure Reset is
      begin
	 catched := False;   
      end Reset;
      
      function Found return Boolean is
      begin
	 return catched;   
      end Found;
   end Int;
end Ints;



^ permalink raw reply	[relevance 1%]

* Signal handler blocks proteced type
@ 2004-03-25 17:03  1% Lutz Donnerhacke
  0 siblings, 0 replies; 76+ results
From: Lutz Donnerhacke @ 2004-03-25 17:03 UTC (permalink / raw)


The following test program shows a strange behavior:

A protected type with a signal handler is instantiated in order to catch a
signal. If the signal is not catched, everything works fine. If the signal
was delivered, the inner scope will not be terminated, because the protected
type can not be finalized.

Why?




\f
with Ada.Text_IO;  use Ada.Text_IO;
with Ints;

procedure t is
begin
   Put_Line("Enviroment started.");
   declare
      i : Ints.Int;
   begin
      Put_Line("Waiting.");
      delay 2.0;
      if i.Found then
         Put_Line("Catched.");
      else
         Put_Line("Nothing.");
      end if;
   end;
   Put_Line("Enviroment stopped.");
end t;
\f
Example:
$ ./t
Enviroment started.
Waiting.
Nothing.
Enviroment stopped.

$ ./t & sleep 1; kill -1 %1; sleep 3
[1] 2366
Enviroment started.
Waiting.
Catched.
$ jobs
[1]+  Running                 ./t &

\f
with Ada.Interrupts.Names;   use Ada.Interrupts.Names;

package Ints is
   protected type Int is
      procedure Signal;
      pragma Attach_Handler(Signal, SIGHUP);
      procedure Reset;
      function Found return Boolean;
   private
      catched : Boolean := False;
   end Int;
end Ints;
\f
package body Ints is
   protected body Int is
      procedure Signal is
      begin
	 catched := True;   
      end Signal;
      
      procedure Reset is
      begin
	 catched := False;   
      end Reset;
      
      function Found return Boolean is
      begin
	 return catched;   
      end Found;
   end Int;
end Ints;



^ permalink raw reply	[relevance 1%]

* Re: gnat/linux:setitimer
  @ 2004-01-15  3:35  2%   ` Tilman Glotzner
  0 siblings, 0 replies; 76+ results
From: Tilman Glotzner @ 2004-01-15  3:35 UTC (permalink / raw)



1) How do I monitor signals with gdb ? 
I know of the "handle <signal> print" command, and the "handle <signal> 
stop" command. 
I tried to set a breakpoint with "catch signal 14", but gdb tells me, that 
this feature is not yet implemented (My version of gdb is 5.1.1). 
Are there any other ways ?

2) I tried to to export all signal related code to c, and released all 
signals  by using pragma Unreserve_All_Interrupts (see program below). The 
signal is not catched either:
Even though setitimer returns a 0 (=success), I am suspecious if the 
SIG_ALRM signal is really sent.

Or maybe  gnat's runtime library uses that signal even though it should be 
release released by pragma Unreserve_All_Interrupts



--------------------------------------------------------------
-- Filename: timer_test.adb
-- Desc: Test program for timer package
--
-- (c) 2003 Tilman Glotzner, DG2TG
--
-- History:
-- Date       Name         Descrition
-- 2003-12-08 T. Glotzner  Creation
--------------------------------------------------------------
pragma Unreserve_All_Interrupts;

with Text_Io,Ada.Interrupts,Ada.Interrupts.Names;
use Text_Io,Ada.Interrupts,Ada.Interrupts.Names;

procedure Timer_Test_A is
   Counter: Integer := 0;
   I: Integer := 20;

   procedure Settimer;
   pragma Import (C,Settimer);
begin
   New_line;
   Put_Line("Timer_Test_A");
   Put_Line("==========");

   Settimer;
   Put_Line("I := " & I'Img);
   while (Counter <=  I) loop
      null;
         Counter := Counter + 1;


         delay(0.5);
--         Put_Line("Counter = " & Counter'Img);
      end loop;

end Timer_Test_A;

// Filename: setitimer.c

#include<stdlib.h>
#include<stdio.h>
#include<signal.h>
#include<time.h>
#include<unistd.h>
#include<sys/time.h>


void sigalrm_dispatcher(int signal)
{
    printf("sigalarm dispatcher started (%d)\n",signal);
}


int settimer()
{
    int status;
    struct itimerval timer;
    /* initial interval */
    timer.it_value.tv_sec = 2;
    timer.it_value.tv_usec = 100000;
    /* subsequent intervals */
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 500000;

    if (SIG_ERR == signal ( SIGALRM, sigalrm_dispatcher ))
    {
      printf("Installation of signal handler failed.\n");
    }
    else
    {
      printf("Installation of signal handler successful.\n");
    }


    status = setitimer( ITIMER_REAL, &timer, NULL );
    printf("settimer executed (Status=%d).\n",status);
}

Thanks,

Tilman



Mark H Johnson

Mark H Johnson wrote:

> TIlman Glotzner wrote:
>> Hello,
>> 
>> below my attempt to connect the linux system timer to an ada program.
>> 1) In the process list, I see the program distributed over 5
>> processes. Each signal handler is mapped onto one process. One
>> process is probably needed for the main program. On which part
>> of the program are the other 2 processes mapped to ?
>> 
> 
> The GNAT implementation of tasks on Linux (up until *very* recently) has
> processes for
>   - the main program
>   - a thread manager
>   - a thread per signal being managed
>   - a thread per task
> and they show up as individual processes in ps, top, etc. We ended up
> writing a small library package that would write a file in /tmp/ that
> had our "task name" so we could correlate between PID's and tasks.
> 
> When I mean "very recently", if you are using the new pthread library
> (e.g., Red Hat 9 or later), the rules have changed somewhat and I
> haven't used it enough to comment on it.
> 
>> 2) When the timer expires, the timer signal (SIGALRM) is not catched
>> by the signal handler.  The signal handlers itselves apparrently work as
>> the handlers react to signals sent by a unix kill command. As
>> process number I need to give the PID of the appropriate signal
>> handler. I suspect that the signal is sent to the process that
>> started the itimer. As the signal signal handlers  run as
>> separated processes, the SIGALRM signal issued from the itimer does not
>> reach the signal handlers. What do I need to do to make it work ?
>> 
> What we do instead is to:
>   - determine the process group
>   - use killpg instead of kill to send the signal to the process group
> In this case, the signal is delivered to all the threads and all but one
> thread will ignore it. Only the signal handler will catch it and process
> it.
> 
>> 3) Is there a unix utility that allows me to monitor signals,
>>  i.e. which program issues which signal, and which program catches it ?
>> 
> The latter part can be done with the debugger (gdb). I am not aware of
> any utility to tell you who sent the signal.
> 
>> 4) I first tried to import the system call "setitimer", and hand over
>> setitimer's parameters by access types(ITimervalPtrs'address). The
>> program also compiles if handing over the variables directly (not
>> references to the variables). Is gnat/ada doing a parameter conversion to
>> a reference implicitly for me ?
>> 
> Not sure, we have C code that actually calls setitimer in our system
> :-). You should be able to do something like...
>    pragma Interface(C, Setitimer);
> and use declarations that are compatible with C to call setitimer
> directly from Ada. We do that for a lot of other functions but just not
> that one.
> 
> You may also need
>    pragma Unreserve_All_Interrupts;
> since the run time may also be trapping the specific signals you are
> trying to use.
>    --Mark

-- 
Tilman Glotzner
ETAS Ltd, Seoul, Korea



^ permalink raw reply	[relevance 2%]

* gnat/linux:setitimer
@ 2004-01-03 18:52  2% TIlman Glotzner
    0 siblings, 1 reply; 76+ results
From: TIlman Glotzner @ 2004-01-03 18:52 UTC (permalink / raw)


Hello,

below my attempt to connect the linux system timer to an ada program.
1) In the process list, I see the program distributed over 5
processes. Each signal handler is mapped onto one process. One
process is probably needed for the main program. On which part
of the program are the other 2 processes mapped to ?

2) When the timer expires, the timer signal (SIGALRM) is not catched
by the signal handler.  The signal handlers itselves apparrently work as
the handlers react to signals sent by a unix kill command. As
process number I need to give the PID of the appropriate signal
handler. I suspect that the signal is sent to the process that
started the itimer. As the signal signal handlers  run as
separated processes, the SIGALRM signal issued from the itimer does not 
reach the signal handlers. What do I need to do to make it work ?

3) Is there a unix utility that allows me to monitor signals,
 i.e. which program issues which signal, and which program catches it ?

4) I first tried to import the system call "setitimer", and hand over
setitimer's parameters by access types(ITimervalPtrs'address). The
program also compiles if handing over the variables directly (not
references to the variables). Is gnat/ada doing a parameter conversion to
a reference implicitly for me ?

Thank you,

Tilman

--------------------------------------------------------------
-- Filename: timer.ads
--------------------------------------------------------------
with Type_Defs,System.Address_To_Access_Conversions,Ada.Interrupts.Names;
use Type_Defs,Ada.Interrupts, Ada.Interrupts.Names;

package Timer is

   -- Timers run in real time.
   ITIMER_REAL: constant := 0;

   -- Timers run only when the process is executing.
   ITIMER_VIRTUAL: constant := 1;

   --  Timers run when the process is executing and when
   --  the system is executing on behalf of the process.
   ITIMER_PROF: constant := 2;

   type T_Time is new Long_Integer;

   type T_Timeval is record
      Tv_Sec : T_Time;        -- seconds
      Tv_Usec: T_Time;        -- microseconds
   end record;

   type T_Itimerval is record
      It_Interval: T_Timeval;    -- next value
      It_Value:    T_Timeval;    -- current Value
   end record;

   package TimevalPtrs is new System.Address_To_Access_Conversions( 
T_Timeval );
   package ITimervalPtrs is new System.Address_To_Access_Conversions( 
T_Itimerval );


  
   protected SignalHandler is
      -- SIGINT (Control-C) signals will be intercepted by
      -- HandleControlC
      procedure HandleControlPwrFail;
      pragma Attach_Handler( HandleControlPwrFail, SIGPWR );

      -- Signal handler for SIGALARM issued from a timer
      procedure HandleAlarm;
      pragma Attach_Handler( HandleAlarm,  SIGALRM );
   end SignalHandler;

   procedure Setitimer(RC:out  Integer; Which: in Integer ;
                       Value: in out T_Itimerval;
                       Ovalue: in out T_Itimerval);
   pragma Import (C,Setitimer);
  pragma Import_Valued_Procedure(Setitimer);

end Timer;

--------------------------------------------------------------
-- Filename: timer.adb
--------------------------------------------------------------
with Timer, System.Address_To_Access_Conversions,Text_IO;
use Timer,Text_Io;
package body Timer is
   protected body SignalHandler is
      -- This protected type contains all our signal handlers
      procedure HandleAlarm is
         -- Alarm signal handler
      begin
         Put_Line( "HandleAlarm: ALARMSIG catched." );
      end HandleAlarm;

      procedure HandleControlPwrFail is
         -- Power fail signal handler
      begin
         Put_Line( "HandleControlPwrFail activated by catched signal SIGPWR" 
);
      end HandleControlPwrFail;
   end SignalHandler;
end Timer;

--------------------------------------------------------------
-- Filename: timer_test.adb
--------------------------------------------------------------
with Text_Io,Timer,Ada.Interrupts,Ada.Interrupts.Names;
use Text_Io,Timer,Ada.Interrupts,Ada.Interrupts.Names;

procedure Timer_Test_B is
   Handler : Parameterless_Handler;
   Counter: Integer := 0;
   Timer: aliased T_Itimerval := ((0,10000),(0,10000));
   OldTimer:  aliased T_Itimerval := ((0,0),(0,0));
   I: Integer := 20;
begin
   Put_Line("Timer_Test");
   Put_Line("==========");


   Timer.It_Value.Tv_Sec := 0;
   Timer.It_Value.Tv_Usec := 100000;
   Timer.It_Interval.Tv_Sec  := 0;
   Timer.It_Interval.Tv_Usec := 100000;

   if Is_Reserved( SIGALRM ) then
      Put_Line( "The ALARMSIG handler is reserved" );
   else
      Put_Line( "The ALARMSIG handler isn't reserved" );
  end if;

   if Is_Attached( SIGALRM ) then
      Put_Line( "The ALARMSIG handler is attached" );
   else
      Put_Line( "The ALARMSIG handler isn't attached" );
   end if;

   if Is_Reserved( SIGPWR ) then
      Put_Line( "The SIGPWR handler is reserved" );
   else
      Put_Line( "The SIGPWR handler isn't reserved" );
   end if;

   if Is_Attached( SIGPWR ) then
      Put_Line( "The SIGPWR handler is attached" );
   else
      Put_Line( "The SIGPWR handler isn't attached" );
   end if;

   New_Line;
   Put_Line( "Testing SIGALRM handler..." );

   Handler := Current_Handler( SIGALRM );
   -- Current_Handler gives a callback to the handler
   Handler.all;
   Put_Line( "End testing SIGALRM handler..." );


   New_Line;
   Put_Line( "Testing SIGPWR handler..." );
   Handler := Current_Handler( SIGPWR );
   -- Current_Handler gives a callback to the handler
   Handler.all;
   Put_Line( "End testing SIGPWR handler..." );
   New_Line;

   Put_Line("Timer parameters");
   Put_Line("----------------");
   Put_Line("Time.sec = " & Timer.It_Value.Tv_Sec'Img );
   Put_Line("Time.usec= " & Timer.It_Value.Tv_Usec'Img );
   Put_Line("Preset.sec = " & Timer.It_Interval.Tv_Sec'Img );
   Put_Line("Preset.usec= " & Timer.It_Interval.Tv_Usec'Img );

   New_Line;
   Put("Arming timer...");

   Setitimer(I,ITIMER_REAL,Timer,OldTimer);
--                 ITimervalPtrs.To_Address(Timer'Unchecked_access),
--                 ITimervalPtrs.To_Address(OldTimer'Unchecked_Access));


   Put_Line("  Timer armed.");
   New_Line;

   Put_Line("I := " & I'Img);
   while (Counter <=  I) loop
      null;
--         Counter := Counter + 1;

--         delay(1.0);
      end loop;

end Timer_Test_B;

-- 
Tilman Gloetzner
ETAS Korea Ltd, Seoul, Korea



^ permalink raw reply	[relevance 2%]

* strange execution error
@ 2003-02-22 22:31  2% alfonso acosta
  0 siblings, 0 replies; 76+ results
From: alfonso acosta @ 2003-02-22 22:31 UTC (permalink / raw)


Hi:

I recently started a project in savannah called adabot 
(https://savannah.nongnu.org/projects/adabot/). Its a realtimebattle 
(http://realtimebattle.sourceforge.net/) bot developed completely in Ada.

The problem I have, is the following:

When trying to test a package which isnt finished (messages.ads in
http://savannah.nongnu.org/cgi-bin/viewcvs/adabot/adabot/src/)
with this procedure:

-----
with Ada.Strings.Unbounded.Text_IO, Ada.Interrupts.Names ;
use  Ada.Strings.Unbounded.Text_IO, Ada.Interrupts.Names, Ada.Interrupts;

procedure Messages.Test is

    Msg : Msg_From_Robot;
    Str : Unbounded_String;
begin

    Msg := (RobotOption, (Signal, SIGUSR1));
    Msg2Str (Msg, Str);
    Put (Str);
end Messages.Test;
-----

After compiling with GNAT I execute it and it gets completely frozen, 
the most curious about it is that 4 processes are created. Gdb tells me 
the error comes from messages.adb line 152:


  Append(Source   => Str,
         New_Item => Interrupt_ID'Pos(Msg.Value.Which));

but I dont understand why its wrong

Can anybody have a look at the code?

Thanks in advance:

Alfonso Acosta

PS: If anyone is interested in the project Ill be pleased to give 
him/her a CVS write account (Its obvoius that Im not an experienced Ada 
programmer and need some help)




^ permalink raw reply	[relevance 2%]

* Re: tasking programs built with GNAT insensitive to SIGTERM
  @ 2003-02-04 19:55  1%   ` Craig Carey
  0 siblings, 0 replies; 76+ results
From: Craig Carey @ 2003-02-04 19:55 UTC (permalink / raw)



On Wed, 29 Jan 2003 15:54:38 -0600, Mark Johnson
<mark_h_johnson@raytheon.com> wrote:

>Oliver Kellogg wrote:
...
>> Under Linux, how come tasking programs built with GNAT
>> (3.2, but other versions as well) don't react to
>> "kill -TERM" ?
>> 
>> Is there a trick to make them killable?
>> 

For GNAT 3.15p in Linux with native threads, attaching a signal handler
for SIGTERM (see below) fixes the problem so that the thread can be
terminated with "kill -s TERM <pid>".

Unfortunately 3 new threads that ignored SIGTERM are added if the
method is used (but it is better, since all 4 die if the right thread
is TERM-ed). I sent in a bug report saying that 4 is too many.



>> See also http://gcc.gnu.org/cgi-bin/gnatsweb.pl
>> bug number 9480.
>> 
>Hmm. Very odd behavior. You can probably get what you want by using
>  pragma Interrupt_State (SIGTERM, System);
>

What is the compiler that implements a pragma 'Interrupt_State' ?.
(The GNAT compiler I tried didn't understand that pragma).

>Which forces SIGTERM to be handled as a "system" interrupt. See the GNAT

The simple example of problem 9480 did not try to handle SIGTERM signals.


>Reference Manual for more details. I ran a test program and it appears
>to do what you want it to.
>
>It is odd enough - I may forward it to ACT to see what they say about
>it.

Any information on when GNAT will run as well in Linux as it does in
Windows 200 ?: one Ctrl-C (a plain Windows signal) and the program is
100% removed from memory.

> Also note - you DO have to hit one of the threads that has that
>signal enabled to make it terminate the program. The main program is OK

Isn't that a compiler vendor or OS bug?. SIGKILL terminates all of the
4 threads no matter which of that signal is sent to, so why have only
one of the four take all four down when SIGTERM is the signal ?.


>(usually the process with the lowest PID), but the thread manager
>(usually main PID +1) has the signal masked.


Here is solution but it is not as good as would be hoped for.

(1) The 1.3 second delay statement can be replaced with a 'Timed Entry
 Call':

    AARM 9.7.2 Timed Entry Calls:
    http://www.adaic.org/standards/95aarm/html/AA-9-7-2.html

      --  A protected object stops blocking when SIGTERM was receieved
   select
      Signals.Shutdown;
      goto ... --  exit program
   or
      delay 1.3;
   end select;
   ...
  
   protected Signals is
      procedure SIGTERM_Handler;   --  unblocks the Shutdown barrier
      pragma Interrupt_Handler (SIGTERM_Handler);
      pragma Attach_Handler (SIGTERM_Handler,
                  Ada.Interrupts.Names.SIGTERM);


If the delay was much bigger than 1.3 secs, and also C's exit() was used
to close the program, then the program would readily be stuck in memory
as a zombie, at least in Linux and Linux emulators.
If exit() is not used then the Timed Entry Call is more likely to be
used.




G. A. Craig Carey
http://www.ijs.co.nz/ada_95.htm




^ permalink raw reply	[relevance 1%]

* Re: On-Screen Elapsed Time Display?
  2002-10-11 18:54  1% On-Screen Elapsed Time Display? Dr Nancy's Sweetie
@ 2002-10-11 19:32  0% ` Jeffrey Carter
  0 siblings, 0 replies; 76+ results
From: Jeffrey Carter @ 2002-10-11 19:32 UTC (permalink / raw)


Dr Nancy's Sweetie wrote:
> I searched Google a few times for this, and didn't seem to find it,
> but maybe I just couldn't think of the Right Magic Keywords.  So
> this is probably a stupid newbie question that's been answered 100
> times.  (Maybe the next person to search on the keywords I came up
> with will find this article and the helpful replies.)
> 
> I have written a game, and thought it might be more interesting with
> "best times" file, so people can compete with each other.  It's
> easy enough to add in something like this:
> 
>    type Time_T is new Long_Integer;
>    Start_Time, Win_Time: Time_T;
>    procedure Time ( Time : in out Time_T);
>    pragma Import (C, Time);

You could also use Ada.Calendar (or Ada.Real_Time if that's not accurate 
enough :).

> 
> and then set Win_Time when the player wins, subtract, and figure out
> how long it took.
> 
> What I don't see easily (and maybe I'm just blind) is a good way to
> get a display on the screen (the game uses ncurses) during play.
> I can update the clock every time someone pushes a key, of course,
> but that's kinda lame.
> 
> What I probably need is some Ada version setitimer().  Then it's
> just a matter of set up a function that displays the clock, hook the
> function to SIGALRM, and set the timer to 900ms.  I found the pragma
> "Attach_Handler", and also found SIGALRM in Ada.Interrupts.Names.
> But what's the Ada equivalent of "setitimer();"?
> 
> I can import setitimer(), and make Ada versions of struct timerval
> and itimerval, but that's starting to feel like I'm overusing C,
> and depending on Unixisms (which is bad for portability).
> 
> What is the Right Thing to do?  I'm using GNAT, if that makes any
> difference.

Maybe you want another task that updates the time display every so often 
using "delay until". Then, of course, you have 2 tasks writing to the 
display, so you need to protect it, but that's simple enough. Create a 
protected queue on which tasks can put Strings to be displayed and the 
position at which to display them, then have a 3rd task that takes 
things off this queue and does the display. Have the queue block the 
display task if the queue is empty.

When dealing with an inherently concurrent problem, things are usually 
simpler if you use high-level concurrency constructs.

-- 
Jeff Carter
"Death awaits you all, with nasty, big, pointy teeth!"
Monty Python & the Holy Grail




^ permalink raw reply	[relevance 0%]

* On-Screen Elapsed Time Display?
@ 2002-10-11 18:54  1% Dr Nancy's Sweetie
  2002-10-11 19:32  0% ` Jeffrey Carter
  0 siblings, 1 reply; 76+ results
From: Dr Nancy's Sweetie @ 2002-10-11 18:54 UTC (permalink / raw)


I searched Google a few times for this, and didn't seem to find it,
but maybe I just couldn't think of the Right Magic Keywords.  So
this is probably a stupid newbie question that's been answered 100
times.  (Maybe the next person to search on the keywords I came up
with will find this article and the helpful replies.)

I have written a game, and thought it might be more interesting with
"best times" file, so people can compete with each other.  It's
easy enough to add in something like this:

   type Time_T is new Long_Integer;
   Start_Time, Win_Time: Time_T;
   procedure Time ( Time : in out Time_T);
   pragma Import (C, Time);

and then set Win_Time when the player wins, subtract, and figure out
how long it took.

What I don't see easily (and maybe I'm just blind) is a good way to
get a display on the screen (the game uses ncurses) during play.
I can update the clock every time someone pushes a key, of course,
but that's kinda lame.

What I probably need is some Ada version setitimer().  Then it's
just a matter of set up a function that displays the clock, hook the
function to SIGALRM, and set the timer to 900ms.  I found the pragma
"Attach_Handler", and also found SIGALRM in Ada.Interrupts.Names.
But what's the Ada equivalent of "setitimer();"?

I can import setitimer(), and make Ada versions of struct timerval
and itimerval, but that's starting to feel like I'm overusing C,
and depending on Unixisms (which is bad for portability).

What is the Right Thing to do?  I'm using GNAT, if that makes any
difference.


Thanks,
Darren

Darren Provine ! kilroy@elvis.rowan.edu ! http://www.rowan.edu/~kilroy
"Everybody writes that we have no chance, but, you know, the horse can't
 read." -- Wilson Brown, trainer of Kentucky Derby entry It'sallinthechase,
           May 2002  (odds 50-1 against)



^ permalink raw reply	[relevance 1%]

* Re: Use of entries using Ravenscar
  @ 2001-12-20 13:52  2%     ` Jimmy Dubén
  0 siblings, 0 replies; 76+ results
From: Jimmy Dubén @ 2001-12-20 13:52 UTC (permalink / raw)


> You couldn't provide an actual code example? I've been playing with
> the Ravenscar profile for a few months now and have never had any
> problem with it.

Okidoki.. here goes.
I have three different files below (sorry, I could not send them
along...).
One procedure that uses the PO, and then a package with the PO that
has the entry.
Originally the code was intended to catch a signal but that did not
work with ravenscar either. Strange since I think it is statically
attached.
Pragma(Ravenscar) not shown here (used in gnat.adc next to Makefile)


<<<<<<<<<<<<CODE>>>>>>>>>>>>

>>>>>>>>test_entry.adb

with Ada.Real_Time, Ada.Text_IO, Signal_Handler_Test;
use Ada.Real_Time, Ada.Text_IO, Signal_Handler_Test;

procedure Test_Entry is
   Period        : constant Duration := 5.0;
   Next_Time     : Time;
begin
   loop
      Next_Time := Clock + To_Time_Span (Period);
      delay until Next_Time;

      Protected_Signal_Handler_Test.Read;
   end loop;
end Test_Entry;

>>>>>>>>>signal_handler_test.ads
with
  Ada.Interrupts,
  Ada.Text_IO,
  Ada.Interrupts.Names;

use
  Ada.Interrupts,
  Ada.Text_IO,
  Ada.Interrupts.Names;

package Signal_Handler_Test is

   protected Protected_Signal_Handler_Test is

      --*F
      --* Read entry ...
      --*E
      entry Read;

      --*F
      --* Report that signal USR1 has occured
      --*E
      procedure Something_Arrived;

      -- Attach this certain procedure to the correct signal
      -- NOT ANY MORE
      --pragma Attach_Handler(Something_Arrived, SIGUSR1);

private
      -- Whether or not there is anything to "read"
      Exists_Something   : Boolean := False;
      No_Of_Something   : Integer := 0;


   end Protected_Signal_Handler_Test;

end Signal_Handler_Test;

>>>>>>>>>signal_handler_test.adb

package body Signal_Handler_Test is

   protected body Protected_Signal_Handler_Test is

      
      entry Read when Exists_Something is
      begin

         -- Decrement message counter
         No_Of_Something := No_Of_Something - 1;
         Put_Line("Read: Something is = " & No_Of_Something'img);

         -- (Possibly) allow others to use the entry again
         Exists_Something := No_Of_Something > 0;

      end Read;


      procedure Something_Arrived is
      begin

         Ada.Text_IO.Put_Line("Something_Arrived: A message has
arrived.");

         -- Increment something counter
         No_Of_Something := No_Of_Something + 1;
         Put_Line("Something_Arrived: Something is = " &
No_Of_Something'img);

         -- A something is available now
         Exists_Something := True;

      end Something_Arrived;

   end Protected_Signal_Handler_Test;

end Signal_Handler_Test;

>>>>>>>>>>>>>NO MORE CODE<<<<<<<<<<<<<<

In the system I'm working with we, among other things, want to catch a
signal from a CAN-driver to be able to do a non-blocking read. (We
can't find good drivers to our CAN-module that is working with Linux
2.4.15)



^ permalink raw reply	[relevance 2%]

* Re: Handling signals in ADA
  2001-03-15 18:48  1% ` David Starner
@ 2001-03-16 17:17  2%   ` Robert A Duff
  0 siblings, 0 replies; 76+ results
From: Robert A Duff @ 2001-03-16 17:17 UTC (permalink / raw)


dvdeug@x8b4e53cd.dhcp.okstate.edu (David Starner) writes:

> Someone else posted a literal translation*. The question is, what do you
> want to do? For most Ada programming, signals aren't the right tool for
> the job. Tasks and exceptions can handle many signal uses; others may
> take a little more thought to rewrite, but it's usually better to
> program in the language you're programming in, than force a design for C
> into Ada. (As a side note, SIGUSR1 is not always safe to use in an Ada
> program - GNAT in the standard (ACT) configuration uses it for
> threading.) 

I don't think using signals constitutes "a design for C".  Signals are
an operating system feature.  Many operating systems have similar
features ("per-process interrupts" or "asynchronous system traps" or
whatever).  That includes operating systems that are not so (evilly)
C-centric as Unix.

Anyway, if you want interface to signals, use a protected object with a
pragma Attach_Handler, and the various related features.  I have done
this, for example, to catch control-C interrupts -- portably to both
Unix and Windows.

> * To properly use SIGUSR1, you could write a one line C function 
> returning SIGUSR1 and import it, or write a compile time program that
> finds the value of SIGUSR1 and includes it. If you're using GNAT, you
> should check out Ada.Interrupts.Names and System.OS_Interface, which
> also tell you all the reserved signals.

You should check out Ada.Interrupts.Names even if you're *not* using
GNAT -- this package is standard (although its contents are obviously
system dependent).

- Bob



^ permalink raw reply	[relevance 2%]

* Re: Handling signals in ADA
    2001-03-16  1:27  2%   ` David C. Hoos, Sr.
@ 2001-03-16  3:06  2%   ` (null)
  1 sibling, 0 replies; 76+ results
From: (null) @ 2001-03-16  3:06 UTC (permalink / raw)


In article <87y9u6k7s6.fsf@deneb.enyo.de>,
Florian Weimer  <fw@deneb.enyo.de> wrote:
>Tomas Hlavaty <hlavaty@labe.felk.cvut.cz> writes:
>
>> Hi, could you help me with translating following C code to ADA?
>
>
>The standard Ada library does not support signals.  Typical Ada
>programs use other communication mechanisms, 

Yes, but typical Unix programs use signals.

Florist will have what you want.  You can find those at 

 ftp://ftp.cs.fsu.edu/pub/PART 

Alternatively if you're using the gnat compiler you can the facilities
in Ada.Interrupts.  Here's an example-


-- cut here --
with Ada.Text_IO; use Ada.Text_IO;

with Ada.Interrupts.names;

with Interrupt_Handler; use Interrupt_Handler;

pragma Unreserve_All_Interrupts;

procedure When_Is_It_Over is
   Fat_Lady:  Singer(Ada.Interrupts.Names.SIGINT);
begin
   loop
      New_Line;
      delay 1.0;
      Put("It ain't over...");
      exit when Fat_Lady.Sings;
   end loop;
   Put_Line(" until the fat lady sings.");
end When_Is_It_over;



-- cut here -- 
with Ada.Interrupts;

package Interrupt_Handler is
   protected type Singer (Id: Ada.Interrupts.Interrupt_Id) is
      function Sings return Boolean;
      procedure Handler;
      pragma Attach_Handler(Handler, Id);
   private
      Done: Boolean := False;
   end Singer;
end;

-- cut here --
package body Interrupt_Handler is
   protected body Singer is
      function Sings return Boolean is
      begin
         return Done;
      end Sings;

      procedure handler is
      begin
         done := True;
      end handler;
   end Singer;
end;
-- 
=======================================================================
 Life is short.                  | Craig Spannring 
      Bike hard, ski fast.       | cts@internetcds.com
 --------------------------------+------------------------------------



^ permalink raw reply	[relevance 2%]

* Re: Handling signals in ADA
  2001-03-16  1:27  2%   ` David C. Hoos, Sr.
@ 2001-03-16  1:48  1%     ` Jeffrey Carter
  0 siblings, 0 replies; 76+ results
From: Jeffrey Carter @ 2001-03-16  1:48 UTC (permalink / raw)


"David C. Hoos, Sr." wrote:
> 
>       pragma Attach_Handler
>         (Handle_SIGINT, Ada.Interrupts.Names.SIGINT);
>       pragma Attach_Handler
>         (Handle_SIGUSR1, Ada.Interrupts.Names.SIGUSR1);
>       pragma Attach_Handler
>         (Handle_SIGUSR2, Ada.Interrupts.Names.SIGUSR2);

Since the constants declared in Ada.Interrupts.Names are
implementation-defined, the most you can say is that this works on
certain compilers & OS's, which you should list.

-- 
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail



^ permalink raw reply	[relevance 1%]

* Re: Handling signals in ADA
  @ 2001-03-16  1:27  2%   ` David C. Hoos, Sr.
  2001-03-16  1:48  1%     ` Jeffrey Carter
  2001-03-16  3:06  2%   ` (null)
  1 sibling, 1 reply; 76+ results
From: David C. Hoos, Sr. @ 2001-03-16  1:27 UTC (permalink / raw)



"Florian Weimer" <fw@deneb.enyo.de> wrote in message
news:87y9u6k7s6.fsf@deneb.enyo.de...
> Tomas Hlavaty <hlavaty@labe.felk.cvut.cz> writes:
>
> > Hi, could you help me with translating following C code to ADA?
>
> The programming language is called 'Ada'.
>
> > -- How to translate it to ADA?
>
> The standard Ada library does not support signals.  Typical Ada
> programs use other communication mechanisms, and a verbatim
> translation is not possible.  If you need signal handling because it's
> required by your environment, have a look at POSIX.5.

This answer is just plain wrong. The following program demonstrates
the use of signals in Ada, using only language-defined units.

Now. to be sure, because Ada restricts interrupt handlers to being
parameterless protected procedures, it is not possible to
pass parameter like what can be done under UNIX with the
standard C runtime, for example.

But the "standard Ada library" _DOES_ support signals.

-- begin source code

package body Signal_Handlers
is

   SIG_INT_Received : Boolean := False;

     function SIGINT_RECEIVED return BOOLEAN
     is
     begin
        return SIG_INT_Received;
     end SIGINT_Received;

   protected body Signals
   is
      procedure Handle_SIGINT
      is
      begin
         Ada.Text_IO.Put_Line ("SIGINT received..; Terminating.");
         SIG_INT_Received := True;
      end Handle_SIGINT;
      procedure Handle_SIGUSR1
      is
      begin
         Ada.Text_IO.Put_Line ("SIGUSR1 received and handled.");
      end Handle_SIGUSR1;
      procedure Handle_SIGUSR2
      is
      begin
         Ada.Text_IO.Put_Line ("SIGUSR2 received and handled.");
      end Handle_SIGUSR2;
   end Signals;

end Signal_Handlers;
with Ada.Interrupts.Names;
with Ada.Text_IO;
package Signal_Handlers
is
   pragma Unreserve_All_Interrupts;

   function SIGINT_Received return Boolean;
   protected Signals is
      procedure Handle_SIGINT;
      procedure Handle_SIGUSR1;
      procedure Handle_SIGUSR2;
   private
      pragma Attach_Handler
        (Handle_SIGINT, Ada.Interrupts.Names.SIGINT);
      pragma Attach_Handler
        (Handle_SIGUSR1, Ada.Interrupts.Names.SIGUSR1);
      pragma Attach_Handler
        (Handle_SIGUSR2, Ada.Interrupts.Names.SIGUSR2);
   end Signals;
end Signal_Handlers;
with Ada.Text_IO;
with Signal_Handlers;
procedure Test_Signal_Handler
is
begin
   loop
      exit when Signal_Handlers.SIGINT_Received;
      Ada.Text_IO.Put_Line ("I'm alive...");
      delay 1.0;
   end loop;
end Test_Signal_Handler;
.




^ permalink raw reply	[relevance 2%]

* Re: Handling signals in ADA
  @ 2001-03-15 18:48  1% ` David Starner
  2001-03-16 17:17  2%   ` Robert A Duff
    1 sibling, 1 reply; 76+ results
From: David Starner @ 2001-03-15 18:48 UTC (permalink / raw)


On Tue, 13 Mar 2001 12:09:03 +0100, Tomas Hlavaty
<hlavaty@labe.felk.cvut.cz> wrote:
>Hi, could you help me with translating following C code to ADA?

Someone else posted a literal translation*. The question is, what do you
want to do? For most Ada programming, signals aren't the right tool for
the job. Tasks and exceptions can handle many signal uses; others may
take a little more thought to rewrite, but it's usually better to
program in the language you're programming in, than force a design for C
into Ada. (As a side note, SIGUSR1 is not always safe to use in an Ada
program - GNAT in the standard (ACT) configuration uses it for
threading.) 

However, sometimes the external enviroment hands a signal you have to
handle. In which case, my solution would be to write a little C
encapsulating all the signal details and call it. You could also check
out the Ada packages listed below, or look up Florist, a free Ada Posix
binding.

* To properly use SIGUSR1, you could write a one line C function 
returning SIGUSR1 and import it, or write a compile time program that
finds the value of SIGUSR1 and includes it. If you're using GNAT, you
should check out Ada.Interrupts.Names and System.OS_Interface, which
also tell you all the reserved signals.

-- 
David Starner - dstarner98@aasaa.ofe.org
Pointless website: http://dvdeug.dhis.org
"I don't care if Bill personally has my name and reads my email and 
laughs at me. In fact, I'd be rather honored." - Joseph_Greg



^ permalink raw reply	[relevance 1%]

* Re: Interrupts service
  2001-01-05 12:28  2% Interrupts service Szygula
@ 2001-01-05 13:20  0% ` Marc A. Criley
  0 siblings, 0 replies; 76+ results
From: Marc A. Criley @ 2001-01-05 13:20 UTC (permalink / raw)


What is this program supposed to do?  How does what it is doing differ
from what you expect?  What compiler are you using?  On what platform?

It is much easier to help if you provide that kind of information when
you ask a question like this.

Marc A. Criley
Senior Staff Engineer
Quadrus Corporation
www.quadruscorp.com


Szygula wrote:
> 
> WHAT'S WRONG IN THIS PROGRAM ???
> 
> with Text_Io, Ada.Calendar, Ada.Integer_Text_Io;
> use Text_Io, Ada.Calendar, Ada.Integer_Text_Io;
> with Ada.Interrupts;
> use Ada.Interrupts;
> 
> with Ada.Interrupts.Names;
> use Ada.Interrupts.Names;
> with System; use System;
> with system.storage_elements; use system.storage_elements;
> 
> procedure program is
> 
> type Parameterless_Handler is access protected procedure;
> 
> protected type Sygnal(p:Interrupt_ID)is
> 
> procedure Steruj;
> pragma Interrupt_handler(Steruj);
> pragma Attach_Handler(Steruj,p);
> end Sygnal;
> 
> protected body sygnal is
> 
> procedure Steruj is
> begin
> Put("przerwanie");
> end steruj;
> 
> end sygnal;
> 
> begin
> null;
> 
> end program;
> 
> I NEED INFORMATION OF INTERRUPTS IN ADA95.
> thanks.
> 
> szygula@szygula.prv.pl
> POLAND



^ permalink raw reply	[relevance 0%]

* Interrupts service
@ 2001-01-05 12:28  2% Szygula
  2001-01-05 13:20  0% ` Marc A. Criley
  0 siblings, 1 reply; 76+ results
From: Szygula @ 2001-01-05 12:28 UTC (permalink / raw)


WHAT'S WRONG IN THIS PROGRAM ???


with Text_Io, Ada.Calendar, Ada.Integer_Text_Io;
use Text_Io, Ada.Calendar, Ada.Integer_Text_Io;
with Ada.Interrupts;
use Ada.Interrupts;

with Ada.Interrupts.Names;
use Ada.Interrupts.Names;
with System; use System;
with system.storage_elements; use system.storage_elements;


procedure program is

type Parameterless_Handler is access protected procedure;


protected type Sygnal(p:Interrupt_ID)is

procedure Steruj;
pragma Interrupt_handler(Steruj);
pragma Attach_Handler(Steruj,p);
end Sygnal;


protected body sygnal is

procedure Steruj is
begin
Put("przerwanie");
end steruj;

end sygnal;

begin
null;

end program;


I NEED INFORMATION OF INTERRUPTS IN ADA95.
thanks.

szygula@szygula.prv.pl
POLAND






^ permalink raw reply	[relevance 2%]

* Re: How to lock keys.
  @ 2000-12-15 23:56  2% ` Alexander Antonenko
  0 siblings, 0 replies; 76+ results
From: Alexander Antonenko @ 2000-12-15 23:56 UTC (permalink / raw)


>>>>> "F" == Freelancer  writes:

F> I'm using ObjectAda and programming console programs in win98. I was
F> wondering if someone could tell me how to lock out any keys that I don't
F> want in my program.


F> For example : I would like to lock out CTRL+C so that it doesn't
F> terminate the program.

You can try something like this:

System.Interrupts.Block_Interrupt(
  System.Interrupts.Interrupt_Id(Ada.Interrupts.Names.SIGINT));

I don't know will this work in windows and with compilers other than
GNAT. In any case see packages Ada.Interrupts & System.Interrupts.

F> Thanks for your help! :)

-- 
Alexander Antonenko
mailto:alexa@i.com.ua
mailto:aga@mix.meow.kiev.ua

I suppose you think I think I know it all
		-- Ozzy



^ permalink raw reply	[relevance 2%]

* more information on OS and compiler
  2000-01-06  0:00  1% question about COM2 Alexander Van Hecke
@ 2000-01-07  0:00  0% ` Alexander Van Hecke
  0 siblings, 0 replies; 76+ results
From: Alexander Van Hecke @ 2000-01-07  0:00 UTC (permalink / raw)


I was asked to give more information on the OS I intend to run this program
on : It should run on MS-DOS.  I use the gnat compiler on Windows 98 (which
can generate DOS code right?).  Any help greatly appreciated.


"Alexander Van Hecke" <alexke@hotmail.com> wrote in message
news:3874C02F.53CE5769@hotmail.com...
> hi all,
>
> I have a question about a program I am writing in Ada.  The program
> should do the following (I know, it's not much :-)) : you type a number
> (INTEGER) on computer 1, this computer sends the number to computer 2
> via nullmodem connected to COM2, you type a number on computer 2, and
> send this number back to computer 1.  both computers do some
> calculations with these numbers and then give some output.  I have been
> trying to write a device driver for the serial port communication, but
> I'm stuck.  I don't know what the Interrupt_ID is for serial
> communication : in the function Attach_Handler you must pass your
> interrupt handler routine and the interrupt ID.  I don't know what this
> is for serial communication, and when I look on the internet, I only
> find examples in C (interrupt ID for serial port is 0xC or 0xB or
> something like that : it doesn't work in Ada).  The ultimate goal is to
> write a package that contains two routines : Send_Number(..) and
> Get_Number(...).  The numbers that must be sent should be several (> 2)
> bytes, so they should probably be split.  Allthough I know my way around
> with C, I have no previous experience with Ada.  Does anybody know the
> solution to this problem?  I will attach my code as it is right now.
> Any comments / suggestions are very welcome!
>
> Thanks in advance,
> alex
>
>
>


----------------------------------------------------------------------------
----


> -- dit is de Serial_Device_Driver package
> -- let op : we werken met COM2!
> -- dwz : TX en RX buffer op 2F8H
> -- divisor latch register op 2F8H en 2F9H
> -- line control register op 2FBH
> -- line status register op 2FDH
>
> package Serial_Device_Driver is
> type 2bits is range 0..3;
> procedure Get_Number(getal : out INTEGER);
> procedure Send_Number(getal : in INTEGER);
>
> private :
> for 2bits'Size use 2; -- er mogen slechts 2 bits voor gebruikt worden;
>
> end Serial_Device_Driver;
>
> with Ada.Interrupts.Names, System, System.Storage_Elements;
> use Ada.Interrupts.Names, System, System.Storage_Elements;
>
> package body Serial_Device_Driver is
> Bits_In_Word : constant := 16;
> Bits_In_Byte : constant := 8;
> Word : constant := 2;
> type Flag in (Down, Set);
>
> type Line_Control_Register is
> record
> DL_access : Flag; -- divisor latch access bit
> break_control : Flag; -- set break control
> stick_parity : Flag; -- stick parity
> even_parity : Flag; -- even parity select
> parity_enable : Flag; -- parity enable
> stop_bits : Flag; -- stop bits
> word_length : 2bits; -- word length : zet op 11
> end record;
>
> -- nu specifieren we de layout
>
> for Line_Control_Register use
> record
> DL_acces at 0*Word range 7..7;
> break_control at 0*Word range 6..6;
> stick_parity at 0*Word range 5..5;
> even_parity at 0*Word range 4..4;
> parity_enable at 0*Word range 3..3;
> stop_bits at 0*Word range 2..2;
> word_length at 0*Word range 0..1;
> end record;
>
> for Line_Control_Register'Size use Bits_In_Byte; -- het register is 8 bits
> for Line_Control_Register'Alignment use Word;
> for Line_Control_Register'Bit_order us Low_Order_First; -- LSB = 0;
>
>
> type Line_Status_Register is
> record
> TSR_empty : Flag; -- Trans-shift-register empty
> THR_empty : Flag; -- Trans-hold-register empty
> Break_Int : Flag; -- Break interrupt indicator
> Framing_err : Flag; -- Framing error indicator
> Par_err : Flag; -- Parity error indicator
> Overrun_err : Flag; -- Overrun error indicator
> rec_data_ready : Flag; -- Receiver data ready
> end record;
>
> -- nu specifieren we de layout
>
> for Line_Status_Register use
> record
> TSR_empty at 0*Word range 6..6;
> THR_empty at 0*Word range 5..5;
> Break_Int at 0*Word range 4..4;
> Framing_err at 0*Word range 3..3;
> Par_err at 0*Word range 2..2;
> Overrun_err at 0*Word range 1..1;
> rec_data_ready at 0*Word range 0..0;
> end record;
>
> for Line_Status_Register'Size use Bits_In_Byte; -- het register is 8 bits
> for Line_Status_Register'Alignment use Word;
> for Line_Status_Register'Bit_order us Low_Order_First; -- LSB = 0;
>
> -- als bit 7 van het line control register 1 is, dan zijn de adressen 3F8H
en 3F9H voor
> -- het divisor latch register
> -- als bit 7 van het line control register 0 is, dan zijn de adressen 3F8H
en 3F9H voor
> -- het verzenden en ontvangen van data
> -- we moeten dus eerst op allebei de computers bit 7 van het line control
register op
> -- 1 zetten, zodat we de baudsnelheid kunnen selecteren;
> -- als dit gedaan is, zetten we bit 7 van het line control register op 0,
zodat we
> -- de adressen 3F8H en 3F9H kunnen gebruiken als dataregister.
>
> type Divisor_Latch_Register is
> record
> baud_rate : INTEGER;
> end record;
>
> -- specifieren van de layout
>
> for Divisor_Latch_Register use
> record
> baud_rate at 0*Word range 0..15;
> end record;
>
>
> for Divisor_Latch_Register'Size use Bits_In_Word; -- het register is 16
bits
> for Divisor_Latch_Register'Alignment use Word;
> for Divisor_Latch_Register'Bit_order us Low_Order_First; -- LSB = 0;
>
> type Data_Register is INTEGER; -- alle mogelijke getallen kunnen voorkomen
in het data register
> for Data_Register'Size use Bits_In_Word;
>
> Contr_Reg_Addr: constant Address := To_Address(16#2FB#);
> Stat_Reg_Addr : constant Address := To_Address(16#2FD#);
> Latch_Reg_Addr : constant Address := To_Address(16#2F8#);
> Data_Reg_Addr : constant Address := To_Address(16#2F8#);
> Serial_Priority : constant Interrupt_Priority := 63;
>
> Control_Reg : aliased Line_Control_Register;
> for Control_Reg'Address use Contr_Reg_Addr;
>
> Status_Reg : aliased Line_Status_Register;
> for Status_Reg'Address use Stat_Reg_Addr;
>
> Latch_Reg : aliased Divisor_Latch_Register;
> for Latch_Reg'Address use Latch_Reg_Addr;
>
> Data_Reg : aliased Data_Register;
> for Data_Reg'Address use Data_Reg_Addr;
>
>
> -- nu de interrupt interface nog schrijven
>
> protected type Interrupt_Interface(Int_Id : Interrupt_Id;
> Cr : access Line_Control_Register;
> Sr : access Line_Status_Register;
> Lr : access Divisor_Latch_Register;
> Dr : access Data_Register) is
>
> entry Read(getal : out INTEGER); -- het uitlezen van een getal
> entry Write(getal : in INTEGER); -- het schrijven van een getal
> private :
> entry Done(getal : out INTEGER);
> procedure Handler;
> pragma Attach_Handler(Handler, Int_Id)
> pragma Interrupt_Priority(Serial_Priority)
> Interrupt_Occurred : Boolean := False;
> Next_Request : Boolean := True;
> end Interrupt_Interface;
>
> Serial_Interface : Interrupt_Interface(Names.Serial, Control_Reg'Address,
> Status_Reg'Address, Latch_Reg'Address, Data_Reg'Address);
>
> protected body Interrupt_Interface is
>
> entry Read(getal : out INTEGER) when Next_Request is
> Shadow_Register : Control_Register;
> begin
> -- shadow register invullen
> -- en copieren naar controle register
> -- data lezen
>
> Interrupt_Occurred := False;
> Next_Request := False;
> requeue Done;
> end Read;
>
> entry Write(getal : in INTEGER) when not Next_Request is
> Shadow_Register : ???
> begin
> ???
> end Write;
>
> procedure Handler is
> begin
> Interrupt_Occurred := True;
> end Handler;
>
> entry Done(getal : out INTEGER) when Interrupt_Occurred is
> begin
> Next_Request := True;
> -- uitlezen van de data in het getal;
> -- checken op errors?
> end Done;
>
> end Interrupt_Interface;
>
> procedure Get_Number(getal : out INTEGER) is
> begin
> Serial_Interface.Read(getal);
> end Get_Number;
>
> procedure Send_Number(getal : in INTEGER) is
> begin
> -- opsplitsen van getal in afzonderlijke groepjes van 2 bytes!
> -- in het datareg kunnen maar 16 bits tegelijk
>     Serial_Interface.Write(getal);
> end Send_Number;
> end Serial_Device_Driver;
>






^ permalink raw reply	[relevance 0%]

* question about COM2
@ 2000-01-06  0:00  1% Alexander Van Hecke
  2000-01-07  0:00  0% ` more information on OS and compiler Alexander Van Hecke
  0 siblings, 1 reply; 76+ results
From: Alexander Van Hecke @ 2000-01-06  0:00 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 1321 bytes --]

hi all,

I have a question about a program I am writing in Ada.  The program
should do the following (I know, it's not much :-)) : you type a number
(INTEGER) on computer 1, this computer sends the number to computer 2
via nullmodem connected to COM2, you type a number on computer 2, and
send this number back to computer 1.  both computers do some
calculations with these numbers and then give some output.  I have been
trying to write a device driver for the serial port communication, but
I'm stuck.  I don't know what the Interrupt_ID is for serial
communication : in the function Attach_Handler you must pass your
interrupt handler routine and the interrupt ID.  I don't know what this
is for serial communication, and when I look on the internet, I only
find examples in C (interrupt ID for serial port is 0xC or 0xB or
something like that : it doesn't work in Ada).  The ultimate goal is to
write a package that contains two routines : Send_Number(..) and
Get_Number(...).  The numbers that must be sent should be several (> 2)
bytes, so they should probably be split.  Allthough I know my way around
with C, I have no previous experience with Ada.  Does anybody know the
solution to this problem?  I will attach my code as it is right now.
Any comments / suggestions are very welcome!

Thanks in advance,
alex



[-- Attachment #2: Serial_Device_Driver.ada --]
[-- Type: text/plain, Size: 6159 bytes --]

-- dit is de Serial_Device_Driver package
-- let op : we werken met COM2!
-- dwz : TX en RX buffer op 2F8H
-- divisor latch register op 2F8H en 2F9H
-- line control register op 2FBH
-- line status register op 2FDH

package Serial_Device_Driver is
	type 2bits is range 0..3;
	procedure Get_Number(getal : out INTEGER);
	procedure Send_Number(getal : in INTEGER);

private : 
	for 2bits'Size use 2;	-- er mogen slechts 2 bits voor gebruikt worden;

end Serial_Device_Driver;

with Ada.Interrupts.Names, System, System.Storage_Elements;
use Ada.Interrupts.Names, System, System.Storage_Elements;

package body Serial_Device_Driver is
	Bits_In_Word : constant := 16;
	Bits_In_Byte : constant := 8;
	Word : constant := 2;
	type Flag in (Down, Set);

	type Line_Control_Register is
	record
		DL_access : Flag;					-- divisor latch access bit
		break_control : Flag;			-- set break control
		stick_parity : Flag;			-- stick parity
		even_parity : Flag;				-- even parity select
		parity_enable : Flag;			-- parity enable
		stop_bits : Flag;					-- stop bits
		word_length : 2bits;			-- word length : zet op 11
	end record;

-- nu specifieren we de layout

	for Line_Control_Register use
	record
		DL_acces 			at 0*Word range 7..7;
		break_control at 0*Word range 6..6;
		stick_parity 	at 0*Word range 5..5;
		even_parity		at 0*Word range 4..4;
		parity_enable at 0*Word range 3..3;
		stop_bits			at 0*Word range 2..2;
		word_length		at 0*Word range 0..1;
	end record;

	for Line_Control_Register'Size use Bits_In_Byte;		-- het register is 8 bits
	for Line_Control_Register'Alignment use Word;
	for Line_Control_Register'Bit_order us Low_Order_First;	-- LSB = 0;


	type Line_Status_Register is
	record
		TSR_empty : Flag;					-- Trans-shift-register empty
		THR_empty : Flag;					-- Trans-hold-register empty
		Break_Int : Flag;					-- Break interrupt indicator
		Framing_err : Flag;				-- Framing error indicator
		Par_err : Flag;						-- Parity error indicator
		Overrun_err : Flag;				-- Overrun error indicator
		rec_data_ready : Flag;		-- Receiver data ready
	end record;

-- nu specifieren we de layout

	for Line_Status_Register use
	record
		TSR_empty 			at 0*Word range 6..6;
		THR_empty				at 0*Word range 5..5;
		Break_Int				at 0*Word range 4..4;
		Framing_err			at 0*Word range 3..3;
		Par_err					at 0*Word range 2..2;
		Overrun_err			at 0*Word range 1..1;
		rec_data_ready	at 0*Word range 0..0;
	end record;

	for Line_Status_Register'Size use Bits_In_Byte;		-- het register is 8 bits
	for Line_Status_Register'Alignment use Word;
	for Line_Status_Register'Bit_order us Low_Order_First;	-- LSB = 0;

-- als bit 7 van het line control register 1 is, dan zijn de adressen 3F8H en 3F9H voor
-- het divisor latch register
-- als bit 7 van het line control register 0 is, dan zijn de adressen 3F8H en 3F9H voor
-- het verzenden en ontvangen van data
-- we moeten dus eerst op allebei de computers bit 7 van het line control register op
-- 1 zetten, zodat we de baudsnelheid kunnen selecteren;
-- als dit gedaan is, zetten we bit 7 van het line control register op 0, zodat we
-- de adressen 3F8H en 3F9H kunnen gebruiken als dataregister.

	type Divisor_Latch_Register is
	record
		baud_rate : INTEGER;
	end record;

-- specifieren van de layout

	for Divisor_Latch_Register use
	record
		baud_rate at 0*Word range 0..15;
	end record;


	for Divisor_Latch_Register'Size use Bits_In_Word;		-- het register is 16 bits
	for Divisor_Latch_Register'Alignment use Word;
	for Divisor_Latch_Register'Bit_order us Low_Order_First;	-- LSB = 0;

	type Data_Register is INTEGER;		-- alle mogelijke getallen kunnen voorkomen in het data register
	for Data_Register'Size use Bits_In_Word;

	Contr_Reg_Addr: constant Address := To_Address(16#2FB#);
	Stat_Reg_Addr : constant Address := To_Address(16#2FD#);
	Latch_Reg_Addr : constant Address := To_Address(16#2F8#);
	Data_Reg_Addr : constant Address := To_Address(16#2F8#);
	Serial_Priority : constant Interrupt_Priority := 63;

	Control_Reg : aliased Line_Control_Register;
	for Control_Reg'Address use Contr_Reg_Addr;

	Status_Reg : aliased Line_Status_Register;
	for Status_Reg'Address use Stat_Reg_Addr;

	Latch_Reg : aliased Divisor_Latch_Register;
	for Latch_Reg'Address use Latch_Reg_Addr;

	Data_Reg : aliased Data_Register;
	for Data_Reg'Address use Data_Reg_Addr; 


-- nu de interrupt interface nog schrijven

	protected type Interrupt_Interface(Int_Id : Interrupt_Id;
		Cr : access Line_Control_Register;
		Sr : access Line_Status_Register;
		Lr : access Divisor_Latch_Register;
		Dr : access Data_Register) is
		
		entry Read(getal : out INTEGER);		-- het uitlezen van een getal
		entry Write(getal : in INTEGER); 		-- het schrijven van een getal
private :	
		entry Done(getal : out INTEGER);
		procedure Handler;
		pragma Attach_Handler(Handler, Int_Id)
		pragma Interrupt_Priority(Serial_Priority)
		Interrupt_Occurred : Boolean := False;
		Next_Request : Boolean := True;
	end Interrupt_Interface;

	Serial_Interface : Interrupt_Interface(Names.Serial, Control_Reg'Address, 
											Status_Reg'Address, Latch_Reg'Address, Data_Reg'Address);

	protected body Interrupt_Interface is

		entry Read(getal : out INTEGER) when Next_Request is
			Shadow_Register : Control_Register;
		begin
			-- shadow register invullen
			-- en copieren naar controle register
			-- data lezen

			Interrupt_Occurred := False;
			Next_Request := False;
			requeue Done;
		end Read;

		entry Write(getal : in INTEGER) when not Next_Request is
			Shadow_Register : ???
		begin
			???
		end Write;

		procedure Handler is
		begin
			Interrupt_Occurred := True;
		end Handler;

		entry Done(getal : out INTEGER) when Interrupt_Occurred is
		begin
			Next_Request := True;
			-- uitlezen van de data in het getal;
			-- checken op errors?
		end Done;

	end Interrupt_Interface;

	procedure Get_Number(getal : out INTEGER) is
	begin
		Serial_Interface.Read(getal);
	end Get_Number;

	procedure Send_Number(getal : in INTEGER) is
	begin
		-- opsplitsen van getal in afzonderlijke groepjes van 2 bytes!
		-- in het datareg kunnen maar 16 bits tegelijk
    Serial_Interface.Write(getal);
	end Send_Number;
end Serial_Device_Driver;

^ permalink raw reply	[relevance 1%]

* Interrupt problem in GNAT
@ 1999-05-19  0:00  2% Joerg Kienzle
  0 siblings, 0 replies; 76+ results
From: Joerg Kienzle @ 1999-05-19  0:00 UTC (permalink / raw)



Hi,

I am running gnat 3.11w on Solaris, and I am trying to use interrupts to
perform a periodic operation. I have declared the following package:

with Ada.Interrupts; use Ada.Interrupts;
with Ada.Interrupts.Names; use Ada.Interrupts.Names;

package Clocks is

   protected Clock is
      procedure Tick;
      pragma Interrupt_Handler (Tick);
      pragma Attach_Handler (Tick, SIGALRM);
   end Clock;

end Clocks;

And the body:

package body Clocks is

   protected body Clock is

      procedure Tick is
      begin
	--  Do something here
      end Tick;

   end Clock;

end Clocks;

As you can see in the spec, I am trying to attach the Tick procedure
to the SIGALRM signal. In my main procedure, I use the operating
system functions timer_create and timer_settime to tell the OS to
send SIGALRM to my process every x seconds.
This works; the process gets a SIGALRM signal, but my handler function
in not called! Instead, "Alarm clock" is printed on the terminal and
the process exits...
The same thing happens if I use the "alarm" function to send
the SIGALRM signal:

with Interfaces.C;
with Clocks;

procedure Main is

   procedure Alarm (Sec : C.Unsigned);
   pragma Import (C, Alarm, "alarm");

   procedure Set_Alarm (I : in Natural);

   procedure Set_Alarm (I : in Natural) is
   begin
      Alarm (C.Unsigned (I));
   end Set_Alarm;

begin

   Set_Alarm (5);

   while True loop
      null;
   end loop;

end Main;


I tried other signals, but I still doesn't work.
What am I doing wrong?

- J�rg

-- 
---------------------------------------------------------------------------
- Joerg Kienzle - Swiss Federal Institue of Technology - CH-1015
Lausanne -
- email : Joerg.Kienzle@epfl.ch    WWW :
http://lglwww.epfl.ch/~jkienzle/ -
- phone : ++41 21 693 42 37        fax : ++41 21 693 50
79                -




^ permalink raw reply	[relevance 2%]

* Re: Ada83 and Ada95 interrupt handling
  @ 1999-03-05  0:00  1% ` Robert A Duff
  0 siblings, 0 replies; 76+ results
From: Robert A Duff @ 1999-03-05  0:00 UTC (permalink / raw)


Armin <ArminSchmidle@swol.de> writes:

> I am porting an Ada83 application to Ada95. In Ada83 there was a
> construction
> known as interrupt entry.
...
> How can I do the same thing in Ada95 ?

I just happened to be working on some examples of interrupt handling for
our (Averstar's) AdaMagic for SHARC implementation, which we validated
last month.

When using a protected procedure as an interrupt handler, there are (at
least) two ways to make the handler notify a task that the interrupt has
occurred.  You can have the task wait on an entry of the same protected
object as the interrupt handler.  Or, you can use suspension objects.

Here's an extract from the documentation I wrote:

...
Example 2.

The second example prints the following:

 Hello from Interrupt_Test_With_Entries main procedure.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Waiting_Task: Got interrupt.
 Generating interrupt.
 Goodbye from Interrupt_Test_With_Entries main procedure.
 Waiting_Task: Got interrupt.
 Goodbye from Waiting_Task.

----------------------------------------------------------------

-- This example illustrates how an interrupt handler (a protected
-- procedure) may communicate with a task using an entry.  The interrupt
-- handler is called when the interrupt occurs, and it causes the
-- entry's barrier to become True.  The task waits by calling the entry;
-- it is blocked until the barrier becomes True.

-- In this example, we simulate 10 interrupts, and we have a task
-- (Waiting_Task) that waits for 10 interrupts by calling the entry.
-- Each interrupt triggers one call to the entry to proceed.  In this
-- example, the only information being transmitted back to the waiting
-- task is the fact that the interrupt has occurred.

-- In a real program, the protected object might have additional
-- operations to do something to some external device (e.g. initiate
-- some I/O).  This might cause the device to generate an interrupt.
-- The interrupt would not be noticed until after this operation
-- returns, even if the device generates the interrupt right away;
-- that's because of the priority rules.  Also, the interrupt handler
-- might get some information from the device, save it locally in the
-- protected object, and then the entry body might pass this information
-- back to the task via an 'out' parameter.

-- In other words, a protected object used in this way acts as a "device
-- driver", containing operations to initiate I/O operations, to wait
-- for operations to complete, and to handle interrupts.  Anything that
-- needs to be done while masking the interrupt of the device should be
-- part of the protected object.

-- Note that if multiple device drivers are needed for similar devices,
-- it is convenient to declare a protected type, and declare multiple
-- objects of that type.  Discriminants can be used to pass in
-- information specific to individual devices.

----------------------------------------------------------------

with Ada.Interrupts.Names; use Ada.Interrupts.Names;
with System.RTS.Temp_IO; use System.RTS.Temp_IO;

package Interrupt_Test_With_Entries is

    -- Empty.

end Interrupt_Test_With_Entries;

----------------------------------------------------------------

package Interrupt_Test_With_Entries.Handlers is

    pragma Elaborate_Body;

    protected Handler_PO is

        procedure Handler; -- The interrupt handler.
        pragma Attach_Handler(Handler, SFT0I);
            -- SFT0I is declared in Ada.Interrupts.Names.

        entry Await_Interrupt;
            -- Each time Handler is called,
            -- this entry is triggered.

    private

        Interrupt_Occurred: Boolean := False;

    end Handler_PO;

end Interrupt_Test_With_Entries.Handlers;

----------------------------------------------------------------

package body Interrupt_Test_With_Entries.Handlers is

    protected body Handler_PO is

        procedure Handler is
        begin
            Interrupt_Occurred := True;
        end Handler;

        entry Await_Interrupt when Interrupt_Occurred is
        begin
            Interrupt_Occurred := False;
        end Await_Interrupt;

    end Handler_PO;

end Interrupt_Test_With_Entries.Handlers;

----------------------------------------------------------------

package Interrupt_Test_With_Entries.Waiting_Tasks is

    pragma Elaborate_Body; -- So the body is allowed.

end Interrupt_Test_With_Entries.Waiting_Tasks;

----------------------------------------------------------------

with Interrupt_Test_With_Entries.Handlers; use Interrupt_Test_With_Entries.Handlers;
package body Interrupt_Test_With_Entries.Waiting_Tasks is

    task Waiting_Task;

    task body Waiting_Task is
    begin
        for I in 1..10 loop
            Handler_PO.Await_Interrupt;
            Put_Line("Waiting_Task: Got interrupt.");
        end loop;
        Put_Line("Goodbye from Waiting_Task.");
    end Waiting_Task;

end Interrupt_Test_With_Entries.Waiting_Tasks;

----------------------------------------------------------------

with System.Machine_Intrinsics;

with Interrupt_Test_With_Entries.Waiting_Tasks;
    -- There are no references to this package; this with_clause is here
    -- so that task Waiting_Task will be included in the program.

procedure Interrupt_Test_With_Entries.Main is

    procedure Generate_Interrupt(Interrupt : Ada.Interrupts.Interrupt_ID) is
        -- This uses machine code intrinsics to simulate a hardware
        -- interrupt, by generating an interrupt in software.

        use System.Machine_Intrinsics;

        -- This sets the N'th bit in IRPTL, where N is the interrupt number,
        -- which causes the interrupt to happen; see page 3-26 of the
        -- ADSP-2106x SHARC Users' Manual, Second Edition.
        -- We want to use the BIT SET instruction, so it's atomic,
        -- but that instruction requires an immediate value;
        -- we can't calculate 2**N and use that as the mask;
        -- hence the rather repetitive code below.

        procedure Gen_0 is
            pragma Inline(Gen_0);
        begin
            Asm("BIT SET IRPTL 0x00000001;");
        end Gen_0;

        procedure Gen_1 is
            pragma Inline(Gen_1);
        begin
            Asm("BIT SET IRPTL 0x00000002;");
        end Gen_1;

        procedure Gen_2 is
            pragma Inline(Gen_2);
        begin
            Asm("BIT SET IRPTL 0x00000004;");
        end Gen_2;

        procedure Gen_3 is
            pragma Inline(Gen_3);
        begin
            Asm("BIT SET IRPTL 0x00000008;");
        end Gen_3;

        procedure Gen_4 is
            pragma Inline(Gen_4);
        begin
            Asm("BIT SET IRPTL 0x00000010;");
        end Gen_4;

        procedure Gen_5 is
            pragma Inline(Gen_5);
        begin
            Asm("BIT SET IRPTL 0x00000020;");
        end Gen_5;

        procedure Gen_6 is
            pragma Inline(Gen_6);
        begin
            Asm("BIT SET IRPTL 0x00000040;");
        end Gen_6;

        procedure Gen_7 is
            pragma Inline(Gen_7);
        begin
            Asm("BIT SET IRPTL 0x00000080;");
        end Gen_7;

        procedure Gen_8 is
            pragma Inline(Gen_8);
        begin
            Asm("BIT SET IRPTL 0x00000100;");
        end Gen_8;

        procedure Gen_9 is
            pragma Inline(Gen_9);
        begin
            Asm("BIT SET IRPTL 0x00000200;");
        end Gen_9;

        procedure Gen_10 is
            pragma Inline(Gen_10);
        begin
            Asm("BIT SET IRPTL 0x00000400;");
        end Gen_10;

        procedure Gen_11 is
            pragma Inline(Gen_11);
        begin
            Asm("BIT SET IRPTL 0x00000800;");
        end Gen_11;

        procedure Gen_12 is
            pragma Inline(Gen_12);
        begin
            Asm("BIT SET IRPTL 0x00001000;");
        end Gen_12;

        procedure Gen_13 is
            pragma Inline(Gen_13);
        begin
            Asm("BIT SET IRPTL 0x00002000;");
        end Gen_13;

        procedure Gen_14 is
            pragma Inline(Gen_14);
        begin
            Asm("BIT SET IRPTL 0x00004000;");
        end Gen_14;

        procedure Gen_15 is
            pragma Inline(Gen_15);
        begin
            Asm("BIT SET IRPTL 0x00008000;");
        end Gen_15;

        procedure Gen_16 is
            pragma Inline(Gen_16);
        begin
            Asm("BIT SET IRPTL 0x00010000;");
        end Gen_16;

        procedure Gen_17 is
            pragma Inline(Gen_17);
        begin
            Asm("BIT SET IRPTL 0x00020000;");
        end Gen_17;

        procedure Gen_18 is
            pragma Inline(Gen_18);
        begin
            Asm("BIT SET IRPTL 0x00040000;");
        end Gen_18;

        procedure Gen_19 is
            pragma Inline(Gen_19);
        begin
            Asm("BIT SET IRPTL 0x00080000;");
        end Gen_19;

        procedure Gen_20 is
            pragma Inline(Gen_20);
        begin
            Asm("BIT SET IRPTL 0x00100000;");
        end Gen_20;

        procedure Gen_21 is
            pragma Inline(Gen_21);
        begin
            Asm("BIT SET IRPTL 0x00200000;");
        end Gen_21;

        procedure Gen_22 is
            pragma Inline(Gen_22);
        begin
            Asm("BIT SET IRPTL 0x00400000;");
        end Gen_22;

        procedure Gen_23 is
            pragma Inline(Gen_23);
        begin
            Asm("BIT SET IRPTL 0x00800000;");
        end Gen_23;

        procedure Gen_24 is
            pragma Inline(Gen_24);
        begin
            Asm("BIT SET IRPTL 0x01000000;");
        end Gen_24;

        procedure Gen_25 is
            pragma Inline(Gen_25);
        begin
            Asm("BIT SET IRPTL 0x02000000;");
        end Gen_25;

        procedure Gen_26 is
            pragma Inline(Gen_26);
        begin
            Asm("BIT SET IRPTL 0x04000000;");
        end Gen_26;

        procedure Gen_27 is
            pragma Inline(Gen_27);
        begin
            Asm("BIT SET IRPTL 0x08000000;");
        end Gen_27;

        procedure Gen_28 is
            pragma Inline(Gen_28);
        begin
            Asm("BIT SET IRPTL 0x10000000;");
        end Gen_28;

        procedure Gen_29 is
            pragma Inline(Gen_29);
        begin
            Asm("BIT SET IRPTL 0x20000000;");
        end Gen_29;

        procedure Gen_30 is
            pragma Inline(Gen_30);
        begin
            Asm("BIT SET IRPTL 0x40000000;");
        end Gen_30;

        procedure Gen_31 is
            pragma Inline(Gen_31);
        begin
            Asm("BIT SET IRPTL 0x80000000;");
        end Gen_31;

        subtype Handleable_Range is Ada.Interrupts.Interrupt_ID
          range 0..31; -- These are the only interrupts that
                       -- actually exist in the hardware.
    begin
        case Handleable_Range'(Interrupt) is
            when 0 => Gen_0;
            when 1 => Gen_1;
            when 2 => Gen_2;
            when 3 => Gen_3;
            when 4 => Gen_4;
            when 5 => Gen_5;
            when 6 => Gen_6;
            when 7 => Gen_7;
            when 8 => Gen_8;
            when 9 => Gen_9;
            when 10 => Gen_10;
            when 11 => Gen_11;
            when 12 => Gen_12;
            when 13 => Gen_13;
            when 14 => Gen_14;
            when 15 => Gen_15;
            when 16 => Gen_16;
            when 17 => Gen_17;
            when 18 => Gen_18;
            when 19 => Gen_19;
            when 20 => Gen_20;
            when 21 => Gen_21;
            when 22 => Gen_22;
            when 23 => Gen_23;
            when 24 => Gen_24;
            when 25 => Gen_25;
            when 26 => Gen_26;
            when 27 => Gen_27;
            when 28 => Gen_28;
            when 29 => Gen_29;
            when 30 => Gen_30;
            when 31 => Gen_31;
        end case;
    end Generate_Interrupt;

begin

    -- Generate 10 simulated interrupts, with delays in between.

    Put_Line("Hello from Interrupt_Test_With_Entries main procedure.");
    for I in 1..10 loop
        delay 0.01;
        Put_Line("Generating interrupt.");
        Generate_Interrupt(SFT0I);
    end loop;
    Put_Line("Goodbye from Interrupt_Test_With_Entries main procedure.");

end Interrupt_Test_With_Entries.Main;

================================================================
================================================================

Example 3.

The third example prints the following:

 Hello from Suspension_Objects_Test main procedure. 
 Generating interrupt. 
 Waiting_Task: Got interrupt. 
 Generating interrupt. 
 Waiting_Task: Got interrupt. 
 Generating interrupt. 
 Waiting_Task: Got interrupt. 
 Generating interrupt. 
 Waiting_Task: Got interrupt. 
 Goodbye from Waiting_Task. 
 Generating interrupt. 
 Generating interrupt. 
 Generating interrupt. 
 Generating interrupt. 
 Generating interrupt. 
 Generating interrupt. 
 Goodbye from Suspension_Objects_Test main procedure. 

-- This example illustrates how an interrupt handler
-- (a protected procedure) may communicate with a task
-- using a suspension object.  A suspension object allows a
-- task or interrupt handler to notify another task that some
-- event (in our case, an interrupt) has occurred.
-- Each time the interrupt occurs, the suspension object is set to True.
-- The task waits for this event by calling Suspend_Until_True.

-- In this example, we simulate some interrupts,
-- and we have a task (Waiting_Task) that waits for them
-- using a suspension object called Interrupt_Occurred.

-- Note that if the task is already waiting (the usual case) when the
-- interrupt occurs, Interrupt_Occurred is only set to True momentarily;
-- Suspend_Until_True automatically resets it to False.  If the task is
-- not waiting, then the True state will be remembered, and when the
-- task gets around to waiting, it will reset it to False and proceed
-- immediately.

-- Note that only one task can wait on a given suspension object; it's
-- sort of like a protected object with an entry queue of length one,
-- which allows it to be implemented more efficiently.  This means that
-- the programmer using suspension objects has to know which task will
-- do the waiting; it's as if that task has a kind of ownership of that
-- particular suspension object.

----------------------------------------------------------------

with Ada.Interrupts.Names; use Ada.Interrupts.Names;
with System.RTS.Temp_IO; use System.RTS.Temp_IO;

package Suspension_Objects_Test is

    -- Empty.

end Suspension_Objects_Test;

----------------------------------------------------------------

with Ada.Synchronous_Task_Control; use Ada.Synchronous_Task_Control;
package Suspension_Objects_Test.Handlers is

    pragma Elaborate_Body;

    protected Handler_PO is

        procedure Handler; -- The interrupt handler.
        pragma Attach_Handler(Handler, SFT0I);

    end Handler_PO;

    Interrupt_Occurred: Suspension_Object;
        -- Default-initialized to False.
        -- Set to True for each interrupt.

end Suspension_Objects_Test.Handlers;

----------------------------------------------------------------

package body Suspension_Objects_Test.Handlers is

    protected body Handler_PO is

        procedure Handler is
        begin
            Set_True(Interrupt_Occurred);
        end Handler;

    end Handler_PO;

end Suspension_Objects_Test.Handlers;

----------------------------------------------------------------

package Suspension_Objects_Test.Waiting_Tasks is

    pragma Elaborate_Body; -- So the body is allowed.

end Suspension_Objects_Test.Waiting_Tasks;

----------------------------------------------------------------

with Suspension_Objects_Test.Handlers; use Suspension_Objects_Test.Handlers;
with Ada.Synchronous_Task_Control; use Ada.Synchronous_Task_Control;
package body Suspension_Objects_Test.Waiting_Tasks is

    task Waiting_Task;

    task body Waiting_Task is
    begin
        for I in 1..4 loop
            Suspend_Until_True(Interrupt_Occurred);
            Put_Line("Waiting_Task: Got interrupt.");
        end loop;
        Put_Line("Goodbye from Waiting_Task.");
    end Waiting_Task;

end Suspension_Objects_Test.Waiting_Tasks;

----------------------------------------------------------------

with System.Machine_Intrinsics;

with Suspension_Objects_Test.Waiting_Tasks;
    -- There are no references to this package; this with_clause is here
    -- so that task Waiting_Task will be included in the program.

procedure Suspension_Objects_Test.Main is

    procedure Generate_Interrupt(Interrupt : Ada.Interrupts.Interrupt_ID) is
        ... -- as in previous example
    end Generate_Interrupt;

begin

    -- Generate some simulated interrupts, with delays in between.

    Put_Line("Hello from Suspension_Objects_Test main procedure.");
    for I in 1..10 loop
        delay 0.01;
        Put_Line("Generating interrupt.");
        Generate_Interrupt(SFT0I);
    end loop;
    Put_Line("Goodbye from Suspension_Objects_Test main procedure.");

end Suspension_Objects_Test.Main;
-- 
Change robert to bob to get my real email address.  Sorry.




^ permalink raw reply	[relevance 1%]

* Re: Connecting To Interrupts Using Protected Procedures
  @ 1999-02-18  0:00  1%     ` Marin David Condic
  0 siblings, 0 replies; 76+ results
From: Marin David Condic @ 1999-02-18  0:00 UTC (permalink / raw)


Pat Rogers wrote:
> 
> 
> Since you asked for a snippet of code:
> 
<snip>
I also received help from David Brown wherein he posted the code
attached. Very similar answers so it seems this is a fairly common way
to go. I appreciate all the help on this. Now the only question we'll
have to answer is how efficient/inefficient the various features may
be...

MDC
===========================================================================

I think this is similar to what you want.  Feel free to post this.
I'm having problems with the configuration of my newsreader, and am
having trouble posting.

   ...

   Tick_Divider : constant := 9;

   protected Pclock is
      entry Wait;
      procedure Tick;
      pragma Attach_Handler (Tick, Ada.Interrupts.Names.SIGINT);
   private
      Counter : Natural := 0;
   end Pclock;

   protected body Pclock is
      entry Wait when Counter > Tick_Divider is
      begin
         Counter := 0;
      end Wait;

      procedure Tick is
      begin
         Counter := Counter + 1;
      end Tick;
   end Pclock;

   task Waiter is
   end Waiter;

   task body Waiter is
   begin
      loop
         Pclock.Wait;
         Ada.Text_IO.Put_Line ("Got slower ticks");
      end loop;
   end Waiter;

==========================================================================

-- 
Marin David Condic
Real Time & Embedded Systems, Propulsion Systems Analysis
United Technologies, Pratt & Whitney, Large Military Engines
M/S 731-95, P.O.B. 109600, West Palm Beach, FL, 33410-9600
Ph: 561.796.8997         Fx: 561.796.4669
***To reply, remove "bogon" from the domain name.***

    "Crime does not pay ... as well as politics."

        --  A. E. Newman




^ permalink raw reply	[relevance 1%]

* interrupt Handler with EZ2LOAD
@ 1998-07-13  0:00  1% Ramon Costa-Castell�
  0 siblings, 0 replies; 76+ results
From: Ramon Costa-Castell� @ 1998-07-13  0:00 UTC (permalink / raw)


Hye,

First of all let me tell that this is the first time
I'm working serously with ADA.

I'm using EZ2LOAD distribution of GNAT307,
and I'm trying to develop and device handler for
and ADC/DAC board (PCL-812PG).
To do this I'm following the device driver template
found in :

Concurrency in ADA
by Alan Burns and Andy Wellings


One of the most important step in this template is when then interrupt
is attached to
my interrupt handler thourgh the instruction:

pragma Attach_Handler(Handler, Int_Id);

The first parameter is the interrupt handler is  the  interrupt handler
address.
But what is it the second one ?

In the book it says that this is an interrupt identifier  is defined in
Ada.Interrupts.Names package, but obviously my card
identifier is not defined there.

How should I define an interrupt identifier for my card,
How this number is related with the IRQ ?

(does anyone has a complete exemple for this platform with the same or
similar board ?)



Thank You in advance for the problems I will
cause.


Best Regards,

Ramon Costa-Castello





^ permalink raw reply	[relevance 1%]

* Re: type names (was Re: Child package: private type and IO)
  1998-03-01  0:00  1%       ` Matthew Heaney
@ 1998-03-04  0:00  1%         ` Fergus Henderson
  0 siblings, 0 replies; 76+ results
From: Fergus Henderson @ 1998-03-04  0:00 UTC (permalink / raw)



mheaney@ni.net (Matthew Heaney) writes:

 >blaak@infomatch.com (Ray Blaak) wrote:
 >
 >>>Objects are the memory locations that store a value of a type.
 >>
 >>But you are using the word here as a type! (i.e. the set of things that are
 >>memory locations that store values).
 >
 >No.  You are confused about what a type is.

No, Ray Blaak is correct here.

 >Let's begin by defining what we mean by a type.  A type is defined as "A
 >set of values, and a set of operations on those values."  For example,  I
 >can define a type
 >
 >with the name "Integer"
 >
 >and the set of values
 >
 >   ..., -3, -2, -1, 0, 1, 2, 3, ...
 >
 >and the set of operations
 >
 >   +: Integer x Integer -> Integer
 >   -: Integer x Integer -> Integer
 >   *: Integer x Integer -> Integer
 >   /: Integer x Integer -> Integer
 >   =: Integer x Integer -> Boolean
 >
 >etc

Agreed.

Above, you used the word "Object" to refer to a type with the name "Object",
with the set of values being the different possible memory locations,
and with the set of operations being fetch, store, etc.

Below, you assume that "Object" and "Type" are mutually exclusive;
this is true in Ada, but there are other languages for which it is not true.

 >A type refers to the set of values, NOT the objects.  An object is a memory
 >location inside a computer, that stores a value, a value we interpret as
 >having a certain type.  So when we declare an object,
 >
 >O : T;
 >
 >we're allocating a memory cell, and we're interpreting the value of the
 >data in that cell as being of type T.  The means the memory cell designated
 >by object O will only contain certain values, and that only certain
 >operations may be applied to the value in that cell.
 >
 >The memory cell designated by object O isn't really interesting.  It's the
 >data in that cell that's interesting.  And it's the data in the cell that
 >"is of type T," not the object itself.

No, the object itself "is [an lvalue] of type T".

To say otherwise would imply that objects are untyped, that
only values are typed, and that it is therefore possible to
store a value of any type in a given object.  This is true
for some untyped languages, but it is not true in Ada.

 >It is completely wrong to name a type "Object."

Well, I don't particularly like this convention much myself;
but I think "completely wrong" is overstating the case.

 >Yes, it's true we often say "Object O has type T," but we really mean "O is
 >the name of a memory cell containing a value of type T."

No.  What we really mean is "O has type n<T>",
where "n<T>" is a (parametric) type whose operations
include "fetch" (syntactically implicit in Ada) and "store" (`:=').

"n<T>" might be better named "name<T>", "lvalue<T>", or even "object<T>".

 >>>A type should be named using a noun phrase, such as
 >>>type Singly_Linked_List is ...;
 >>
 >>I think that style of type names used really depends on if type names are
 >>qualified with package names or not.
 >
 >Of course, a type name should NOT be qualified by a package name.  A type
 >name is a type name, and a package name is a package name.  A package name
 >is NOT a type name, and in no way participates in naming a type.  

No, a package name surely does participate in naming a type,
for the type's fully-qualified name includes the name of the
package in which it is contained.

 >A package is a namespace, and serves only to prevent clashes among
 >similarly named types in an otherwise global namespace.

No, packages also provide encapsulation, not just namespace control.

 >A package disambiguates type names, but it is itself not a type name.

Agreed.

 >To use a package as part of the type, as in 
 >
 >package P is 
 >
 >   type Object is ...;
 >...
 >end P;
 >
 >The_Object : P.Object;
 >
 >so that the "real" type name is "P.Object" only confuses the difference
 >between a module and a type.

Nonsense!

The package name is P; the type name is P.Object
(though it can be abbreviated as Object, in certain contexts).
What's there to be confused about?

 >>Having:
 >>
 >>  package Linked_List is
 >>    type Linked_List is ...
 >>  end Linked_List;
 >>
 >>results in usage like:
 >>
 >>  Employees : Linked_List.Linked_List;
 >>
 >>which I personally find irritating.
 >
 >The package is misnamed.  A common idiom, and a very OLD idiom in the Ada
 >community, is to use the plural of the type name as the package name,

Well, that doesn't help much -- now the usage is

    Employees : Linked_Lists.Linked_List;

which is still just as ugly.

 >I'm sorry you find this convention irritating.  If so, then you can tell
 >the language designers that they named the packages
 >
 >Ada.Characters
 >Ada.Interrupts
 >Ada.Interrupts.Names
 >Ada.Exceptions
 >Ada.Numerics
 >Ada.Streams
 >Ada.Strings
 >Interfaces
 >Interfaces.C.Pointers
 >Interfaces.C.Strings
 >System.Address_To_Access_Conversions
 >System.Storage_Elements
 >System.Storage_Pools
 >
 >incorrectly, and that the names they chose irritate you.

It's not a question of "correct" or "incorrect", it's a question
of style.  The style chosen for the standard library strongly
encourages the use of `use', to avoid unnecessary redundancy in
names like `Ada.Strings.Unbounded.Unbounded_String'.
This is probably not such a bad thing
for the standard library, since experienced Ada programmers 
will know the standard library well; but for more general settings,
encouraging the use of `use' may not be such a good idea.

Personally, I quite like the style of naming types `T',
e.g. `Ada.Strings.Unbounded.T'.

 >> However a package like:
 >>
 >>  package Linked_List is
 >>    type Object is ...
 >>  end Linked_List;
 >>
 >>results in usage like:
 >>
 >>  Employees : Linked_List.Object;
 >>
 >>which reads better to me.
 >
 >It reads better to you because you are confused.  You don't understand the
 >difference between a module and a type.

Well, it reads better to me too, and I definitely do
understand the difference between a module and a type
(and I think Ray Blaak probably does too).

 >If you don't believe that this is the Ada idiom, [...]

I think Ada is big enough for more than one idiom!

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F




^ permalink raw reply	[relevance 1%]

* Re: type names (was Re: Child package: private type and IO)
  @ 1998-03-01  0:00  1%       ` Matthew Heaney
  1998-03-04  0:00  1%         ` Fergus Henderson
  0 siblings, 1 reply; 76+ results
From: Matthew Heaney @ 1998-03-01  0:00 UTC (permalink / raw)



In article <6dcio1$fvo$1@berlin.infomatch.com>, blaak@infomatch.com (Ray
Blaak) wrote:

>>Objects are the memory locations that store a value of a type.
>
>But you are using the word here as a type! (i.e. the set of things that are
>memory locations that store values).

No.  You are confused about what a type is.

Let's begin by defining what we mean by a type.  A type is defined as "A
set of values, and a set of operations on those values."  For example,  I
can define a type

with the name "Integer"

and the set of values

   ..., -3, -2, -1, 0, 1, 2, 3, ...

and the set of operations

   +: Integer x Integer -> Integer
   -: Integer x Integer -> Integer
   *: Integer x Integer -> Integer
   /: Integer x Integer -> Integer
   =: Integer x Integer -> Boolean

etc

A type refers to the set of values, NOT the objects.  An object is a memory
location inside a computer, that stores a value, a value we interpret as
having a certain type.  So when we declare an object,

O : T;

we're allocating a memory cell, and we're interpreting the value of the
data in that cell as being of type T.  The means the memory cell designated
by object O will only contain certain values, and that only certain
operations may be applied to the value in that cell.

The memory cell designated by object O isn't really interesting.  It's the
data in that cell that's interesting.  And it's the data in the cell that
"is of type T," not the object itself.
   
It is completely wrong to name a type "Object."  There are 2 reasons:

1) It confuses the difference between a memory cell (which merely stores a
value) and the value itself.  "Type" refers to a set of values, and to the
operations you can perform to manipulate those values.

"Type" does NOT refer to the memory cell containing a value.  The term we
use to refer to a memory cell containing a value is "Object."

Yes, it's true we often say "Object O has type T," but we really mean "O is
the name of a memory cell containing a value of type T."

The name "T" is the name we've bound to the TYPE, not to the object.  So
"T" is the name by which we refer to a set of values and a set of
operations.  The name "O" is the name we bind to an OBJECT, not a type;
that is, "O" refers to a memory cell.

So when you name a type "Object," it's confusing because the term "Object"
refers to a memory cell.  But a type is NOT a memory call, it's a set of
values.

2) It confuses the difference between a module and a type.

In Ada, module and type are ORTHOGONAL language features.  This really
confuses a lot of people, and I have no idea why.

The Ada language construct for a module is a package.  A package is NOT a
type.  A package which exports a type declaration merely demarcates the
"primitive" operations of a type among all the operations that have the
type as a parameter or return value.  

The Ada language construct for a type comprises 2 parts:

a) a type declaration, which binds a name to the type, specifies its class,
and specifies the set of values as a range (or implied range).

b) subprogram declarations, which take parameters of the type, or return
values of the type.

Consider this example:

package P is

   type T is range 1 .. 4;

   procedure Op1 (O : T);

   function Op2 (F : Float) return T;

end P;

with P;
package Q is

   procedure Op3 (O : P.T);

end Q;

Let's analyze this piece by piece.

The declaration 

   type T is range 1 .. 4;

a) specifies the type class, here Integer

b) specifies the set of values (having the Integer class) for the type,
here 1, 2, 3, 4

c) binds a name to the type, here "T"

d) specifies primitive operations that are "predefined" for this class of
type, here

   +: T x T -> T
   +: T -> T
   -: T x T -> T
   -: T -> T
   =: T x T -> Boolean

etc

The operations Op1 and Op2 are also "primitive" operations of the type
whose name is T.  We say they are "user-defined," in contrast to the
"predefined" primitive operations as addition, subtraction, etc.

They are primitive because they take a parameter of the type (Op1) and
return a value of the type (Op2), and they are declared in the same package
(P) as the type declaration.

By contrast, the operation Op3 is NOT a "primitive" operation of the type
whose name is T.  Even though Op3 takes a parameter of type P.T, it is not
primitive because it is not declared in the same package as the type
declaration.

We make the distinction between primitive and non-primitive operations
because only the former are "inherited" during a derivation.  For example,

with P;
package R is

   type NT is new P.T;

  procedure Op4 (O : NT);

end R;

The primitive operations of type R.NT are "+", "-", "*", "/", etc, and Op1,
Op2, and Op4.  Op1 and Op2 (and addition, etc) are inherited from T, and a
new primitive operation, Op4, was added too.

Note the Op3 is NOT an operation of type NT, because Op3 is not a primitive
operation of type T.

And by the way, while I'm on the subject, a "class" in other languages as
C++, Eiffel, and Java maps to an Ada tagged type.  It does NOT map to an
Ada package.  To convert the C++ declaration

class Stack ...;

to Ada, you have to do this:

package Stacks is

   type Stack is ...;  -- this is the "class Stack"


>>So when refer to an object's type as "Object," then how do you refer to the
>>object?
>
>Perhaps as An_Object, or The_List, or The_Set, or even Value. An even better
>approach is to use names from the domain, like maybe Employees, or
>Active_Flights, or Current_Account.

An an even better approach is

Account : Bank_Account;

File : Text_File;

Mode : File_Mode;


>>A type should be named using a noun phrase, such as
>>type Singly_Linked_List is ...;
>
>I think that style of type names used really depends on if type names are
>qualified with package names or not.

Of course, a type name should NOT be qualified by a package name.  A type
name is a type name, and a package name is a package name.  A package name
is NOT a type name, and in no way participates in naming a type.  

A package is a namespace, and serves only to prevent clashes among
similarly named types in an otherwise global namespace.  A package
disambiguates type names, but it is itself not a type name.

To use a package as part of the type, as in 

package P is 

   type Object is ...;
...
end P;

The_Object : P.Object;

so that the "real" type name is "P.Object" only confuses the difference
between a module and a type.

>Having:
>
>  package Linked_List is
>    type Linked_List is ...
>  end Linked_List;
>
>results in usage like:
>
>  Employees : Linked_List.Linked_List;
>
>which I personally find irritating.

The package is misnamed.  A common idiom, and a very OLD idiom in the Ada
community, is to use the plural of the type name as the package name, as in


generic
...
package Stacks

   type Stack is ...;
...;
end Stacks;

I'm sorry you find this convention irritating.  If so, then you can tell
the language designers that they named the packages

Ada.Characters
Ada.Interrupts
Ada.Interrupts.Names
Ada.Exceptions
Ada.Numerics
Ada.Streams
Ada.Strings
Interfaces
Interfaces.C.Pointers
Interfaces.C.Strings
System.Address_To_Access_Conversions
System.Storage_Elements
System.Storage_Pools

incorrectly, and that the names they chose irritate you.

> However a package like:
>
>  package Linked_List is
>    type Object is ...
>  end Linked_List;
>
>results in usage like:
>
>  Employees : Linked_List.Object;
>
>which reads better to me.

It reads better to you because you are confused.  You don't understand the
difference between a module and a type.

>Note this does not imply that all types should be
>called "Object" either. With this example in particular, it is natural to work
>with objects and references to objects:
>
>  type Handle;
>  type Object is record
>    ...
>        Next : Handle;
>        Previous : Handle;
>  end record;
>  type Handle is access Object;


This is another horrible naming convention.  The term "handle" loosely
refers to a pointer-to-pointer.  Handles are used in memory allocation
schemes to allow you to relocate chunks of memory to reduce fragmentation
(Mac programmers will know what I'm talking about).

The Ada idiom for a name of an access type is T_Access, for example

type Stack is tagged private;

type Stack_Access is access all Stack;

type Stack_Class_Access is access all Stack'Class;

Do not name an access type Handle, because it is not a handle.

Do not name an access type Pointer, because access objects are not
pointers.  If they were, then Jean Ichbiah would have chosen the keyword
"pointer" instead of "access," right?

If you don't believe that this is the Ada idiom, then make note of the
names of the types

Ada.Text_IO.File_Access

Ada.Strings.Unbounded.String_Access

Ada.Streams.Stream_IO.Stream_Access


>then one can say things like:
>
>  Manager_Subset : Linked_List.Handle;
>
>which is really clear (to me, of course :-).
>
>If one uses use clauses a lot, then of course more descriptive type names are
>better:
>
>  data : Linked_List;

Ahh, that's more like it.

Here's an example from a library I'm writing:

package ACL.Lists is ...;


package ACL.Lists.Single is

   type Single_List is private;
...;
end ACL.Lists.Single;


package ACL.Lists.Double is

   type Double_List is private;
...
end ACL.Lists.Double;


Here's another example you often find in tutorials:

package Bank_Accounts is

   type Bank_Account is abstract tagged limited private;
...;
end Bank_Accounts;


package Bank_Accounts.Checking is

   type Checking_Account is new Bank_Account with private;
...;
end Bank_Accounts.Checking;


package Bank_Accounts.Savings is

   type Savings_Account is new Bank_Account with private;
...
end Bank_Accounts.Savings;


>>A good guideline is, Be consistant with the style in the reference manual. 
>>There are NO types in the RM named "Object," so there should be none in
>>your code either.
>
>One shouldn't be so afraid to do something different, if one thinks it is an
>improvement. How else can standards get better?

A bunch of guys from all over the planet with PhDs in computer science
designed the language, and somehow they didn't come up with your "better
idea."  Telling, isn't it?  If you think it is an improvement, perhaps that
is because there is knowledge that you don't have.




^ permalink raw reply	[relevance 1%]

Results 1-76 of 76 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
1998-02-14  0:00     Child package: private type and IO johnjohn
1998-02-17  0:00     ` sparre
1998-02-27  0:00       ` Matthew Heaney
1998-03-01  0:00         ` type names (was Re: Child package: private type and IO) Ray Blaak
1998-03-01  0:00  1%       ` Matthew Heaney
1998-03-04  0:00  1%         ` Fergus Henderson
1998-07-13  0:00  1% interrupt Handler with EZ2LOAD Ramon Costa-Castell�
1999-02-17  0:00     Connecting To Interrupts Using Protected Procedures Marin David Condic
1999-02-17  0:00     ` Pat Rogers
1999-02-18  0:00       ` Pat Rogers
1999-02-18  0:00  1%     ` Marin David Condic
1999-02-23  0:00     Ada83 and Ada95 interrupt handling Armin
1999-03-05  0:00  1% ` Robert A Duff
1999-05-19  0:00  2% Interrupt problem in GNAT Joerg Kienzle
2000-01-06  0:00  1% question about COM2 Alexander Van Hecke
2000-01-07  0:00  0% ` more information on OS and compiler Alexander Van Hecke
2000-12-15 18:24     How to lock keys Freelancer
2000-12-15 23:56  2% ` Alexander Antonenko
2001-01-05 12:28  2% Interrupts service Szygula
2001-01-05 13:20  0% ` Marc A. Criley
2001-03-13 11:09     Handling signals in ADA Tomas Hlavaty
2001-03-15 18:48  1% ` David Starner
2001-03-16 17:17  2%   ` Robert A Duff
2001-03-15 22:05     ` Florian Weimer
2001-03-16  1:27  2%   ` David C. Hoos, Sr.
2001-03-16  1:48  1%     ` Jeffrey Carter
2001-03-16  3:06  2%   ` (null)
2001-12-18 16:28     Use of entries using Ravenscar Jimmy Dubén
2001-12-20  7:54     ` Jimmy Dubén
2001-12-20  8:46       ` martin.m.dowie
2001-12-20 13:52  2%     ` Jimmy Dubén
2002-10-11 18:54  1% On-Screen Elapsed Time Display? Dr Nancy's Sweetie
2002-10-11 19:32  0% ` Jeffrey Carter
2003-01-29 15:04     tasking programs built with GNAT insensitive to SIGTERM Oliver Kellogg
2003-01-29 21:54     ` Mark Johnson
2003-02-04 19:55  1%   ` Craig Carey
2003-02-22 22:31  2% strange execution error alfonso acosta
2004-01-03 18:52  2% gnat/linux:setitimer TIlman Glotzner
2004-01-05 16:18     ` gnat/linux:setitimer Mark H Johnson
2004-01-15  3:35  2%   ` gnat/linux:setitimer Tilman Glotzner
2004-03-25 17:03  1% Signal handler blocks proteced type Lutz Donnerhacke
2004-03-25 17:05  1% Lutz Donnerhacke
2004-06-16  9:29     SIGINT problem under LINUX Radek Kotowicz
2004-06-16 11:13  2% ` Jeff C,
2005-01-17 12:26  1% Catching Ctrl-C SIGINT Christopher Broeg
2005-01-17 14:07  1% Christopher Broeg
2005-01-17 14:13  1% Christopher Broeg
2005-06-15 15:39     Interrupt handler seems not to be called in GNAT 3.15p Thorsten
2005-06-16  8:03  1% ` Egil H. H�vik
2005-06-16  9:36  0%   ` Thorsten
2005-08-10 16:01  2% problem with ada.interrupts evangeli
2005-08-25 12:25  0% ` Thierry Pirot
2008-05-27 11:19     Access procedure to pointer Sébastien
2008-05-27 12:05     ` Ludovic Brenta
2008-05-27 17:45       ` Sébastien
2008-05-27 18:26         ` Dmitry A. Kazakov
2008-05-28  9:06           ` Sébastien
2008-05-28 10:13             ` Jean-Pierre Rosen
2008-05-28 14:57               ` Sébastien
2008-05-28 15:26                 ` Jean-Pierre Rosen
2008-05-28 21:36  2%               ` Adam Beneschan
2008-05-28 23:02  0%                 ` Sebastien Morand
2008-05-29  0:58                       ` Jeffrey R. Carter
2008-05-29  9:06                         ` Sébastien
2008-05-29 20:20  1%                       ` Jeffrey R. Carter
2008-05-28 15:29  1%             ` Sébastien
2009-05-15 16:26  2% Interrupt handler and Ada.Real_Time.Timing_Events Reto Buerki
2009-05-15 16:54  0% ` Adam Beneschan
2009-05-15 16:56  0% ` Ludovic Brenta
2009-05-16 11:05  0% ` Timing Example was " anon
2009-08-05 19:58     Ada and (SIGTERM?) Tomek Walkuski
2009-08-06  1:06     ` Adam Beneschan
2009-08-06 19:30       ` Tomek Wałkuski
2009-08-06 19:57  1%     ` Jeffrey R. Carter
2009-08-06 20:00  1%     ` okellogg
2010-04-12  4:12     How to exit a loop with keyboard input Jerry
2010-04-12 10:36     ` Jerry
2010-04-12 13:59  2%   ` John McCormick
2010-04-13 19:38  0%     ` Jerry
2010-10-26 15:52  2% GNAT and SIGTERM (Linux x86_64) Bryan
2010-10-26 16:36  0% ` Yannick Duchêne (Hibou57)
2010-10-27  7:43  7%   ` Ludovic Brenta
2011-03-07  9:34     ACCESS TO SYSTEM VARIABLES Emile8
2011-03-07 11:47     ` Georg Bauhaus
2011-03-07 20:14       ` Emile8
2011-03-07 21:32         ` Peter C. Chapin
2011-03-08 17:13           ` Emile8
2011-03-09 18:59  2%         ` Emile8
2015-01-20 22:34  1% Use of expression function in protected type Simon Wright
2015-01-27 16:09  2% gnat ARM - predefined packages RasikaSrinivasan
2015-01-27 16:49  0% ` Bob Duff
2015-01-27 16:49  0% ` Simon Wright
2015-01-27 16:50       ` Simon Wright
2015-01-27 18:29         ` RasikaSrinivasan
2015-01-27 21:55           ` Simon Wright
2015-01-28  7:03             ` Egil H H
2015-01-28  7:52               ` Simon Wright
2015-01-28  8:41                 ` J-P. Rosen
2015-01-28 13:11                   ` Simon Wright
2015-01-28 17:30  1%                 ` RasikaSrinivasan
2015-03-03  7:45     GNAT stm34f4 zfp question jan.de.kruyf
2015-03-03  9:20     ` jan.de.kruyf
2015-03-03 17:15       ` Patrick Noffke
2015-03-04 15:22         ` jan.de.kruyf
2015-03-04 18:28           ` Simon Wright
2015-03-18 17:58  1%         ` Simon Wright
2015-05-27 19:38     longest path through a task jan.de.kruyf
2015-05-27 20:09     ` Niklas Holsti
2015-05-28  6:54       ` jan.de.kruyf
2015-05-28 16:37         ` Simon Wright
2015-05-28 17:43           ` jan.de.kruyf
2015-05-28 17:52  1%         ` Simon Wright
2015-05-28 18:12  0%           ` jan.de.kruyf
2015-06-20 18:38  1% GNAT GPL 2015 Troubles RasikaSrinivasan
2015-06-20 19:31     ` Simon Wright
2015-06-21  9:55       ` Stephen Leake
2015-06-21 11:13         ` Simon Wright
2015-06-21 16:00           ` RasikaSrinivasan
2015-06-21 16:21  1%         ` Simon Wright
2015-06-23 14:07  0%           ` Stephen Leake
2015-06-23 17:07  0%             ` Simon Wright
2016-02-07 22:45  1% ANN: Cortex GNAT RTS 20160207 Simon Wright
2016-03-14 17:42  1% ANN: Cortex GNAT RTS 20160314 Simon Wright
2016-05-22 14:20  1% ANN: Cortex GNAT RTS 20160522 Simon Wright
2016-06-25  2:40  1% GNAT bug with protected procedure interrupt handler Daniel King
2016-10-11 17:02  1% Precondition on protected entry Simon Wright
2016-10-12 16:07  2% ` Stephen Leake
2017-09-16 20:47  2% how to use "in out" for the "self" parameter in a function in a protected object? Frank Buss
2017-10-12 15:16  2% Interrupts & Ravenscar Simon Wright
2017-11-15 14:28     Ada.Real_Time.Time_Last Simon Wright
2017-11-15 20:03     ` Ada.Real_Time.Time_Last Niklas Holsti
2017-11-17  9:20       ` Ada.Real_Time.Time_Last Simon Wright
2017-11-17 21:39         ` Ada.Real_Time.Time_Last Niklas Holsti
2017-11-18 13:06           ` Ada.Real_Time.Time_Last AdaMagica
2017-11-18 13:18             ` Ada.Real_Time.Time_Last Niklas Holsti
2017-11-18 14:15               ` Ada.Real_Time.Time_Last Jeffrey R. Carter
2017-11-18 15:24                 ` Ada.Real_Time.Time_Last Niklas Holsti
2017-11-18 22:20                   ` Ada.Real_Time.Time_Last Robert A Duff
2017-11-19 10:50  1%                 ` Ada.Real_Time.Time_Last Niklas Holsti
2019-01-29  3:39     Ada.Interrpts.Names lyttlec
2019-01-29 10:29     ` Ada.Interrpts.Names Simon Wright
2019-01-29 13:09  1%   ` Ada.Interrpts.Names Simon Wright
2019-01-29 14:31  1%     ` Ada.Interrpts.Names Simon Wright
2019-02-25  6:51     Ada in command / control systems Jesper Quorning
2019-02-25  8:24     ` Dmitry A. Kazakov
2019-02-25 13:50       ` russ lyttle
2019-02-25 15:25         ` Simon Wright
2019-02-25 19:21           ` russ lyttle
2019-02-26  4:50             ` J-P. Rosen
2019-02-26 15:50  1%           ` Simon Wright
2019-02-26 22:10  0%             ` lyttlec
2019-02-26 22:39  0%               ` Niklas Holsti
2021-03-28 19:41  1% Elaboration code, aggregates Simon Wright

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox