doc-helmut wrote:no, you're wrong,
my wish always was to have multi-threading-safe BT access, your advice was to avoid multi-threaded access.
IIRC, the guidance by John and others was to avoid calling BT functions from across different threads at all times. Having done a lot of socket, serial and BT programming, this can generally be a good idea in certain software environments! The real question is, on a higher level: Is it possible to get fast and
asynchronous BT high level functions? And yes, the implementation answer will contain threads, of course. But nobody said it has to be possible to talk to the BT subsystem from different threads!
doc-helmut wrote:
A way might be to internally queue-up all in- or outgoing MT-based BT messages by a superordinate task using sort of a FIFO message stack before physically sending/receiving, and after that sending /receiving them by working off the stack.
And that is EXACTLY the way to do it! The BT functions are a bit fragile and sometimes quirky, yes. But with experience from experiments, you can use them reliably in a single threaded program. I know you did that! The real task now is to wrap all BT access in a single thread. Other threads can then carry out other things -- like polling sensors and motors.
The BT task has to be tight and simple: Just send and receive everything ASAP, in a round-robin fashion when talking to multiple NXTs. To keep the BT task utilized at full capacity, a data structure has to buffer incoming and outgoing packets, of course. You can use a queue for FIFO (or a priority queue for more fancy stuff), which I would recommend.
The BT task doesn't have to worry about forming packets or anything else. Just get data from the BT buffer to a user defined format, and vice versa.
Every external access to the incoming and outgoing queues is protected by mutexes!
A possible data structure for packets could be
Code: Select all
IncomingPacket:
- Sender (NXT/Connection Nr.)
- Data (Bytes/String), with length
OutgoingPacket:
- Recipient (NXT/Connection Nr.)
- Data (Bytes/String), with length
I know this is trivial, but this is all it takes. Even when it's not always possible to work easily with structs of arrays or arrays of structs, and without real pointers, you can still implement a small queue/ring buffer on your own! I'd personally "ignore" the mailbox system and not use it as part of this custom queue.
The queue push/pop operations to the queues need to be mutex protected.
The BT task then looks like this:
Code: Select all
repeat
{
while (!outgoingQueueIsEmpty())
{
sendBTPacket( pushFromOutgoingQueue() )
}
repeat
{
IncomingPacket packet = receiveBTPacket();
if( !packetIsEmpty(packet) )
{
pushToIncomingQueue(packet)
}
}
}
Then there are simple high level methods for sending and receiving:
send( packet ), packetsAvailable(), packet = receive()
(all usable outside the BT task, protected by mutexes). These functions can also return error codes when the queue is full, or drop packets, or block to wait out the bottleneck...
Use benchmarks how many packets per second (RX/TX) are possible to one NXT, two NXTs, three NXTs, and how much bytes/sec. Then you have limits on what is possible!
Other worker tasks can poll sensors and compile packets as fast as they can. Of course this is just the lowest level. The multiplexing and de-multiplexing can be done on top of this -- but it's not in the BT task and hence not a special problem.
doc-helmut wrote:
But it must be very quick though: I have to poll over all 20 sensors (touch, analog, i2c, 3 muxers) plus at least 4 encoder values on 3 remote NXTs in real-time (each and every sensor randomly 20 times each second), I have to control parallely 8 remote motors with max 100ms delay, and intermediately I have sometimes to transfer e.g. single numbers and up to 40x40 arrays of char from 1 NXT to an other one (numbers sometimes quickly, large arrays not time-sensitive).
Well yeah, you can also add: "And I need 100kb/s and 8 threads and a golden rainbow". These are ambitious goals, and you know it. Saying "I need all of this" doesn't help. Find out what is possible with a tight small BT task, get experimentally verified throughput rates, and work with it!
Ford, could you tell me the "best" BT functions you used to send and receive BT packets, which worked stable in single task mode? I know there are multiple versions out there, but I forgot which are the "official" ones to use...
Btw, the second video is blocked :-/.