Writing a zero-copy NIC driver for a Kinetis K64.
Your porting examples show a deferred "task" processing incoming messages but state performance woud be better if done within an ISR.
Currently, I'm attempting to do just that within the Receive ISR but the stack is locking up.
I call xSendEventStructToIPTask() with the network buffer attached.
Within xSendEventStructToIPTask .. it calls:
xReturn = xQueueSendToBack( xNetworkEventQueue, pxEvent, xTimeout )
which attempts to place the buffer at the end of the queue.
First thing xQueueSendToBack does is call taskENTER_CRITICAL(); and then we're locked.
void vPortEnterCritical( void )
/* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if( uxCriticalNesting == 1 )
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
The Assert locks us because we are in an ISR.
What is (if there is) the proper way to pass the network buffer back to the stack when an incoming message is received when processing within the ISR?
I'm hoping there is a way as deferring the incoming message to a task is slow.
Any help/comments appreciated.
Thanks Dave -- I'm aware of that function BUT ... that function would have to be called within a function that the NIC would call ... as in a function named xSendEventStructToIPTask_ISR (I made this up as I'm asking if such a function exists).
I'm not sure I'm following.
- If the function is called from a task then use xQueueSend() [xQueueSendToBack() is the same].
- If the function is called from an ISR then use xQueueSendToBackFromISR().
- If the function is called from both a task and an interrupt then it is ok to use xQueueSendToBackFromISR() with due care, but it is not ok to call xQueueSend(). Alternatively, inside the function, check to see if you are in an interrupt or not and call the appropriate queue send version for the context.
Did I miss the point?
My question got side-tracked with the queue comments.
I mentioned the queue function because THAT is the function that is locking up when xSendEventStructToIPTask() is called within an ISR.
So ... is ther an ISR version of xSendEventStructToIPTask()?
No - but its quite a simple function so you could create one. You will
have to use the correct ISR safe API and not do things like print
anything out (as it is in an ISR context) but it should be easy enough.
I did that myself ... did not want to duplicate something you folks haf already written.
Just as a follow-up.
I decided to implement the deferred Rcv Task.
I do a LOT of pre-qualing the packet before I send it to the stack.
I don't like long interrupts and the RCV processing was on the edge, Over the edge if it processed several messages at one time.
So, I went with the safer RCV task.
I thought I would FYI after my posting this question.
If you wanted the stack to filter all the messages, then interrupt processing would be the best.
Thanks for all the comments.