From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,17395bd9bffaca19,start X-Google-Attributes: gid103376,public From: "Marin David Condic, 561.796.8997, M/S 731-93" Subject: Ada95/Mil-Std-1553 Problem (Long Post - Sorry About That) Date: 1997/01/12 Message-ID: <97011214115169@psavax.pwfl.com> X-Deja-AN: 209383518 sender: Ada programming language comments: Gated by NETNEWS@AUVM.AMERICAN.EDU x-vms-to: SMTP%"INFO-ADA@VM1.NODAK.EDU" newsgroups: comp.lang.ada x-vms-cc: CONDIC Date: 1997-01-12T00:00:00+00:00 List-Id: I have a problem I am trying to solve that involves building a good general purpose interface to a Mil-Std-1553 data bus using Ada95. The 1553 moves data in blocks of 16 bit words, 32 words at a shot. How exactly is not the problem. Accept for the moment that we need some array of 32 words as the local buffer to hold the data being sent or received. Here's what you'd like to have: -- You would like to create any record type of some arbitrary number of words (Possibly limited to some maximum, like 1024 words) and you want the first two words to always be the same: Number of words in the message followed by message ID. Ex: Type Msg is record Num_Wds : Integer := 2; Msg_ID : Integer := 0; -- Conforming records would have other stuff here. end record; -- You want to write a package which will send or receive any arbitrary object of a conforming record type to/from the bus. -- The message length should not be arbitrarily restricted. (That is to say, you don't want to insist that each message be exactly N words in size - although for practical concerns, I'd accept some maximum upper bound. Dynamically allocating buffers could be a major problem.) An illegal package spec which would do the job would look something like this: package Mil_Std_1553 is function Msg_Waiting return BOOLEAN ; function Msg_ID return INTEGER ; procedure Get ( Msg : out ); procedure Put ( Msg : in ); end Mil_Std_1553; The requirements look something like this: -- The program wants to work with structured data (record types) -- The bus wants to work with 32 word chunks of raw words. It will want machine addresses of where to get/put the data, so you can probably make a big ring buffer and keep moving pointers around. -- The guy at the other end of the wire wants to send or receive predictable formatted data as spelled out in an interface control document (some well defined set of messages) -- The guy at the other end may have been programmed in almost any other language, so you can't count on the idiosyncrasies of a particular compiler/hardware combination. -- Output (from our side) is a little simpler because you can dynamically determine the size of the record structure that the data is parked in and use that to convert/block/xmit the data. -- Input is harder because you have to determine from the message ID where the data is ultimately to be parked. (You get a big case statement or lots of little guys being dispatched to check if the data is for them.) -- Buffering/Blocking/Deblocking/Hardware is all to be hidden invisibly in the package body - the client just wants to define a message and send/receive it while seeing as little as possible from the Mil_Std_1553 package. (avoid overlaying onto visible raw-word buffers, etc.) A traditional solution in languages like Ada83, C, Jovial, etc. has been to do some version of the following: -- Declare a fixed size raw-word array. -- Declare N record types & objects (or maybe 1 discriminated record type - although this contains its own form of punishment.) -- Use address clauses or other mechanisms to overlay the record objects on the raw word array. -- For sends, you move the data from some local record to the overlaid record object and call "Put" -- For receives, you check the Msg_ID (if data is waiting) and go into a big case statement to move the data to some local record. Discriminated records can be a help, but it generally means maintaining some mondo-big record declaration that is a pain to extend. You'd like to declare new messages on the fly and minimize impact. It seems like Ada95 ought to have a better answer, but I'm not smart enough to see it. -- Tagged records suggest a possible solution, but I've been having problems playing around with that. Output can be coerced by force (I have a relatively small example if anyone wants to see it) but you've got to get rid of the record tag. It's unpredictable and it can make problems for the other end - not to mention wasting a word of storage in the message) Input is a lot harder because you won't get the record tag in the message or it would be unpredictable. That, and you need to write lots of dispatched "Get" routines. -- Someone suggested streams, but I can't figure out how this would work. I'd need to see some small subset example because I just don't see it from my limited experience. -- Pointers to a record class may provide some help, but you're still stuck with the tag and the associated problems on the input side. -- If you could control the value and placement of the tag, you might have an answer because it could substitute for the message ID. But I'm not sure that's possible. -- You *really* need to limit data motion and buffering. You can't get around at least one buffer for the 1553 to read/write to/from. But you probably don't want to compute out of that buffer unless you're astronomically fast and you have predictable message intervals. The goal ought to be 2 moves: from/to local storage and up/down the wire (1553 hardware move) We'd also expect to have to implement buffer protection to eliminate risks of multiple task accesses (and hardware accesses!) to the buffer, but I think some version of protected types ought to handle this. You also want to avoid any dynamic allocation or unpredictable stack sizes and such so declaring lots of buffers on the fly is probably not a good answer. Anybody out there ever seen something like this done in Ada95? Can you suggest an approach? I'll e-mail my feeble attempts to program an output solution (compiles & runs using Gnat/WinNT) to anyone who asks. Thanks. MDC Marin David Condic, Senior Computer Engineer ATT: 561.796.8997 M/S 731-96 Technet: 796.8997 Pratt & Whitney, GESP Fax: 561.796.4669 P.O. Box 109600 Internet: CONDICMA@PWFL.COM West Palm Beach, FL 33410-9600 Internet: CONDIC@FLINET.COM =============================================================================== "When the going gets weird, the weird turn pro." -- Dr. Hunter S. Thompson ===============================================================================