xmos / xcore_iot

Other
30 stars 39 forks source link

xLINK dynamic configuration example #440

Closed keithm-xmos closed 1 year ago

keithm-xmos commented 2 years ago

Add an example that demonstrates how to dynamically configure xLINKs (5 wire and 2 wire, streaming or not)

Potentially useful reference: https://www.xmos.ai/download/AN01024:-xCONNECT-dynamic-configuration-demo(1.0.0rc4).pdf

xmos-jmccarthy commented 2 years ago

Scope: lib_trycatch added to fwk_core xlink example in xcore_sdk/examples/freertos featuring 2 build configs, 2L and 5L (pending pinout check) example will just be a throughput test and require 2 explorer boards 2v0.

Targets: 2L max theoretical throughput is 160Mbit/s 5L max theoretical throughput is 400Mbit/s

andrewdewhurst commented 2 years ago

Just wondering about the implications of streaming channels on an RTOS. I think streaming channels are statically allocated, which consumes the resource forever, but also what happens when the destination process stalls? There is back-pressure to the sender, but once it backs-up, data is left in a pipeline between sender and receiver. So, it seems that when a transmitting and receiving task can be interrupted gets complicated!

xmos-jmccarthy commented 2 years ago

Streaming channels are a pair of channels that have the destinations set up for bidirectional communication, one way per channel. The only difference between them an "normal" channels is that bidirectional communication can occur without additional handshaking. (IE no need to send end tokens, change direction, etc). This is not due to anything inherent about the streaming channel. It is just because there are 2 channels. Here is a snippet from the tools provided header xcore/channel_streaming.h

_XCORE_INLINE streaming_channel_t s_chan_alloc() _XCORE_NOTHROW
{
  streaming_channel_t __c;

  if ((__c.end_a = chanend_alloc()))
  {
    if ((__c.end_b = chanend_alloc()))
    {
      // exception safe calls to __xcore_s_chanend_set_dest()
      chanend_set_dest(__c.end_a, __c.end_b);
      chanend_set_dest(__c.end_b, __c.end_a);
    }

They are not an issue for the current RTOS drivers setup and use the same mechanisms as the non streaming channel based drivers. An interrupt is setup on the RX end channel resource. When data comes in, the ISR triggers. What the ISR does from here can vary, with most drivers receiving the data and copying it into an RTOS buffer. An example of this would be the streaming channel output from the current and legacy mic array IO threads.

There can be issues, in the event that the receiving end has not emptied, but there are none inherently caused by the RTOS. The way most of the RTOS ISRs that handle this decoupling are set up, if for some reason the application was not meeting timing, the RTOS driver ISR would receive the data packet, see there is no space, and drop it, preventing an application crash at the cost of a lost data packet. The user can then add their own logic to handle a lost packet, be it assertion, ignore it, or some other logic.

andrewdewhurst commented 2 years ago

Not sure this is relevant, but I thought a normal channel blocked until the receiver side acknowledged it – so in the RTOS world I assume that the sender can’t get de-scheduled until it finishes. For a streaming channel, then the communication is still blocking but only when the pipeline of stages in the channel all et stalled – i.e. it backs up. Anyway, I was worrying about issues where you don’t know if the thing you sent was received, or if you could tear down a channel when there is still data in flight.

Anyway – I don’t need you to explain this to me, just worry about it for me!

Andrew

From: xmos-jmccarthy @.> Sent: 23 August 2022 16:38 To: xmos/xcore_sdk @.> Cc: Andrew Dewhurst @.>; Comment @.> Subject: Re: [xmos/xcore_sdk] xLINK dynamic configuration example (Issue #440)

Streaming channels are a pair of channels that have the destinations set up for bidirectional communication, one way per channel. The only difference between them an "normal" channels is that bidirectional communication can occur without additional handshaking. (IE no need to send end tokens, change direction, etc). This is not due to anything inherent about the streaming channel. It is just because there are 2 channels. Here is a snippet from the tools provided header xcore/channel_streaming.h

_XCORE_INLINE streaming_channel_t s_chan_alloc() _XCORE_NOTHROW

{

streaming_channel_t __c;

if ((__c.end_a = chanend_alloc()))

{

if ((__c.end_b = chanend_alloc()))

{

  // exception safe calls to __xcore_s_chanend_set_dest()

  chanend_set_dest(__c.end_a, __c.end_b);

  chanend_set_dest(__c.end_b, __c.end_a);

}

They are not an issue for the current RTOS drivers setup and use the same mechanisms as the non streaming channel based drivers. An interrupt is setup on the RX end channel resource. When data comes in, the ISR triggers. What the ISR does from here can vary, with most drivers receiving the data and copying it into an RTOS buffer. An example of this would be the streaming channel output from the current and legacy mic array IO threads.

There can be issues, in the event that the receiving end has not emptied, but there are none inherently caused by the RTOS. The way most of the RTOS ISRs that handle this decoupling are set up, if for some reason the application was not meeting timing, the RTOS driver ISR would receive the data packet, see there is no space, and drop it, preventing an application crash at the cost of a lost data packet. The user can then add their own logic to handle a lost packet, be it assertion, ignore it, or some other logic.

— Reply to this email directly, view it on GitHubhttps://github.com/xmos/xcore_sdk/issues/440#issuecomment-1224246739, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AKD2PCGBZD6HIHVSHDDEZQDV2TV37ANCNFSM5WW5EGIA. You are receiving this because you commented.Message ID: @.**@.>>