Folks, I originally inquired on this to the fine folks at TI who, as is so appallingly typical, immediately shrugged their shoulders and suggested that I come here and spend y'alls' time and effort instead....
So, without further ado, below is the bulk of my inquiry email to them; any takers here?
Thanks in advance.
When using a higher level protocol stack above CANbus, the desired model from a receive perspective runs more towards a FIFO rather than an array of discrete mailboxes, as one will tend to want to get a potentially arbitrarily large assortment of message ID that effectively render the acceptance mask facilities useless; one instead must run with ‘wide open’ filters, and do the filtering in software. From this view, the eCAN construction is quite atrocious, as, basically, a message received into a mailbox can be overwritten at any time, e.g. while it is being read out of the box. The only way to prevent this is to create a pseudo FIFO of some number N of mailboxes via the overwrite protection mechanism, where N corresponds to things such as the CAN bus’s packet burst size and other traffic characteristics for a given application, and the device driver’s worst case interrupt latency and degree of preemption by higher priority ISRs, again for a given application, such that one can warrant the absence of overruns i.e. lost Rx messages.
So, one could e.g. create this pseudo FIFO using the range of mailboxes extending from #31 through #(31 – N + 1). And this range might well be the entirety of Rx mailboxes employed by the device driver.
However, the nature of the controller whereby, upon reception of a packet, it always begins its search for a mailbox (in which to place the message) with #31 and proceeds ‘downwards’ is problematic. Considering the ISR that services Rx’d messages: if there is a burst of Rx activity that results in storage in e.g. boxes 31-28 by the time that the ISR actually gets to where it can remove #31, how does it return that box to the controller? It can’t do it immediately, as e.g. a new or ongoing burst might then store into 31 & 27-25, and the temporal ordering of received messages is then lost, which can result in the failure of higher level protocols that presume (quite reasonably, in my view) that such ordering is preserved. So, in fact, this pseudo FIFO must have a length of 2N, with the ISR proceeding as follows:
- Start pulling messages at #31 and proceed downwards until either one runs out of messages or pulls N messages; don’t return the boxes to the controller
· - For the case where the number of pulled messages is < N, resume pulling at the stopping point in one or more future ISR invocations until N have been pulled.
· - When N have been pulled, return them all to the controller en masse, indeed, atomically. This creates a sufficient degree of ‘headroom’ so as to preserve ordering in the event of an imminent burst.
· - In the same ISR invocation wherein N have been pulled, continue downwards until no more messages are found; if none are found then check again on the next ISR invocation, to address a possible race condition. Here, the 2nd half of the pseudo FIFO is being used to cover bursting, or traffic generally, that may have occurred during the aforementioned ISR invocations where the headroom consisting of the 1st half of the pseudo FIFO was being reacquired. Mailboxes in the 2nd half, as they are emptied, can be returned to the controller individually / singly.
· - When it is certain that the 2nd half has been emptied, the process resumes with the 1st half.
So, all well and good, but how to negate the mailbox interrupt flag for boxes that have been emptied but are not ready for return to the controller? Sadly, it seems that both purposes rely upon the same action, i.e. the negation of a given box’s CANRMP bit!
And thus the actual question: how indeed to do this? Can I clear the given box’s CANME bit, and cause the negation, and later reenable it immediately prior to or after clearing CANRMP when I am ready to return it? Would clearing CANME, and then CANRMP, do the job, with re-setting of CANME to effect the return? Are rubber chickens necessary?