RTEMS | libtest: Add packet processor (#5057)

Sebastian Huber (@sebhub) gitlab at rtems.org
Tue Jul 2 06:36:50 UTC 2024



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.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/bugs/attachments/20240702/93d90197/attachment-0001.htm>


More information about the bugs mailing list