Thank you, that gives a clear picture.
You would be able to create a function
GetUDPPayloadBuffer() with the FromISR suffix, but as you might guess, it would be “mission impossible” to create a
sendto() function that runs from an ISR.
How many bytes do you receive in an SPI message? Varying from… to …?
Are you using BufferAllocation_1 or 2?
What about the following: before starting you preallocate e.g. 4 UDP payload buffers. You put their addresses in a queue called “empty_buffers”.
The SPI interrupt will pass the address of a free buffer to SPI/DMA.
Also, when a buffer is full, the buffer will be passed to a queue called “full_buffers”.
A high-priority task
udp_send() is blocking on the queue “full_buffers”. As soon as it gets a packet, it will send it to the LAN. At the same time, it will call
GetUDPPayloadBuffer() to create a new buffer and pass it to “empty_buffers”.
( The buffer that was passed to
sendto() will be released by the Network interface. )
Of course you can put the UDP buffers into an envelope, a struct that gives some more information like: number of bytes read, time-stamp or whatever debug information:
#define MAX_UDP_BUFFERS 4
enum eBufferStatus eStatus;
} xEnvelopes[ MAX_UDP_BUFFERS ];
In this solution you will use queues between a single sender and a single receiver. That means that you can also use a stream buffer in stead.
About the priorities:
higher: the network interface: prvEMACHandlerTask()
normal: the IP-task: prvIPTask() ( macro ipconfigIP_TASK_PRIORITY )
below-normal: the new
lower: all other tasks that make use of the +TCP library.