6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Apr 26, 2024 11:07 pm

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Serbus protocol
PostPosted: Sat Jun 23, 2007 6:04 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Garth and others who plan on using the serial bus Garth and I designed...

In writing up a design document for the Serbus (serial bus) protocol, I have run into an interesting design problem that I'll need help in resolving.

First, some elementary background (fasten your seatbelts, this will go by fast):

A peripheral is that box that you plug into the Serbus port.

An object is a device under the control of the peripheral. Example: an IDE controller allows up to two harddrives, CD-ROM drives, et. al. to be attached. Therefore, an IDE controller would expose two objects to the Serbus implementation.

An interface is the set of commands that an object responds to. For example, a mouse can offer both button presses and releases as well as position announcements, whereas a keyboard can give only button presses and releases. However, a keyboard typically has a set of LEDs that can be controlled, while the mouse doesn't.

An interface ID is a single byte used on the wire for invoking commands on an object, so that we don't have to waste a lot of bytes for every command or response.

To support bootstrapping the discovery process, the peripheral is itself also an object. This also allows for expanding the bus via switches if necessary. However, this isn't really relavent to my question.

On to the question at hand . . .

A host might send an object the command, "Do you support IDE harddrive commands?" If it does, it'll return a success code with whatever other data needs to be communicated (like interface ID, etc). If it doesn't, a failure code is sent back. Very simple.

The question I have is, how do you prefer to identify interfaces during a query command? There are three approaches, basically:

(1) A central authority can hand out interface identifiers on-demand. This is essentially what IEEE is doing with Ethernet addresses (to sell Ethernet cards, you get blocks of up to 65536 Ethernet IDs at a time). This is also what USB does too.

(2) Microsoft COM demonstrated that using UUIDs is a viable approach for identifying interfaces on objects. The UUID includes the interface author's Ethernet address if available (since it already is guaranteed unique), but if not, it's typically computed as an MD5 cryptographic hash of some other information on the system. Either way, it's a fixed-sized field of 16 bytes, which is statistically unique. They're computed exactly once, and listed in software header files and in print. E.g., a Forth block device might support an interface "named" SB_IForthBootDevice, which could perhaps be mapped to:

Code:
static const char const SB_IForthBootDevice[16] = {
  0x10, 0x42, 0xFE, 0x8A, 0x9A, 0x56, 0xBD, 0xD5,
  0xFF, 0xA5, 0x21, 0x00, 0x05, 0x22, 0xCD, 0xEA
};


(3) Java and CORBA both demonstrate that textual interface IDs are viable as an approach as well, provided enough hierarchy exists. For example, the Kestrel will be interested in using the first available block storage device as a bootstrap source as well as for the Forth block storage system. Therefore, objects can be queried to see if they support the "com.falvotech.kestrel.storage.rawBlock" interface, and if they do, the first one found is used to boot from.

I really don't have the resources to implement option (1), so my question is, which of (2) or (3) would you prefer? Please try to consider things both as a manufacturer of peripherals as well as a programmer.

Thanks for any feedback you can offer. :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Serbus protocol
PostPosted: Sat Jun 23, 2007 7:12 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 990
Location: near Heidelberg, Germany
kc5tja wrote:
Garth and others who plan on using the serial bus Garth and I designed...

Quote:
A host might send an object the command, "Do you support IDE harddrive commands?" If it does, it'll return a success code with whatever other data needs to be communicated (like interface ID, etc). If it doesn't, a failure code is sent back. Very simple.

The question I have is, how do you prefer to identify interfaces during a query command? There are three approaches, basically:

(1) A central authority can hand out interface identifiers on-demand. This is essentially what IEEE is doing with Ethernet addresses (to sell Ethernet cards, you get blocks of up to 65536 Ethernet IDs at a time). This is also what USB does too.

(2) Microsoft COM demonstrated that using UUIDs is a viable approach for identifying interfaces on objects. The UUID includes the interface author's Ethernet address if available (since it already is guaranteed unique), but if not, it's typically computed as an MD5 cryptographic hash of some other information on the system. Either way, it's a fixed-sized field of 16 bytes, which is statistically unique.

Quote:
(3) Java and CORBA both demonstrate that textual interface IDs are viable as an approach as well, provided enough hierarchy exists. For example, the Kestrel will be interested in using the first available block storage device as a bootstrap source as well as for the Forth block storage system. Therefore, objects can be queried to see if they support the "com.falvotech.kestrel.storage.rawBlock" interface, and if they do, the first one found is used to boot from.


Well, actually the third option is basically the same as the first option - only that the central authority can be interpreted as the internet domain name system, where the namespace root "com.falvotech" is owned by the same entity owning the internet domain "falvotech.com". In fact this works and scales pretty well :-)
If you have the resources, I'd prefer this one. OTOH, the names can become quite long, where you have to decide whether you spend the resources needed to handle these names in a 6502/65816.

I'd stay away from the UUID approach. Although they are statistically unique, they are only statistically unique and not really unique. I don't know how windows handles this, but I don't want to debug a system where suddenly a problem pops up due to a UUID collision. Also they are hard to read and to remember (similar to ethernet addresses, but even longer)

Quote:
I really don't have the resources to implement option (1), so my question is, which of (2) or (3) would you prefer? Please try to consider things both as a manufacturer of peripherals as well as a programmer.


