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 // Read a single byte from the sys io backend. 49 // Implemented by: Backend 50 // 51 // This function will block until it either succeeds or fails to read a byte 52 // from the pw_sys_io backend. 53 // 54 // Returns OkStatus() - A byte was successfully read. 55 // Status::ResourceExhausted() - if the underlying source vanished. 56 Status ReadByte(std::byte* dest); 57 58 // Read a single byte from the sys io backend, if available. 59 // Implemented by: Backend 60 // 61 // Returns OkStatus() - A byte was successfully read, and is in dest. 62 // Status::Unavailable() - No byte is available to read; try later. 63 // Status::Unimplemented() - Not supported on this target. 64 Status TryReadByte(std::byte* dest); 65 66 // Write a single byte out the sys io backend. 67 // Implemented by: Backend 68 // 69 // This function will block until it either succeeds or fails to write a byte 70 // out the pw_sys_io backend. 71 // 72 // Returns OkStatus() if a byte was successfully read. 73 Status WriteByte(std::byte b); 74 75 // Write a string out the sys io backend. 76 // Implemented by: Backend 77 // 78 // This function takes a null-terminated string and writes it out the sys io 79 // backend, adding any platform-specific newline character(s) (these are 80 // accounted for in the returned StatusWithSize). 81 // 82 // Return status is OkStatus() if all the bytes from the source string were 83 // successfully written. In all cases, the number of bytes successfully written 84 // are returned as part of the StatusWithSize. 85 StatusWithSize WriteLine(const std::string_view& s); 86 87 // Fill a byte span from the sys io backend using ReadByte(). 88 // Implemented by: Facade 89 // 90 // This function is implemented by this facade and simply uses ReadByte() to 91 // read enough bytes to fill the destination span. If there's an error reading a 92 // byte, the read is aborted and the contents of the destination span are 93 // undefined. This function blocks until either an error occurs, or all bytes 94 // are successfully read from the backend's ReadByte() implementation. 95 // 96 // Return status is OkStatus() if the destination span was successfully 97 // filled. In all cases, the number of bytes successuflly read to the 98 // destination span are returned as part of the StatusWithSize. 99 StatusWithSize ReadBytes(ByteSpan dest); 100 101 // Write span of bytes out the sys io backend using WriteByte(). 102 // Implemented by: Facade 103 // 104 // This function is implemented by this facade and simply writes the source 105 // contents using WriteByte(). If an error writing a byte is encountered, the 106 // write is aborted and the error status returned. This function blocks until 107 // either an error occurs, or all bytes are successfully read from the backend's 108 // WriteByte() implementation. 109 // 110 // Return status is OkStatus() if all the bytes from the source span were 111 // successfully written. In all cases, the number of bytes successfully written 112 // are returned as part of the StatusWithSize. 113 StatusWithSize WriteBytes(ConstByteSpan src); 114 115 } // namespace pw::sys_io 116