1 // Copyright 2019 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 // This module defines a simple and unoptimized interface for byte-by-byte 17 // input/output. This can be done over a logging system, stdio, UART, via a 18 // photodiode and modulated kazoo, or basically any way to get data in and out 19 // of an application. 20 // 21 // This facade doesn't dictate any policies on input and output data encoding, 22 // format, or transmission protocol. It only requires that backends return a 23 // OkStatus() if the operation succeeds. Backends may provide useful error 24 // Status types, but depending on the implementation-specific Status values is 25 // NOT recommended. Since this facade provides a very vague I/O interface, it 26 // does NOT provide tests. Backends are expected to provide their own testing to 27 // validate correctness. 28 // 29 // The intent of this module for simplifying bringup or otherwise getting data 30 // in/out of a CPU in a way that is platform-agnostic. The interface is designed 31 // to be easy to understand. There's no initialization as part of this 32 // interface, there's no configuration, and the interface is no-frills WYSIWYG 33 // byte-by-byte i/o. 34 // 35 // 36 // PLEASE DON'T BUILD PROJECTS ON TOP OF THIS INTERFACE. 37 38 #include <cstddef> 39 #include <cstring> 40 #include <string_view> 41 42 #include "pw_bytes/span.h" 43 #include "pw_status/status.h" 44 #include "pw_status/status_with_size.h" 45 46 namespace pw::sys_io { 47 48 /// Reads a single byte from the `pw_sys_io` backend. 49 /// This function blocks until it either succeeds or fails to read a 50 /// byte. 51 /// 52 /// @pre This function must be implemented by the `pw_sys_io` backend. 53 /// 54 /// @warning Do not build production projects on top of `pw_sys_io`. 55 /// 56 /// @returns @rst 57 /// 58 /// .. pw-status-codes:: 59 /// 60 /// OK: A byte was successfully read and is in ``dest``. 61 /// 62 /// RESOURCE_EXHAUSTED: The underlying source vanished. 63 /// 64 /// @endrst 65 Status ReadByte(std::byte* dest); 66 67 /// Reads a single byte from the `pw_sys_io` backend, if available. 68 /// 69 /// @pre This function must be implemented by the `pw_sys_io` backend. 70 /// 71 /// @warning Do not build production projects on top of `pw_sys_io`. 72 /// 73 /// @returns @rst 74 /// 75 /// .. pw-status-codes:: 76 /// 77 /// OK: A byte was successfully read and is in ``dest``. 78 /// 79 /// UNAVAILABLE: No byte is available to read; try later. 80 /// 81 /// UNIMPLEMENTED: The function is not supported on this target. 82 /// 83 /// @endrst 84 Status TryReadByte(std::byte* dest); 85 86 /// Writes a single byte out the `pw_sys_io` backend. The function blocks until 87 /// it either succeeds or fails to write the byte. 88 /// 89 /// @pre This function must be implemented by the `pw_sys_io` backend. 90 /// 91 /// @warning Do not build production projects on top of `pw_sys_io`. 92 /// 93 /// @returns @rst 94 /// 95 /// .. pw-status-codes:: 96 /// 97 /// OK: A byte was successfully written. 98 /// 99 /// @endrst 100 Status WriteByte(std::byte b); 101 102 /// Writes a string out the `pw_sys_io` backend. 103 /// 104 /// This function takes a `string_view` and writes it out the `pw_sys_io` 105 /// backend, adding any platform-specific newline character(s) (these are 106 /// accounted for in the returned `StatusWithSize`). 107 /// 108 /// @pre This function must be implemented by the `pw_sys_io` backend. 109 /// 110 /// @warning Do not build production projects on top of `pw_sys_io`. 111 /// 112 /// @returns @rst 113 /// 114 /// .. pw-status-codes:: 115 /// 116 /// OK: All the bytes from the source string were successfully 117 /// written. 118 /// 119 /// In all cases, the number of bytes successfully written are returned as 120 /// part of the ``StatusWithSize``. 121 /// 122 /// @endrst 123 StatusWithSize WriteLine(std::string_view s); 124 125 /// Fills a byte span from the `pw_sys_io` backend using `ReadByte()`. 126 /// 127 /// This function is implemented by the facade and simply uses `ReadByte()` to 128 /// read enough bytes to fill the destination span. If there's an error reading 129 /// a byte, the read is aborted and the contents of the destination span are 130 /// undefined. This function blocks until either an error occurs or all bytes 131 /// are successfully read from the backend's `ReadByte()` implementation. 132 /// 133 /// @returns @rst 134 /// 135 /// .. pw-status-codes:: 136 /// 137 /// OK: The destination span was successfully filled. 138 /// 139 /// In all cases, the number of bytes successuflly read to the destination 140 /// span are returned as part of the ``StatusWithSize``. 141 /// 142 /// @endrst 143 StatusWithSize ReadBytes(ByteSpan dest); 144 145 /// Writes a span of bytes out the `pw_sys_io` backend using `WriteByte()`. 146 /// 147 /// This function is implemented by the facade and simply writes the source 148 /// contents using `WriteByte()`. If an error writing a byte is encountered, the 149 /// write is aborted and the error status is returned. This function blocks 150 /// until either an error occurs, or all bytes are successfully written from the 151 /// backend's `WriteByte()` implementation. 152 /// 153 /// @returns @rst 154 /// 155 /// .. pw-status-codes:: 156 /// 157 /// OK: All the bytes from the source span were successfully written. 158 /// 159 /// In all cases, the number of bytes successfully written are returned as 160 /// part of the ``StatusWithSize``. 161 /// 162 /// @endrst 163 StatusWithSize WriteBytes(ConstByteSpan src); 164 165 } // namespace pw::sys_io 166