ShapeShifter:
Just like the key/value database used by the Bridge.put() and Bridge.get() calls, the actual storage for the mailbox message queue is stored on the AR3391 processor and managed by the Linux code. The '32U4 need only keep the current message in memory, and request the next one from the Linux side as needed. This is essentially the same organization as Bridge.get() where the value is retrieved from the Linux side as needed.
::::SNIP::::
@ShapeShifter,
apparently, I am presuming too much. Apologizes to the original poster.
For simplicity, I will use byte in the following description as a common unit; but I could just as easily say char or int. In addition, I will make the same premise for inspecting a queue. That premise is:
A system in which one could query for a possible item requires a hold mechanism.
That is, if you are asking, "if there is something there", then I must put that something somewhere - until you ask if I have it. (This differs from asking for it, but I will cover that.)
When creating a mailing system, as was alluded to, it would be ideal to have the proper conditions. The system, in this case, is in-fact a double queue. The interfaces are equal and balanced, not just programtically, but in terms of resources. That means the ATMega32u4 and the AR9331 are equal; and they must be for this system to work cleanly.
Also, we must conclude there is no out-of-band means to do this; such as an extra electrical wire or circuit.
== the first implementation ==
A system in which one could query for a possible item requires a hold mechanism. And as such, it requires a queue because if one byte is waiting, another is commonly just behind. This can happen for a variety reason, but generally this type of system accomodates an over-run flag, which makes the system useful, but a bit limiting.
To be clear, we have one byte slot for waiting, one byte slot for queueing and a one byte flag. Next we will consider the same system, but with two bytes.
For the moment, I'll ignore the code to make this run.
== the second implementation ==
A system in which one could query for a possible item requires a hold mechanism. This time instead a holding queue, we use a flag - generally the simplest concept being a flip-flop. This flag would work one of two ways. #1 It could trigger an interrupt and the CPU could immediately (or very soon) get the byte. #2 It could just be a simple flag that could be polled. In which case, the loop that checks the flag, gets the byte.
In either case, this fails because the interface to the bridge is non-blocking and time-dependent, and there is no physical control line (no out-of-band line). In other words, this case has no flow control. So, for something like this (the mailing system) to work, it requires flow-control.
== third implementation ==
A system in which one could query for a possible item requires a hold mechanism. Since we are using a bidirectional queued system, flow-control must be accomplished somehow.
At this point, we consider XON/XOFF control (in-band software flow control). For systems using the ASCII character code, XOFF is generally represented using a character or byte with decimal value 19; XON with value 17.
This has one major problem. If we take two bytes out of the ASCII character set and makes them the flow control flags, then we essentially have a hole in our data. We could change the characters to something else, but it would have to be acceptable to our implementation. We'll say that this is acceptable.
== Back to the problem ==
So, let's look at the psudeo-code for this.
if (byte_available_for_bridge) {
get_byte
if (output_port_empty) {
put_byte_into_output
} elseif (hold_port_empty) {
put_byte_into_hold
} else {
raise_overflow_flag
}
}
Next, if we have an overflow flag, that is a third state we need to transmit to the other side. The three (3) states being:
- have data
- have no data
- data is over-run
We could get rid of the overflow_flag and keep a tight loop on both sides. And since we created a simple two byte value hole in our data set to handle flow control, this could work. But we'll still need to signal the other CPU that data is available.
In other words, in software we have flow control, but no method of signalling that data is available.
At this point the choice is, get the data quickly or have a hole in your data set.
The alternative, what was implemented, is:
if (byte_available_for_bridge) {
get_byte
put_byte_into_output
}
The one case I intentionally did not cover, is a double byte sequence. In this case, the second byte carries the state information of the other CPU/MPU. The downside is this cuts the bandwidth in half.
I'm not sure I covered the most important cases, or all the cases. I'm not entirely sure I was clear either, but I hope this helps.
On this part, I will be very clear. The serial port used with the bridge is a two wire serial port, and nothing more. And we could have a signal for flow control, or data over-run, or both, but at the sacrifice of a hole in our data set.
Jesse