blob: 1b9282b907667bbeb40002690ee74f0442c0e33f [file] [log] [blame]
.. _module-pw_hdlc:
.. rst-class:: with-subtitle
=======
pw_hdlc
=======
.. pigweed-module::
:name: pw_hdlc
- **Simple**: Transmit RPCs and other data between devices over serial
- **Robust**: Detect corruption and data loss
- **Efficient**: Stream to transport without buffering
.. include:: design.rst
:start-after: .. pw_hdlc-overview-start
:end-before: .. pw_hdlc-overview-end
Encoding looks like this:
.. pw_hdlc-encoding-example-start
.. tab-set::
.. tab-item:: C++
:sync: cpp
.. code-block:: cpp
// Writes a span of data to a pw::stream::Writer and returns the status. This
// implementation uses the pw_checksum module to compute the CRC-32 frame check
// sequence.
#include "pw_hdlc/encoder.h"
#include "pw_hdlc/sys_io_stream.h"
int main() {
pw::stream::SysIoWriter serial_writer;
Status status = pw::hdlc::WriteUIFrame(123 /* address */, data, serial_writer);
if (!status.ok()) {
PW_LOG_INFO("Writing frame failed! %s", status.str());
}
}
.. tab-item:: Python
:sync: py
.. code-block:: python
# Read bytes from serial and encode HDLC frames
import serial
from pw_hdlc import encode
ser = serial.Serial()
address = 123
ser.write(encode.ui_frame(address, b'your data here!'))
.. pw_hdlc-encoding-example-end
And decoding looks like this:
.. pw_hdlc-decoding-example-start
.. tab-set::
.. tab-item:: C++
:sync: cpp
.. code-block:: cpp
// Read individual bytes from pw::sys_io and decode HDLC frames.
#include "pw_hdlc/decoder.h"
#include "pw_sys_io/sys_io.h"
int main() {
std::byte data;
std::array<std::byte, 128> decode_buffer;
pw::hdlc::Decoder decoder(decode_buffer);
while (true) {
if (!pw::sys_io::ReadByte(&data).ok()) {
// Log serial reading error
}
Result<Frame> decoded_frame = decoder.Process(data);
if (decoded_frame.ok()) {
// Handle the decoded frame
}
}
}
.. tab-item:: Python
:sync: py
.. code-block:: python
# Decode data read from serial
import serial
from pw_hdlc import decode
ser = serial.Serial()
decoder = decode.FrameDecoder()
while True:
for frame in decoder.process_valid_frames(ser.read()):
# Handle the decoded frame
.. pw_hdlc-decoding-example-end
.. pw_hdlc-nav-start
.. grid:: 1
.. grid-item-card:: :octicon:`rocket` Get started & guides
:link: module-pw_hdlc-guide
:link-type: ref
:class-item: sales-pitch-cta-primary
How to set up and use ``pw_hdlc``
.. grid:: 2
.. grid-item-card:: :octicon:`code-square` API reference
:link: module-pw_hdlc-api
:link-type: ref
:class-item: sales-pitch-cta-secondary
Reference details about the ``pw_hdlc`` API
.. grid-item-card:: :octicon:`stack` Design
:link: module-pw_hdlc-design
:link-type: ref
:class-item: sales-pitch-cta-secondary
Design details about ``pw_hdlc``
.. grid:: 2
.. grid-item-card:: :octicon:`graph` Code size analysis
:link: module-pw_hdlc-size
:link-type: ref
:class-item: sales-pitch-cta-secondary
The code size impact of ``pw_hdlc``
.. grid-item-card:: :octicon:`list-ordered` RPC over HDLC example
:link: module-pw_hdlc-rpc-example
:link-type: ref
:class-item: sales-pitch-cta-secondary
A step-by-step example of sending RPCs over HDLC
.. grid:: 1
.. grid-item-card:: :octicon:`workflow` Experimental async router
:link: module-pw_hdlc-router
:link-type: ref
:class-item: sales-pitch-cta-secondary
An experimental asynchronous HDLC router using ``pw_channel``
.. pw_hdlc-nav-end
.. toctree::
:maxdepth: 1
:hidden:
guide
api
design
size
rpc_example/docs
router
Source code <https://cs.opensource.google/pigweed/pigweed/+/main:pw_hdlc/>