1.. _module-pw_hdlc: 2 3.. rst-class:: with-subtitle 4 5======= 6pw_hdlc 7======= 8.. pigweed-module:: 9 :name: pw_hdlc 10 11 - **Simple**: Transmit RPCs and other data between devices over serial 12 - **Robust**: Detect corruption and data loss 13 - **Efficient**: Stream to transport without buffering 14 15.. include:: design.rst 16 :start-after: .. pw_hdlc-overview-start 17 :end-before: .. pw_hdlc-overview-end 18 19Encoding looks like this: 20 21.. pw_hdlc-encoding-example-start 22 23.. tab-set:: 24 25 .. tab-item:: C++ 26 :sync: cpp 27 28 .. code-block:: cpp 29 30 // Writes a span of data to a pw::stream::Writer and returns the status. This 31 // implementation uses the pw_checksum module to compute the CRC-32 frame check 32 // sequence. 33 34 #include "pw_hdlc/encoder.h" 35 #include "pw_hdlc/sys_io_stream.h" 36 37 int main() { 38 pw::stream::SysIoWriter serial_writer; 39 Status status = pw::hdlc::WriteUIFrame(123 /* address */, data, serial_writer); 40 if (!status.ok()) { 41 PW_LOG_INFO("Writing frame failed! %s", status.str()); 42 } 43 } 44 45 .. tab-item:: Python 46 :sync: py 47 48 .. code-block:: python 49 50 # Read bytes from serial and encode HDLC frames 51 52 import serial 53 from pw_hdlc import encode 54 55 ser = serial.Serial() 56 address = 123 57 ser.write(encode.ui_frame(address, b'your data here!')) 58 59.. pw_hdlc-encoding-example-end 60 61And decoding looks like this: 62 63.. pw_hdlc-decoding-example-start 64 65.. tab-set:: 66 67 .. tab-item:: C++ 68 :sync: cpp 69 70 .. code-block:: cpp 71 72 // Read individual bytes from pw::sys_io and decode HDLC frames. 73 74 #include "pw_hdlc/decoder.h" 75 #include "pw_sys_io/sys_io.h" 76 77 int main() { 78 std::byte data; 79 std::array<std::byte, 128> decode_buffer; 80 pw::hdlc::Decoder decoder(decode_buffer); 81 while (true) { 82 if (!pw::sys_io::ReadByte(&data).ok()) { 83 // Log serial reading error 84 } 85 Result<Frame> decoded_frame = decoder.Process(data); 86 87 if (decoded_frame.ok()) { 88 // Handle the decoded frame 89 } 90 } 91 } 92 93 .. tab-item:: Python 94 :sync: py 95 96 .. code-block:: python 97 98 # Decode data read from serial 99 100 import serial 101 from pw_hdlc import decode 102 103 ser = serial.Serial() 104 decoder = decode.FrameDecoder() 105 106 while True: 107 for frame in decoder.process_valid_frames(ser.read()): 108 # Handle the decoded frame 109 110.. pw_hdlc-decoding-example-end 111 112.. pw_hdlc-nav-start 113 114.. grid:: 1 115 116 .. grid-item-card:: :octicon:`rocket` Get started & guides 117 :link: module-pw_hdlc-guide 118 :link-type: ref 119 :class-item: sales-pitch-cta-primary 120 121 How to set up and use ``pw_hdlc`` 122 123.. grid:: 2 124 125 .. grid-item-card:: :octicon:`code-square` API reference 126 :link: module-pw_hdlc-api 127 :link-type: ref 128 :class-item: sales-pitch-cta-secondary 129 130 Reference details about the ``pw_hdlc`` API 131 132 .. grid-item-card:: :octicon:`stack` Design 133 :link: module-pw_hdlc-design 134 :link-type: ref 135 :class-item: sales-pitch-cta-secondary 136 137 Design details about ``pw_hdlc`` 138 139.. grid:: 2 140 141 .. grid-item-card:: :octicon:`graph` Code size analysis 142 :link: module-pw_hdlc-size 143 :link-type: ref 144 :class-item: sales-pitch-cta-secondary 145 146 The code size impact of ``pw_hdlc`` 147 148 .. grid-item-card:: :octicon:`list-ordered` RPC over HDLC example 149 :link: module-pw_hdlc-rpc-example 150 :link-type: ref 151 :class-item: sales-pitch-cta-secondary 152 153 A step-by-step example of sending RPCs over HDLC 154 155.. grid:: 1 156 157 .. grid-item-card:: :octicon:`workflow` Experimental async router 158 :link: module-pw_hdlc-router 159 :link-type: ref 160 :class-item: sales-pitch-cta-secondary 161 162 An experimental asynchronous HDLC router using ``pw_channel`` 163 164.. pw_hdlc-nav-end 165 166.. toctree:: 167 :maxdepth: 1 168 :hidden: 169 170 guide 171 api 172 design 173 size 174 rpc_example/docs 175 router 176 Source code <https://cs.opensource.google/pigweed/pigweed/+/main:pw_hdlc/> 177