1 // Copyright 2021 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 #include "pw_log/levels.h" 17 #include "pw_log/options.h" 18 #include "pw_polyfill/static_assert.h" 19 #include "pw_tokenizer/config.h" 20 21 // The size of the stack-allocated argument encoding buffer to use by default. 22 // A buffer of this size is allocated and used for the 4-byte token and for 23 // encoding all arguments. It must be at least large enough for the token (4 24 // bytes). 25 // 26 // This buffer does not need to be large to accommodate a good number of 27 // tokenized string arguments. Integer arguments are usually encoded smaller 28 // than their native size (e.g. 1 or 2 bytes for smaller numbers). All floating 29 // point types are encoded as four bytes. Null-terminated strings are encoded 30 // 1:1 in size, however, and can quickly fill up this buffer. 31 #ifndef PW_LOG_TOKENIZED_ENCODING_BUFFER_SIZE_BYTES 32 #define PW_LOG_TOKENIZED_ENCODING_BUFFER_SIZE_BYTES \ 33 PW_TOKENIZER_CFG_ENCODING_BUFFER_SIZE_BYTES 34 #endif // PW_LOG_TOKENIZED_ENCODING_BUFFER_SIZE_BYTES 35 36 // This macro takes the PW_LOG format string and optionally transforms it. By 37 // default, pw_log_tokenized specifies three fields as key-value pairs. 38 #ifndef PW_LOG_TOKENIZED_FORMAT_STRING 39 40 #define _PW_LOG_TOKENIZED_FIELD(name, contents) "■" name "♦" contents 41 42 /// This macro takes the `pw_log` module name and format string to produce a new 43 /// string that will be tokenized. Any information can be packed into this 44 /// string without affecting code size, since tokenization removes it from the 45 /// binary. By default, `pw_log_tokenized` includes three fields as key-value 46 /// pair: log module, message, and file path (`__FILE__`). 47 #define PW_LOG_TOKENIZED_FORMAT_STRING(module, message) \ 48 _PW_LOG_TOKENIZED_FIELD("msg", message) \ 49 _PW_LOG_TOKENIZED_FIELD("module", module) \ 50 _PW_LOG_TOKENIZED_FIELD("file", __FILE__) 51 52 #endif // PW_LOG_TOKENIZED_FORMAT_STRING 53 54 // The log level, line number, flag bits, and module token are packed into the 55 // tokenizer's payload argument, which is typically 32 bits. These macros 56 // specify the number of bits to use for each field. A field with zero bits is 57 // excluded. 58 59 /// Bits to allocate for the log level. Defaults to @c_macro{PW_LOG_LEVEL_BITS} 60 /// (3). 61 #ifndef PW_LOG_TOKENIZED_LEVEL_BITS 62 #define PW_LOG_TOKENIZED_LEVEL_BITS PW_LOG_LEVEL_BITS 63 #endif // PW_LOG_TOKENIZED_LEVEL_BITS 64 65 /// Bits to allocate for the line number. Defaults to 11 (up to line 2047). If 66 /// the line number is too large to be represented by this field, line is 67 /// reported as 0. 68 /// 69 /// Including the line number can slightly increase code size. Without the line 70 /// number, the log metadata argument is the same for all logs with the same 71 /// level and flags. With the line number, each metadata value is unique and 72 /// must be encoded as a separate word in the binary. Systems with extreme space 73 /// constraints may exclude line numbers by setting this macro to 0. 74 /// 75 /// It is possible to include line numbers in tokenized log format strings, but 76 /// that is discouraged because line numbers change whenever a file is edited. 77 /// Passing the line number with the metadata is a lightweight way to include 78 /// it. 79 #ifndef PW_LOG_TOKENIZED_LINE_BITS 80 #define PW_LOG_TOKENIZED_LINE_BITS 11 81 #endif // PW_LOG_TOKENIZED_LINE_BITS 82 83 /// Bits to use for implementation-defined flags. Defaults to 2. 84 #ifndef PW_LOG_TOKENIZED_FLAG_BITS 85 #define PW_LOG_TOKENIZED_FLAG_BITS 2 86 #endif // PW_LOG_TOKENIZED_FLAG_BITS 87 88 /// Bits to use for the tokenized version of @c_macro{PW_LOG_MODULE_NAME}. 89 /// Defaults to 16, which gives a ~1% probability of a collision with 37 module 90 /// names. 91 #ifndef PW_LOG_TOKENIZED_MODULE_BITS 92 #define PW_LOG_TOKENIZED_MODULE_BITS 16 93 #endif // PW_LOG_TOKENIZED_MODULE_BITS 94 95 static_assert((PW_LOG_TOKENIZED_LEVEL_BITS + PW_LOG_TOKENIZED_LINE_BITS + 96 PW_LOG_TOKENIZED_FLAG_BITS + PW_LOG_TOKENIZED_MODULE_BITS) == 32, 97 "Log metadata fields must use 32 bits"); 98 99 #ifdef __cplusplus 100 101 #include <cstddef> 102 103 namespace pw::log_tokenized { 104 105 // C++ constant for the encoding buffer size. Use this instead of the macro. 106 inline constexpr size_t kEncodingBufferSizeBytes = 107 PW_LOG_TOKENIZED_ENCODING_BUFFER_SIZE_BYTES; 108 109 } // namespace pw::log_tokenized 110 111 #endif // __cplusplus 112