Friday, October 28, 2011

Mil Std 1553

I've been playing with a Mil Std 1553 bus for several weeks now, and I wanted to record what I've learned here.

1553 is a shared bus consisting of a Bus Controller (BC) and one or more Remote Terminal (RT). It is possible to go into "dynamic mode" where any device can act as a BC, but that is not how it is usually used. Instead, the BC normally knows everything about the systems- each RT, which messages they want to send, when and how often they can send what messages, etc. The BC is the only one that is allowed to use the bus- it polls the RTs for specific messages and the RTs must respond then and only then. It is possible for two RTs to talk if allowed by the devices themselves, but even then the BC asks one to talk to the other- they never start talking by themselves.

The polling that the BC does either tells an RT to send or receive a data message of a maximum of 32 words (with a word as 2 bytes). This poll is called a command message which consists of 20 bits of data, with 3 sync in the beginning, 16 bits of data, and an odd parity bit at the end. The data section contains a 5 bit RT address, where 0 and 31 are reserved as the broadcast address (although you can play with that a little), a bit indicating whether to send data or receive it, a 5 bit subaddress (which I'll get into in a minute), and 5 bits indicating the length of the message (where 0 indicates a message of length 32, so no 0 length messages are possible).

The subaddress is what tells the RT what type of message to send. We might even have 32 buffers of 32 words on the RT, where it just sends out the data in the 32 word section when it is requested. In practice its a lot more complex, but conceptually the subaddress is just an index into an array of 32 word messages structures. If the subaddress is given as 31 then it is not a request for data, but a mode-code. For mode codes, the 5 length bits indicate which mode messages is being sent rather then the length of a data transfer. Some mode messages will send out a single word of data, but that is simple specified in the standard, and must be known beforehand as it is not containing in the message itself except implicitly in the meaning of the code given. The mode codes are mostly for checking status, setting options, etc. The only one I've actually made use of is mode code 17, sync with data. This can be used periodically by the BC to keep the RTs in sync with it and to tell them a single word of data. It might, for example, be polling in a predetermined fashion, and the sync word might tell the RTs where it is in its schedule of message polls.

32 words of data is not enough to transport most messages. To extend the size of a message one can place it in multiple subaddresses and poll each one in turn, or poll the same subaddress multiple times and concatenate the results. The only problem with polling the same subaddress is that the RT or BC must be able to handle the rate at which it is requested, which can be fairly fast. A hardware mechanism for handling this is the easiest to deal with.

It is common for the BC to have a schedule giving a certain time slot to each message (1 ms for example) and always doing the same schedule each time period (1 second, for example). This schedule can change to only poll for messages that are needed, or to account for period messages like an occasional file transfer. Again, hardware support is important here, as the timing may have to be very accurate.

I think thats all I will say about Military Standard 1553 for now.

Tuesday, October 11, 2011

Breaking the Forth Wall

I've made yet more progress on my stand-alone Forth for the x86. I wanted to mention some interesting things about forth real quick while I work out some problems with the call-gate style of key handling and add DOES> words to the language.

There is some very interesting things about Forth as a language. It can very easily support simplified versions of some very powerful features from other languages such as coroutines, continuations, exception handling, closures, and object-orient features. Often these sorts of things are implemented in a similar spirit to other features in a Forth like memory management- the programmer takes more responsibility for her code than usual and the implementation is a simple one that has good enough characteristics to work for what the programmer needs. I could certainly program in Haskell and get all of the power I want in a language for most tasks, but Forth is interesting because it does these things in such a low level context, where we have access to every part of the system and can play with them as needed for whatever we want. For example, we can use the return stack to implement coroutines with a word as simple as ": yield r> r> swap >r >r ;". This will continue the word that called us, which can do the same thing to continue the word called. We might not get everything we want out of this type of implementation, and we have to be very careful to not mess things up, but its pretty good considering we are just above assembly language in terms of abstraction and we have to build everything ourselves.

Another thing I wanted to mention is that there seems to be some relationship between stack languages and functional programming. It is very natural for concatentive language to be seen as functional language where the main operation is composition rather than application. Notice that whitespace represents application in Haskell, but represents composition in Factor, Cat, Joy or Forth. Also, the concept of a graph reduction machine (which is used to give operational semantics to functional programming languages) apparently has found fast and very natural implementations on stack machines where the graph is compiled code (rather then traversing the graph structure with separate code).

In addition, I've been reading Moving Forths section about DOES>, explaining probably the most complex part of Forth, and they mention that the use of code fields in some ways anticipates object oriented programming. This reminded me of the STGM (Spineless Tagless Graph-Reduction Machine) which is Haskell's abstract machine and is implemented as its run-time system. I remember reading that they used essentially a code field to determine what to do with their objects (in the more general sense of entities in a program's memory) rather then tagging them with types and switching on the type (the tag is just a pointer to code that does the Right Thing). This is exactly how variables, constants, does words, and regular words are implemented in Forth. Its probably a well known technique, but Forth must have pioneered it.

Hopefully next time I will have an actual progress update and won't have to resort to a pun for a title.