Sebastian Huber created an issue: 
https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5057

Assignee: Sebastian Huber

## Summary

libtest: Add packet processor

The RTEMS Test Framework packet processor provides a simple mechanism to 
exchange reliable and in-order data through transmitting and receiving one 
character at a time.

The packet processor does not buffer data. The processor uses a stop-and-wait 
automatic repeat request method. There is at most one packet in transmission. 
The data transfer is done using a single character input and output method. The 
protocol uses 12-bit sequence numbers, so a host could use a sliding window 
method to increase throughput. All integers and data are base64url encoded. A 
24-bit CRC is used to ensure the data integrity. The `{` character starts a 
packet. The `}` character terminates a packet. The `#` character prefixes a 
24-bit CRC value. The `:` character separates fields. The `+` character 
prefixes data fields. The following packets are defined:

* hello: `{<12-bit seq><12-bit ack>:H#<24-bit CRC>}` 
* acknowledge: `{<12-bit seq><12-bit ack>:A#<24-bit CRC>}` 
* reject: `{<12-bit seq><12-bit ack>:R :<12-bit seq of rejected packet> 
#<24-bit CRC>}` 
* signal: `{<12-bit seq><12-bit ack>:S :<64-bit signal number> :<64-bit signal 
value> <optional list of colon separated 64-bit values> #<24-bit CRC>}`
* channel: `{<12-bit seq><12-bit ack>:C :<64-bit channel number> :<64-bit 
channel data size> <optional list of colon separated 64-bit values> #<24-bit 
CRC> + #<24-bit CRC>}`

The intended use case are boot loaders and test runners. For example, test 
runners may interface with an external test server performing equipment 
handling on request using the packet processor.

Use `T_packet_initialize()` to initialize the packet processor. Use 
`T_packet_process()` to drive the packet processing. You can enqueue packets 
for transmission with `T_packet_enqueue()`. You can reliably send signals with 
`T_packet_send()`. You can reliably, in-order transmit and receive channel data 
with `T_packet_channel_push()` and `T_packet_channel_exchange()`.

A simple boot loader for test runs could be implemented like this:

```c
      #include <bsp.h>
      #include <rtems/bspIo.h>
      #include <rtems/counter.h>
      #include <rtems/test-packet.h>
    
      typedef struct {
        T_packet_event_control base;
        uint8_t *load_address;
      } boot_control;
    
      static void output_char(T_packet_control* self, uint8_t ch) {
        (void)self;
        rtems_putc(ch);
      }
    
      static T_packet_status event_handler(T_packet_control* self,
                                           T_packet_event_control* base,
                                           T_packet_event evt) {
        boot_control* evt_ctrl = (boot_control*)base;
    
        switch (evt) {
          case T_PACKET_EVENT_SIGNAL:
            if (T_packet_get_signal_number(self) == 0) {
              T_packet_output_acknowledge(self);
              bsp_restart(T_packet_get_signal_value_as_address(self));
            }
    
            break;
          case T_PACKET_EVENT_HELLO:
            T_packet_output_acknowledge(self);
            break;
          case T_PACKET_EVENT_CHANNEL_BEGIN:
            if (T_packet_get_channel_number(self) == 0) {
              void *address;
    
              if (T_packet_get_extra_count(self) >= 1) {
                address = T_packet_get_extra_as_address(self, 0);
                evt_ctrl->load_address = address;
              } else {
                address = evt_ctrl->load_address;
              }
    
              T_packet_set_channel_target(self, address);
            }
    
            break;
          case T_PACKET_EVENT_CHANNEL_END:
            if (T_packet_get_channel_number(self) == 0) {
              evt_ctrl->load_address += T_packet_get_channel_size(self);
              T_packet_output_acknowledge(self);
            }
    
            break;
          case T_PACKET_EVENT_OUTPUT_END:
            rtems_putc('\n');
            break;
          default:
            break;
        }
    
        return T_PACKET_SUCCESSFUL;
      }
    
      static uint32_t clock_monotonic(T_packet_control* self) {
        (void)self;
        return rtems_counter_read();
      }
```

See also:

* https://lists.rtems.org/pipermail/devel/2024-January/077181.html
* https://lists.rtems.org/pipermail/devel/2024-January/077055.html

-- 
View it on GitLab: https://gitlab.rtems.org/rtems/rtos/rtems/-/issues/5057
You're receiving this email because of your account on gitlab.rtems.org.


_______________________________________________
bugs mailing list
bugs@rtems.org
http://lists.rtems.org/mailman/listinfo/bugs

Reply via email to