New MessageRead feature in the enhanced NBC/NXC firmware
Posted: 26 Feb 2012, 03:37
In the enhanced NBC/NXC firmware version that I uploaded earlier today I have implemented a new feature in the MessageRead system call which underlies the ReceiveRemote* API functions in NXC (and ReceiveMessage along with SysMessageRead).
In the standard firmware, as has been explained on these forums before, if you have multiple slaves attached to a master NXT and you try to read, for example, MAILBOX1 then the firmware will attempt to retrieve a message from one of the slaves to put into MAILBOX1 if it happens to be empty when you execute the MessageRead system call function. The firmware starts with connection one the first time you call SysMessageRead if the mailbox is empty. The second time you call it tries connection 2 if the mailbox is still empty. The third time it tries connection 3 if the mailbox is still empty and it keeps on going around all the active connections until it eventually gets a response from a slave that puts a message into the mailbox you are trying to read from.
This gives the user no control over which connection gets used next regardless of which mailbox you may have your slaves configured to use. If you only have one active connection then there is no issue at all with this design but it definitely can cause problems when you have multiple active connections to other NXTs.
What I have done is made it possible to OR into the QueueID the connection number that you want to restrict the firmware to using if it finds an empty mailbox. You pass the connection number in as a value from 1 to 3 shifted left 6 bits. In other words, 0x40 = 1, 0x80 = 2, and 0xC0 = 3. If you want to read MAILBOX1 from connection 1 then you would pass MAILBOX1 | 0x40 into the API functions that read from a mailbox. With the enhanced firmware this will make it so that if the mailbox is empty it will only attempt to read from the remote device on the specified connection and not round-robin through all of the active connections.
I'd love to have some help testing this new feature and comparing the behavior with that of the standard firmware when you have multiple active connections and you use a different mailbox for each slave.
Just keep in mind that Bluetooth communication can be tricky - especially when you put functions that interact with the Bluetooth subsystem all throughout your program and call them in multiple tasks.
John Hansen
In the standard firmware, as has been explained on these forums before, if you have multiple slaves attached to a master NXT and you try to read, for example, MAILBOX1 then the firmware will attempt to retrieve a message from one of the slaves to put into MAILBOX1 if it happens to be empty when you execute the MessageRead system call function. The firmware starts with connection one the first time you call SysMessageRead if the mailbox is empty. The second time you call it tries connection 2 if the mailbox is still empty. The third time it tries connection 3 if the mailbox is still empty and it keeps on going around all the active connections until it eventually gets a response from a slave that puts a message into the mailbox you are trying to read from.
This gives the user no control over which connection gets used next regardless of which mailbox you may have your slaves configured to use. If you only have one active connection then there is no issue at all with this design but it definitely can cause problems when you have multiple active connections to other NXTs.
What I have done is made it possible to OR into the QueueID the connection number that you want to restrict the firmware to using if it finds an empty mailbox. You pass the connection number in as a value from 1 to 3 shifted left 6 bits. In other words, 0x40 = 1, 0x80 = 2, and 0xC0 = 3. If you want to read MAILBOX1 from connection 1 then you would pass MAILBOX1 | 0x40 into the API functions that read from a mailbox. With the enhanced firmware this will make it so that if the mailbox is empty it will only attempt to read from the remote device on the specified connection and not round-robin through all of the active connections.
I'd love to have some help testing this new feature and comparing the behavior with that of the standard firmware when you have multiple active connections and you use a different mailbox for each slave.
Just keep in mind that Bluetooth communication can be tricky - especially when you put functions that interact with the Bluetooth subsystem all throughout your program and call them in multiple tasks.
John Hansen