RTnetA: You can consider RTnet as an completely own network stack, though some data structures and algorithms are derived from the linux network stack.
A: Unless RTmac intercepts the transmission, the packet traverses the RTnet stack with the priority of the sending RTAI task.
Q: What are the algoritms used for message "scheduling" on RTnet?
A: Currently there is a TDMA algorithm implemented over RTmac, a generic media access control plugin. Two major revisions of TDMA exists: the first one supporting only one slot per station and only synchronious network startup came with RTnet up to release 0.9. TDMA revision 2, available since release 0.8, overcomes this limitation. Description below refers to it.
A: see http://sourceforge.net/mailarchive/message.php?msg_id=10303203
> I guess the day will come when we can add an Ethercat protocol module to RTnet, > maybe also Powerlink as an alternative RTmac discipline (it seems to be much like our TDMA). > Driving, e.g., Powerlink slaves by an RTnet master at moderate but still > hard-real-time update rates should be feasible. > > We spoke to both vendors several times without getting concrete > responses. E.g., early in 2002 I offered B&R to implement Powerlink for > free(!) as media access control protocol before Marc started his own > implementation. Today I think it was not that bad they didn"t reacted, > because our framework appears to be more flexible and is less remote-I/O > centred than most other protocols. I"m not that sure, for instance, if > it is possible to stack middlewares like RTPS or RT-CORBA on top of > those approaches. With RTnet - no big deal (see ORTE project for RTPS).
Q: Where do I go for more information on rtnet?
A: The main website of RTnet is: http://www.rtnet.org and there is a [RTnet mailinglist].
If you are looking for a special function you can easily find it in the RTnet cross reference on: http://www.rts.uni-hannover.de/rtnet/lxr/source
And here are some examples:
http://www.rts.uni-hannover.de/rtnet/lxr/source/addons/examples
modprobe rtnet modprove rt_eepro100 rtifconfig rteth0 up 192.168.1.1x 255.255.255.0
A: In this case this is just a harmless warning. You do not need to run rtifconfig twice. If you do not like this warning, you should load rtnet with a higher value of "rtskb_pool_default". The default for this value is 24 so you could use:
modprobe rtnet rtskb_pool_default=32
The reason for this warning is a busy network filling the not yet fully set up reception buffers. This effect does not occur on a RTmac/TDMA managed network when you are using the "rtnet" script to start up your station.
A: (The following is based on release 0.8.1, TDMA revision 2.1)
Each cycle is composed of several slots or time slices. On any given node only some of the slots are used to transmit. Each node must lay claim to at least one slot. In addition there are slot buffers which hold messages. Any socket you create and bind gets attached to a slot buffer. You can change the slot buffer that a socket is attached to via an ioctl() call (RTNET_RTIOC_XMITPARAMS). In addition, you can specify the message priority of the messages loaded via a given socket. Thus you can have two sockets attached to the same slot buffer but with different priorities and the one with the higher priority will always get its messages sent first. In the current implementation of the code there is an almost one-to-one coupling between slots and slot-buffers. The only exception is slot 1. This is the non-realtime slot used by the vnic. If a node does not define a slot 1 then all the NRT traffic gets loaded into slot buffer 0 (with the lowest message priority) and goes at slot 0.
The core of the processing is handled by a worker thread which runs at the highest real time priority (this is independent of the priority of the threads that the various sockets are created in.) What happens in that thread depends on whether you are a master, a backup master or a slave. If it is a master then the first thing it does in the worker thread is sleep until its time to send the next sync frame. When it wakes up it transmits that sync frame. Then it immediately looks at its first slot. It looks at the phasing for that slot, i.e., are we sharing it with other nodes and/or throttling the used bandwidth. If so, it checks if it is our turn to use it. If it’s not our turn then it keeps going through its slots until it finds one that is suppose to send this cycle. Assuming it finds a slot in which it is suppose to send this cycle, it then calculates the offset time to the beginning of that slot and goes to sleep for that period. When it wakes up (and only then) it checks the slot buffer associated with this slot to see if there is something to send. If so it sends it. ( It’s important to understand that the thread does not determine if there is anything to send until just at the moment it’s suppose to send. Thus, if you have a very long cycle and a node has a slot near the end, one only needs to insure that the socket loads the slot buffer sometime before the sending slot. They do not have to have it loaded before the beginning of the cycle.) After sending (or not if the slot buffer is empty) it continues looking to see if there is another slot this cycle in which it is suppose to send. If so, it sets the timer for the appropriate additional time to that slot’s offset and goes back to sleep. This process repeats until there are no more slots in which it is suppose to send this cycle. At that point it sets a timer for when the next sync frame is to go out and it goes back to sleep and the process repeats.
If a node is a slave then things are almost the same except instead of setting a timer for sending a sync frame, the worker thread does a blocking wait on a semaphore. When the sync frame arrives, the receive interrupt processes the packet and determines it is a sync frame and then it signals the semaphore. From that point on, the behavior is the same as that of the master. It goes through its list of slots and sees if there are any it is suppose to send this cycle. If so, it sets a sleep timer to the beginning of that slot and goes to sleep. It wakes and checks the slot buffer for a message to send and sends it, etc.. Once it’s finished with all its slots for that cycle it goes back and waits on the semaphore again. Note that this means if the master dies (and there is no backup master), the slave’s worker thread stalls at this sleep and never runs because no sync frames means nothing signals this semaphore. Because of the strong coupling from socket -> slot buffer -> slot, you basically have the case where any given socket can only send messages out during a single slot in the cycle. This means that if the socket’s sendmsg() call is asynchronous with the Rtnet sync frames, then there will be a worst case latency of at least an entire cycle because you might load the message immediately after that slot was checked (and found empty) and hence have to wait until next cycle before it’s checked again. Note that if the slot is shared via phasing, then the worst case latency grows to the number of phases times the cycle time. This latency will occur even if the node has multiple slots available within a cycle. Again, any given socket only fills one slot buffer and each slot basically has one slot buffer so, by default, each socket only attaches to one slot. Because of the way that the NRT slot (which is 1) can be ‘mapped’ over to the realtime slot buffer of slot 0, there is already a framework in place to allow a single slot buffer to be shared by multiple slots. Then, since a socket really attaches to a slot buffer, that socket would have its message go out in any of several defined slots. Then, you can give a node several slots within a cycle and the worst case latency will be the maximum separation between these multiple slots. This also may allow you to increase the cycle period which reduces the number of interrupts seen at both the master and the clients. I will be modifying the RTnet code to implement this and if it works, I’ll submit it for inclusion in the main project. [patch will be welcome - the project maintainer ;)]
Backup masters basically work just like primary masters, except that they additionally monitor the network for the scheduled synchronisation frame at the beginning of a cycle. If that frame is missing, the backup master sends out its own sync frame in a dedicated backup slot.
Update: The concept of joint-slots has now been implemented (tho not yet fully tested). It is part of the 0.9.0 release. With this feature you can assign several slots to a node and then 'join' the slot buffers together for all slots so that when you create a socket and bind it, its output goes out on the next available slot.