1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
------------------------------------------------------------------------------
-- --
-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
-- --
-- I N T E R F A C E S . V X W O R K S --
-- --
-- S p e c --
-- --
-- Copyright (C) 1999-2005, AdaCore --
-- --
-- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNARL; see file COPYING. If not, write --
-- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
-- Boston, MA 02110-1301, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
-- this unit does not by itself cause the resulting executable to be --
-- covered by the GNU General Public License. This exception does not --
-- however invalidate any other reasons why the executable file might be --
-- covered by the GNU Public License. --
-- --
-- GNARL was developed by the GNARL team at Florida State University. --
-- Extensive contributions were provided by Ada Core Technologies, Inc. --
-- --
------------------------------------------------------------------------------
-- This package provides a limited binding to the VxWorks API
-- In particular, it interfaces with the VxWorks hardware interrupt
-- facilities, allowing the use of low-latency direct-vectored
-- interrupt handlers. Note that such handlers have a variety of
-- restrictions regarding system calls and language constructs. In particular,
-- the use of exception handlers and functions returning variable-length
-- objects cannot be used. Less restrictive, but higher-latency handlers can
-- be written using Ada protected procedures, Ada 83 style interrupt entries,
-- or by signalling an Ada task from within an interrupt handler using a
-- binary semaphore as described in the VxWorks Programmer's Manual.
--
-- For complete documentation of the operations in this package, please
-- consult the VxWorks Programmer's Manual and VxWorks Reference Manual.
with System.VxWorks;
package Interfaces.VxWorks is
pragma Preelaborate;
------------------------------------------------------------------------
-- Here is a complete example that shows how to handle the Interrupt 0x14
-- with a direct-vectored interrupt handler in Ada using this package:
-- with Interfaces.VxWorks; use Interfaces.VxWorks;
-- with System;
--
-- package P is
--
-- Count : Integer;
-- pragma Atomic (Count);
--
-- Level : constant := 1;
-- -- Interrupt level used by this example
--
-- procedure Handler (parameter : System.Address);
--
-- end P;
--
-- package body P is
--
-- procedure Handler (parameter : System.Address) is
-- S : STATUS;
-- begin
-- Count := Count + 1;
-- logMsg ("received an interrupt" & ASCII.LF & ASCII.Nul);
--
-- -- Acknowledge VME interrupt
-- S := sysBusIntAck (intLevel => Level);
-- end Handler;
-- end P;
--
-- with Interfaces.VxWorks; use Interfaces.VxWorks;
-- with Ada.Text_IO; use Ada.Text_IO;
--
-- with P; use P;
-- procedure Useint is
-- -- Be sure to use a reasonable interrupt number for the target
-- -- board!
-- -- This one is the unused VME graphics interrupt on the PPC MV2604
-- Interrupt : constant := 16#14#;
--
-- task T;
--
-- S : STATUS;
--
-- task body T is
-- begin
-- loop
-- Put_Line ("Generating an interrupt...");
-- delay 1.0;
--
-- -- Generate VME interrupt, using interrupt number
-- S := sysBusIntGen (1, Interrupt);
-- end loop;
-- end T;
--
-- begin
-- S := sysIntEnable (intLevel => Level);
-- S := intConnect (INUM_TO_IVEC (Interrupt), handler'Access);
--
-- loop
-- delay 2.0;
-- Put_Line ("value of count:" & P.Count'Img);
-- end loop;
-- end Useint;
-------------------------------------
subtype int is Integer;
type STATUS is new int;
-- Equivalent of the C type STATUS
OK : constant STATUS := 0;
ERROR : constant STATUS := -1;
type VOIDFUNCPTR is access procedure (parameter : System.Address);
type Interrupt_Vector is new System.Address;
type Exception_Vector is new System.Address;
function intConnect
(vector : Interrupt_Vector;
handler : VOIDFUNCPTR;
parameter : System.Address := System.Null_Address) return STATUS;
-- Binding to the C routine intConnect. Use this to set up an
-- user handler. The routine generates a wrapper around the user
-- handler to save and restore context
function intContext return int;
-- Binding to the C routine intContext. This function returns 1 only
-- if the current execution state is in interrupt context.
function intVecGet
(Vector : Interrupt_Vector) return VOIDFUNCPTR;
-- Binding to the C routine intVecGet. Use this to get the
-- existing handler for later restoral
procedure intVecSet
(Vector : Interrupt_Vector;
Handler : VOIDFUNCPTR);
-- Binding to the C routine intVecSet. Use this to restore a
-- handler obtained using intVecGet
function INUM_TO_IVEC (intNum : int) return Interrupt_Vector;
-- Equivalent to the C macro INUM_TO_IVEC used to convert an interrupt
-- number to an interrupt vector
function sysIntEnable (intLevel : int) return STATUS;
-- Binding to the C routine sysIntEnable
function sysIntDisable (intLevel : int) return STATUS;
-- Binding to the C routine sysIntDisable
function sysBusIntAck (intLevel : int) return STATUS;
-- Binding to the C routine sysBusIntAck
function sysBusIntGen (intLevel : int; Intnum : int) return STATUS;
-- Binding to the C routine sysBusIntGen. Note that the T2
-- documentation implies that a vector address is the proper
-- argument - it's not. The interrupt number in the range
-- 0 .. 255 (for 68K and PPC) is the correct agument.
procedure logMsg
(fmt : String; arg1, arg2, arg3, arg4, arg5, arg6 : int := 0);
-- Binding to the C routine logMsg. Note that it is the caller's
-- responsibility to ensure that fmt is a null-terminated string
-- (e.g logMsg ("Interrupt" & ASCII.NUL))
type FP_CONTEXT is private;
-- Floating point context save and restore. Handlers using floating
-- point must be bracketed with these calls. The pFpContext parameter
-- should be an object of type FP_CONTEXT that is
-- declared local to the handler.
procedure fppRestore (pFpContext : in out FP_CONTEXT);
-- Restore floating point context
procedure fppSave (pFpContext : in out FP_CONTEXT);
-- Save floating point context
private
type FP_CONTEXT is new System.VxWorks.FP_CONTEXT;
-- Target-dependent floating point context type
pragma Import (C, intConnect, "intConnect");
pragma Import (C, intContext, "intContext");
pragma Import (C, intVecGet, "intVecGet");
pragma Import (C, intVecSet, "intVecSet");
pragma Import (C, INUM_TO_IVEC, "__gnat_inum_to_ivec");
pragma Import (C, sysIntEnable, "sysIntEnable");
pragma Import (C, sysIntDisable, "sysIntDisable");
pragma Import (C, sysBusIntAck, "sysBusIntAck");
pragma Import (C, sysBusIntGen, "sysBusIntGen");
pragma Import (C, logMsg, "logMsg");
pragma Import (C, fppRestore, "fppRestore");
pragma Import (C, fppSave, "fppSave");
end Interfaces.VxWorks;
|