I wonder if option (1) really is so much work. I'm doing something similar to this with the optional headers in the o65 file format. IIRC Noone actually ever asked me for an extension. But then defining these interfaces admittedly is more work, because there are new objects all the time.

You also have to consider that more than one person can create an interface for a device, say a specific mouse with more than usual buttons (or different mice with the same higher number of buttons). If you don't want to be the clearing house, you would at least have to provide a forum where developers can come together to define a common interface. And for this common interface you might want to reserve a specific namespace anyway.

hope this help
André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jun 23, 2007 7:34 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
My use of Java-style paths is a bad example, and wasn't intended (and, I think, a bad idea anyway -- how many companies have defined Java APIs, but gone out of business later in life? What happens to the IDs when some other company purchases a domain that conflicts with an old Java module path?). A more likely example is this (more CORBA-like):

    * kestrel.storage.block.forth -- Forth-optimized interface for block storage
    * kestrel.ui.keyboard -- Keyboard input device
    * kestrel.ui.mouse -- Mouse input device


That way, I'd be master over the kestrel.* namespace, but other root-level names would be the domain of others.

Basically, I'm trying to capture the niceness of having a Commodore-like command protocol over the Serbus. But, I'd like the protocol to also be a bit more organized than Commodore's approach as well. If you have other ideas, I'm open to suggestion. :)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jul 27, 2007 6:55 pm 
Offline

Joined: Thu Jul 26, 2007 4:46 pm
Posts: 105
I'd suggest MAC address based UUIDs. Theyre even more statisitically unique than the other common generation method.

For comparison, a UUID I generated today and a month ago using the MAC method:
Today: f39f9e24-3c71-11dc-90d3-000c412297ef
Month ago: 9fa3fb88-28a0-11dc-9d7b-000c412297ef

You will notice some digits in common. Those are seeded from the MAC address. The benefit is theyre only 16 bytes, so comparing them is much faster than a character string, and they take less memory.

URLs also work, but theyre verbose.

Your method, of "kestrel.x," doesn't IMO. Fact is, chance of conflict because of expired domain is lower than for two people coming up with the same name. But it's still higher than a UUID.

In the system I'm designing, I use UUIDs for devices and interfaces. A device, ID X, says it supports N interfaces, A, B, C...

Devices also contain a name string, but this is mainly for utilities like "lspci"

(Incidentally, the bus I'm designing is a low speed 3-pin serial bus for things like keyboards, mice and joysticks)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jul 29, 2007 4:46 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
I'm well aware about UUIDs -- I wrote a COM clone for Linux years ago. :-) I generally like UUIDs.

Is the bus you're working on going to be openly documented? Is it feasible to combine efforts with respect to capability discovery and configuration?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jul 29, 2007 6:19 pm 
Offline

Joined: Thu Jul 26, 2007 4:46 pm
Posts: 105
Yes, the bus is going to be open.

I'm thinking it's actually going to be 4 lines - VDD, DATA, /DETECT and VSS

(I'm going to use XXh to signify hex here)

The bus uses 4-bit addressing, and 4-bit for it's autoconfigure commands. Devices can use 8-Bit commands if they want, except 0Xh, since 0Xh is used)

Autoconfiguration is done by sending command 00Xh to device 0h, where X is the address that the host wants the device to move to. If the host has ran out of addresses, then it will send a zero to indicate this. It then queries the device by again issuing command 01h. The device then responds with:
It's UUID and the UUID of the interfaces it supports. Finally, it responds with 0h or 1h, which is the state of the device's /DETECT pin. If the detect pin is active, then the host will send command 020h, which informs the device to attach it's slave to the bus.

The only other bus commands are 03h, poll interrupt (4-bit flags: power, detect, reserved (Set to 0) and device, where device is used by the device to signal a condition), 04h, sleep, 05h, wakeup, and 06h additional feature detect.

When I mentioned "If the detect pin is active, then the host will send command 020h, which informs the device to attach it's slave to the bus", there is a reason for the parameter: A device can be an up to 4-Port hub, and if it's interface is the standard hub interface, then this parameter selects which bus to activate. A bus cannot be deactivated.

The actual wire protocol is 115kbaud serial, 5-bit word length, 1 start bit, 1 stop bit, even parity. The first of the 5-bits is used to determine if this is a device ID packet or a data packet. A device is allowed to draw up to 100mA from the bus, thus a host must be prepared for a 1.5amp power draw. A device must not draw more than 10mA until it is configured.

The DATA wire itself is open collector. I'm still wondering what to use to isolate the devices until the host sends the 02h command, however)

The bus protocol should be easily implemented in nearly any microcontroller.

Any comments?

-Owen


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jul 29, 2007 10:31 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
The description is too thick for me; it's not very clear to me at all. I guess I'll need to see diagrams to see how things interact.

Is there a facility to query a peripheral to see if it supports an interface as well? A la COM's IUnknown::QueryInterface() method?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jul 30, 2007 12:10 am 
Offline

Joined: Thu Jul 26, 2007 4:46 pm
Posts: 105
I could probably make it much more clear if I were writing this up for a PDF or such, and had better formatting available... Anyway,

Yes, support is implemented for querying a device's capabilites. However, a device may only implement one interface, since this is for simple peripherals (Think keyboards and mice). Also, it adds unwanted overhead when using a short serial word (That of selecting an interface). I envisiage that many peripherals will just use 15 commands from 1h to Fh, rather than the full 240 available.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 25 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: