TI Utilities API
Log.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2025 Texas Instruments Incorporated - http://www.ti.com
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
498 #ifndef ti_log_Log__include
499 #define ti_log_Log__include
500 
503 
504 #include <stdint.h>
505 #include <stddef.h>
506 
507 #if defined (__cplusplus)
508 extern "C" {
509 #endif
510 
511 /*
512  * ======== ti_log_Log_ENABLE ========
513  * Enable instrumentation using link-time optimization implementation
514  *
515  * Define this symbol to add instrumentation at compile time.
516  * It must be defined before including this header file.
517  */
518 
519 #if defined(DOXYGEN) || ti_log_Log_ENABLE
520 /*
521  * =============================
522  * ======== Log Enabled ========
523  * =============================
524  */
525 
529 #define Log_TI_LOG_VERSION 0.2.0
530 
565 #define Log_MODULE_DEFINE(name, init) const Log_Module LogMod_ ## name = init
566 
594 #if defined(DOXYGEN) || defined(__IAR_SYSTEMS_ICC__)
595 #define Log_MODULE_DEFINE_WEAK(name, init) const __weak Log_Module LogMod_ ## name = init
596 #elif defined(__TI_COMPILER_VERSION__) || (defined(__clang__) && defined(__ti_version__)) || defined(__GNUC__)
597 #define Log_MODULE_DEFINE_WEAK(name, init) const Log_Module LogMod_ ## name __attribute__((weak)) = init
598 #else
599 #error "Incompatible compiler: Logging is currently supported by the following \
600 compilers: TI ARM Compiler, TI CLANG Compiler, GCC, IAR. Please migrate to a \
601 supported compiler."
602 #endif
603 
614 #define Log_MODULE_USE(name) extern const Log_Module LogMod_ ## name
615 
622 #define LOG_MODULE_SYM(name) LogMod_ ## name
623 
626 /* This macro protects against side effects of the C preprocessor expansion
627  * of log statements. Each log API should be guarded by it.
628  * An article explaining this behavior can be found here:
629  * https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
630  */
631 #define _Log_GUARD_MACRO(x) do{ x }while(0)
632 
633 /*
634  *
635  * ======== Log Private Macros ========
636  *
637  * The following macros are intended to be private to the log module and
638  * are not intended for use by the user. Private macros will start with _Log.
639  *
640  * In the case of multi level macros (macros that invoke other macros), a
641  * letter is appended at the end of the definition. With each level of nesting,
642  * the appended letter is incremented.
643  *
644  * For example: _Log_test --> _Log_test_A --> _Log_test_B
645  */
646 /* Extracts the first/remaining argument from __VA_ARGS__ */
647 #define _Log_CAR_ARG(N, ...) N
648 #define _Log_CDR_ARG(N, ...) __VA_ARGS__
649 
650 
651 /*
652  * ======== Meta string tokenization macros ========
653  */
654 /* Helper macro to concatenate two symbols */
655 #define _Log_CONCAT2_A(x,y) x ## _ ## y
656 #define _Log_CONCAT2(x,y) _Log_CONCAT2_A(x,y)
657 #define _Log_CONCAT3(x,y,z) _Log_CONCAT2(x,_Log_CONCAT2(y,z))
658 
659 /* Helper macro to concatenate two symbols */
660 #define _Log__TOKEN2STRING_A(x) #x
661 #define _Log_TOKEN2STRING(x) _Log__TOKEN2STRING_A(x)
662 
663 /* Macro to place meta string in a memory section separated by record separator */
664 #define _Log_APPEND_META_TO_FORMAT(opcode, \
665  file, \
666  line, \
667  level, \
668  module, \
669  format, \
670  nargs) \
671  _Log_TOKEN2STRING(opcode) "\x1e" \
672  _Log_TOKEN2STRING(file) "\x1e" \
673  _Log_TOKEN2STRING(line) "\x1e" \
674  _Log_TOKEN2STRING(level) "\x1e" \
675  _Log_TOKEN2STRING(module) "\x1e" \
676  _Log_TOKEN2STRING(format) "\x1e" \
677  _Log_TOKEN2STRING(nargs)
678 
679 /* Place a string in trace format section named ".log_data" locally
680  * This section must exist in the linker file
681  */
682 #if defined(__IAR_SYSTEMS_ICC__)
683 #define _Log_PLACE_FORMAT_IN_SECTOR(name, opcode, level, module, format, nargs)\
684  __root static const char name[] @ ".log_data" = \
685  _Log_APPEND_META_TO_FORMAT(opcode, \
686  __FILE__, \
687  __LINE__, \
688  level, \
689  module, \
690  format, \
691  nargs); \
692  __root static const char * const _Log_CONCAT2(Ptr, name) @ _Log_TOKEN2STRING(_Log_CONCAT2(.log_ptr, module)) = name;
693 #elif defined(__TI_COMPILER_VERSION__) || (defined(__clang__) && defined(__ti_version__)) || defined(__GNUC__)
694 #define _Log_PLACE_FORMAT_IN_SECTOR(name, opcode, level, module, format, nargs)\
695  static const char name[] \
696  __attribute__((used,section(".log_data"))) = \
697  _Log_APPEND_META_TO_FORMAT(opcode, \
698  __FILE__, \
699  __LINE__, \
700  level, \
701  module, \
702  format, \
703  nargs); \
704  static const char * const _Log_CONCAT2(Ptr, name) \
705  __attribute__((used,section(_Log_TOKEN2STRING(_Log_CONCAT3(.log_ptr, __LINE__, module))))) = name;
706 #else
707 #error "Incompatible compiler: Logging is currently supported by the following \
708 compilers: TI ARM Compiler, TI CLANG Compiler, GCC, IAR. Please migrate to a \
709 supported compiler."
710 #endif
711 
712 /*
713  * ======== Variadic macro workaround ========
714  */
715 /* Helper macro to count the number of arguments in __VA_ARGS_ */
716 #define _Log_NUMARGS(...) _Log_NUMARGS_A(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
717 #define _Log_NUMARGS_A(...) _Log_NUMARGS_B(__VA_ARGS__)
718 #define _Log_NUMARGS_B(_first, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
719 
720 /*
721  * Helper to select arg/noarg variant macro since empty va_arg fails
722  * when arguments are expected. Eg
723  * Log_VARIANT(test, A, 7, "Hello") -> test__noarg(A, 7, "Hello")
724  * Log_VARIANT(test, A, 7, "Hello %d", 42) -> test__arg1(A, 7, "Hello %d", 42)
725  */
726 #define _Log_VARIANT(x, module, level, ...) \
727  _Log_CONCAT2(x, _Log_NUMARGS_B(__VA_ARGS__, _arg8, _arg7, _arg6, _arg5, _arg4, _arg3, _arg2, _arg1, _noarg)) ( module, level, __VA_ARGS__ )
728 
729 /*
730  * ======== Module-level preprocessor include macros ========
731  */
732 
733 /* Helper macro to extract the second argument of a variable number of input
734  * args
735  */
736 #define _Log_SECOND_ARG(x, y, ...) y
737 
738 /* Temporary token name.
739  * Name must end in "1" for preprocessor substitution below to work.
740  */
741 #define _Log_TOKEN_1 0,
742 
743 /* Helper macro to check whether a symbol is defined with a non-zero value.
744  * If x is a preprocessor define, the conversion below shows the macro output:
745  * x = 0 -> 0
746  * x = 1 -> 1
747  * x (no value) -> 0
748  * (undefined) -> 0
749  */
750 #define _Log_DEFINED(x) _Log_DEFINED_A(x)
751 
752 /* If x is 1, _Log_TOKEN_##y turns into _Log_TOKEN_1 and is replaced with "0,"
753  * If x is anything else, _Log_TOKEN_##y turns into _Log_TOKEN_y.
754  */
755 #define _Log_DEFINED_A(y) _Log_DEFINED_B(_Log_TOKEN_##y)
756 
757 /* If z is "0,", _Log_SECOND_ARG is called with the triplet "0, 1, 0" and
758  * selects the second item in it, 1.
759  * If z is anything else, _Log_SECOND_ARG is called with the tuple "z 1, 0" and
760  * selects the second item in it, 0.
761  */
762 #define _Log_DEFINED_B(z) _Log_SECOND_ARG(z 1, 0)
763 
764 /* Empty Log buf macro to use when a log module is not enabled in the
765  * preprocessor during compilation
766  */
767 #define _Log_buf_C_0(module, level, format, data, size)
768 
769 /* Log_buf macro to use when a log module is enabled in the preprocessor during
770  * compilation.
771  */
772 #define _Log_buf_C_1(module, level, format, data, size) \
773  _Log_GUARD_MACRO( \
774  Log_MODULE_USE(module); \
775  _Log_PLACE_FORMAT_IN_SECTOR(_Log_CONCAT2(LogSymbol, __LINE__), \
776  LOG_OPCODE_BUFFER, \
777  level, \
778  LogMod_ ## module, \
779  format, \
780  0); \
781  LogMod_ ## module.buf(&LogMod_ ## module, \
782  level, \
783  (uint32_t)&_Log_CONCAT3(Ptr, LogSymbol, __LINE__), \
784  data, \
785  size); \
786  )
787 
788 /* First level indirection macro for Log_buf that delegates between an empty
789  * implementation and the actual log emission based on whether a module is
790  * enabled in the preprocessor during compilation.
791  *
792  * The _Log_DEFINED() macro generates a token output of [0, 1] that is then
793  * concatenated with "_Log_buf_C" to form the correct delegate macro name.
794  *
795  * The expected module define name is ti_log_Log_ENABLE_ | <module> and must be
796  * set to 1. E.g. "-Dti_log_Log_ENABLE_MyLogModule=1". Just defining the symbol in
797  * the preprocessor will not emit any logs.
798  */
799 #define _Log_buf_B(module, level, format, data, size) \
800  _Log_CONCAT2(_Log_buf_C, _Log_DEFINED(ti_log_Log_ENABLE_ ## module))(module, level, format, data, size)
801 
802 /* Redirects to cast all printf arguments to uintptr_t to avoid surprises if
803  * passing wider values and the compiler silently allows it.
804  *
805  * These redirects also allow us to select which delegate function pointer to
806  * load from the #Log_Module. There are dedicated wrappers for certain printf
807  * argument counts.
808  *
809  * - 0-3 args redirect to dedicated functions to avoid loading the argument
810  * count when LTO is enabled.
811  * - 4-8 args redirect to a generic implementation.
812  *
813  * The 4-8 args break point is a compromise between how often the wrapper can
814  * be expected to be used in an average application and the constant overhead
815  * associated with providing it at all. There is also overhead per Log_Module
816  * for each additional arg count wrapper used. This overhead is eliminated when
817  * LTO is enabled though.
818  */
819 #define _Log_printf__arg1(module, level, fmt, a0) \
820  module.printf1(&module, \
821  level, \
822  (uint32_t)&_Log_CONCAT3(Ptr, LogSymbol, __LINE__), \
823  (uintptr_t)a0)
824 #define _Log_printf__arg2(module, level, fmt, a0, a1) \
825  module.printf2(&module, \
826  level, \
827  (uint32_t)&_Log_CONCAT3(Ptr, LogSymbol, __LINE__), \
828  (uintptr_t)a0, \
829  (uintptr_t)a1)
830 #define _Log_printf__arg3(module, level, fmt, a0, a1, a2) \
831  module.printf3(&module, \
832  level, \
833  (uint32_t)&_Log_CONCAT3(Ptr, LogSymbol, __LINE__), \
834  (uintptr_t)a0, \
835  (uintptr_t)a1, \
836  (uintptr_t)a2)
837 #define _Log_printf__arg4(module, level, fmt, a0, a1, a2, a3) \
838  _Log_printf__arg(module, level, fmt, (uintptr_t)a0, \
839  (uintptr_t)a1, \
840  (uintptr_t)a2, \
841  (uintptr_t)a3)
842 #define _Log_printf__arg5(module, level, fmt, a0, a1, a2, a3, a4) \
843  _Log_printf__arg(module, level, fmt, (uintptr_t)a0, \
844  (uintptr_t)a1, \
845  (uintptr_t)a2, \
846  (uintptr_t)a3, \
847  (uintptr_t)a4)
848 #define _Log_printf__arg6(module, level, fmt, a0, a1, a2, a3, a4, a5) \
849  _Log_printf__arg(module, level, fmt, (uintptr_t)a0, \
850  (uintptr_t)a1, \
851  (uintptr_t)a2, \
852  (uintptr_t)a3, \
853  (uintptr_t)a4, \
854  (uintptr_t)a5)
855 #define _Log_printf__arg7(module, level, fmt, a0, a1, a2, a3, a4, a5, a6) \
856  _Log_printf__arg(module, level, fmt, (uintptr_t)a0, \
857  (uintptr_t)a1, \
858  (uintptr_t)a2, \
859  (uintptr_t)a3, \
860  (uintptr_t)a4, \
861  (uintptr_t)a5, \
862  (uintptr_t)a6)
863 #define _Log_printf__arg8(module, level, fmt, a0, a1, a2, a3, a4, a5, a6, a7) \
864  _Log_printf__arg(module, level, fmt, (uintptr_t)a0, \
865  (uintptr_t)a1, \
866  (uintptr_t)a2, \
867  (uintptr_t)a3, \
868  (uintptr_t)a4, \
869  (uintptr_t)a5, \
870  (uintptr_t)a6, \
871  (uintptr_t)a7)
872 
873 #define _Log_printf__arg(module, level, ...) \
874  module.printf(&module, \
875  level, \
876  (uint32_t)&_Log_CONCAT3(Ptr, LogSymbol, __LINE__), \
877  _Log_NUMARGS(__VA_ARGS__), \
878  _Log_CDR_ARG(__VA_ARGS__))
879 
880 #define _Log_printf__noarg(module, level, ...) \
881  module.printf0(&module, \
882  level, \
883  (uint32_t)&_Log_CONCAT3(Ptr, LogSymbol, __LINE__))
884 
885 /* Empty Log_printf macro to use when a log module is not enabled in the
886  * preprocessor during compilation
887  */
888 #define _Log_printf_C_0(opcode, module, level, ...)
889 
890 /* Log_printf macro to use when a log module is enabled in the preprocessor during
891  * compilation.
892  */
893 #define _Log_printf_C_1(opcode, module, level, ...) \
894  _Log_GUARD_MACRO( \
895  Log_MODULE_USE(module); \
896  _Log_PLACE_FORMAT_IN_SECTOR(_Log_CONCAT2(LogSymbol, __LINE__), \
897  opcode, \
898  level, \
899  LogMod_ ## module, \
900  _Log_CAR_ARG(__VA_ARGS__), \
901  _Log_NUMARGS(__VA_ARGS__)) \
902  _Log_VARIANT(_Log_printf, LogMod_ ## module, level, __VA_ARGS__); \
903  )
904 
905 /* First level indirection macro for Log_printf that delegates between an empty
906  * implementation and the actual log emission based on whether a module is
907  * enabled in the preprocessor during compilation.
908  *
909  * The _Log_DEFINED() macro generates a token output of [0, 1] that is then
910  * concatenated with "_Log_buf_C" to form the correct delegate macro name.
911  *
912  * The expected module define name is ti_log_Log_ENABLE_ | <module> and must be
913  * set to 1. E.g. "-Dti_log_Log_ENABLE_MyLogModule=1". Just defining the symbol
914  * in the preprocessor will not emit any logs.
915  */
916 #define _Log_printf_B(opcode, module, level, ...) \
917  _Log_CONCAT2(_Log_printf_C, _Log_DEFINED(ti_log_Log_ENABLE_ ## module))(opcode, module, level, __VA_ARGS__)
918 
935 #define Log_buf(module, level, format, data, size) _Log_buf_B(module, level, format, data, size)
936 
956 #define Log_printf(module, level, ...) _Log_printf_B(LOG_OPCODE_FORMATED_TEXT, module, level, __VA_ARGS__)
957 
962 #if defined(__IAR_SYSTEMS_ICC__)
963 #define _Log_DEFINE_LOG_VERSION(module, version) \
964  __root static const char _Log_CONCAT2(Log_ti_log_version, __COUNTER__)[] @ ".log_data" = \
965  _Log_APPEND_META_TO_FORMAT(LOG_OPCODE_VERSION, \
966  module, \
967  version, \
968  0, \
969  0, \
970  0, \
971  0)
972 #elif defined(__TI_COMPILER_VERSION__) || (defined(__clang__) && defined(__ti_version__)) || defined(__GNUC__)
973 #define _Log_DEFINE_LOG_VERSION(module, version) \
974  static const char _Log_CONCAT2(Log_ti_log_version, __COUNTER__)[] \
975  __attribute__((used,section(".log_data"))) = \
976  _Log_APPEND_META_TO_FORMAT(LOG_OPCODE_VERSION, \
977  module, \
978  version, \
979  0, \
980  0, \
981  0, \
982  0)
983 #else
984 #error "Incompatible compiler: Logging is currently supported by the following \
985 compilers: TI ARM Compiler, TI CLANG Compiler, GCC, IAR. Please migrate to a \
986 supported compiler."
987 #endif
988 
989 /* Generate a symbol in the elf file that defines the version of the Log API */
990 _Log_DEFINE_LOG_VERSION(Log, Log_TI_LOG_VERSION);
991 
1004 #define Log_MODULE_SET_LEVELS(module, levels) \
1005  _Log_GUARD_MACRO( \
1006  Log_MODULE_USE(module); \
1007  if (LogMod_ ## module.dynamicLevelsPtr != NULL) { \
1008  *LogMod_ ## module.dynamicLevelsPtr = levels; \
1009  } \
1010  )
1011 
1021 #define Log_MODULE_GET_LEVELS(module) \
1022  _Log_GUARD_MACRO( \
1023  Log_MODULE_USE(module); \
1024  if (LogMod_ ## module.dynamicLevelsPtr != NULL) { \
1025  *LogMod_ ## module.dynamicLevelsPtr; \
1026  } \
1027  else { \
1028  LogMod_ ## module.levels; \
1029  } \
1030  )
1031 
1032 #else /* defined(DOXYGEN) || ti_log_Log_ENABLE */
1033 
1034 /*
1035  * =================================================
1036  * ======== Log Disabled (default behavior) ========
1037  * =================================================
1038  */
1039 
1040 #define Log_MODULE_DEFINE(...)
1041 #define Log_MODULE_DEFINE_WEAK(name, init)
1042 #define Log_MODULE_USE(...)
1043 #define Log_printf(module, level, ...)
1044 #define Log_buf(module, level, ...)
1045 #define _Log_DEFINE_LOG_VERSION(module, version)
1046 #define Log_MODULE_SET_LEVELS(module, levels)
1047 #define Log_MODULE_GET_LEVELS(module)
1048 
1049 #endif /* defined(DOXYGEN) || ti_log_Log_ENABLE */
1050 
1051 
1052 
1062 typedef enum Log_Level {
1067  Log_DEBUG = 1 << 0,
1068 
1078  Log_VERBOSE = 1 << 1,
1079 
1087  Log_INFO = 1 << 2,
1088 
1103  Log_WARNING = 1 << 3,
1104 
1116  Log_ERROR = 1 << 4,
1117 
1122 
1127 } Log_Level;
1128 
1129 typedef const struct Log_Module_ Log_Module;
1130 
1131 typedef void (*Log_printf_fxn)(const Log_Module *handle,
1132  Log_Level level,
1133  uint32_t headerPtr,
1134  uint32_t numArgs,
1135  ...);
1136 
1137 typedef void (*Log_printfN_fxn)(const Log_Module *handle,
1138  Log_Level level,
1139  uint32_t headerPtr,
1140  ...);
1141 
1142 typedef void (*Log_buf_fxn)(const Log_Module *handle,
1143  Log_Level level,
1144  uint32_t headerPtr,
1145  uint8_t *data,
1146  size_t size);
1147 
1153 struct Log_Module_ {
1154  void *sinkConfig;
1171  uint32_t levels;
1172  uint32_t* const dynamicLevelsPtr;
1173 };
1174 
1199 __attribute__((weak)) void LogSinkDummy_printf(const Log_Module *handle,
1200  Log_Level level,
1201  uint32_t headerPtr,
1202  uint32_t numArgs,
1203  ...)
1204 {
1205  /* The function is defined as weak to allow definition (as opposed to just a
1206  * declaration) within this header file without running into symbol
1207  * conflicts during linking.
1208  * This way we do not need a separate library dependency just for this dummy
1209  * log sink.
1210  */
1211 
1212  /* Cast all input arguments to void to avoid unused argument warnings. */
1213  (void)handle;
1214  (void)level;
1215  (void)headerPtr;
1216  (void)numArgs;
1217 
1218  /* Do not perform any operations and return immediately. */
1219 }
1220 
1244 __attribute__((weak)) void LogSinkDummy_printfN(const Log_Module *handle,
1245  Log_Level level,
1246  uint32_t headerPtr,
1247  ...)
1248 {
1249  /* The function is defined as weak to allow definition (as opposed to just a
1250  * declaration) within this header file without running into symbol
1251  * conflicts during linking.
1252  * This way we do not need a separate library dependency just for this dummy
1253  * log sink.
1254  */
1255 
1256  /* Cast all input arguments to void to avoid unused argument warnings. */
1257  (void)handle;
1258  (void)level;
1259  (void)headerPtr;
1260 
1261  /* Do not perform any operations and return immediately. */
1262 }
1263 
1288 __attribute__((weak)) void LogSinkDummy_buf(const Log_Module *handle,
1289  Log_Level level,
1290  uint32_t headerPtr,
1291  uint8_t *data,
1292  size_t size)
1294  /* The function is defined as weak to allow definition (as opposed to just a
1295  * declaration) within this header file without running into symbol
1296  * conflicts during linking.
1297  * This way we do not need a separate library dependency just for this dummy
1298  * log sink.
1299  */
1300 
1301  /* Cast all input arguments to void to avoid unused argument warnings. */
1302  (void)handle;
1303  (void)level;
1304  (void)headerPtr;
1305  (void)data;
1306  (void)size;
1307 
1308  /* Do not perform any operations and return immediately. */
1309 }
1310 
1319 #define Log_MODULE_INIT_SINK_DUMMY \
1320  { \
1321  .sinkConfig = NULL, \
1322  .printf = LogSinkDummy_printf, \
1323  .printf0 = LogSinkDummy_printfN, \
1324  .printf1 = LogSinkDummy_printfN, \
1325  .printf2 = LogSinkDummy_printfN, \
1326  .printf3 = LogSinkDummy_printfN, \
1327  .buf = LogSinkDummy_buf, \
1328  .levels = 0, \
1329  .dynamicLevelsPtr = NULL, \
1330  }
1331 
1333 #if defined (__cplusplus)
1334 }
1335 #endif
1336 
1337 #endif // ti_log_Log__include
Definition: Log.h:1067
void(* Log_buf_fxn)(const Log_Module *handle, Log_Level level, uint32_t headerPtr, uint8_t *data, size_t size)
Definition: Log.h:1142
uint32_t *const dynamicLevelsPtr
Definition: Log.h:1172
const Log_printfN_fxn printf2
Definition: Log.h:1164
Log_Level
Log level bitmask values.
Definition: Log.h:1062
Definition: Log.h:1126
uint32_t levels
Definition: Log.h:1171
const Log_printf_fxn printf
Definition: Log.h:1155
Definition: Log.h:1078
void(* Log_printfN_fxn)(const Log_Module *handle, Log_Level level, uint32_t headerPtr,...)
Definition: Log.h:1137
const Log_printfN_fxn printf0
Definition: Log.h:1158
Definition: Log.h:1121
Log_Level level
Definition: Log.h:1200
Definition: Log.h:1116
Log_Level uint32_t headerPtr
Definition: Log.h:1200
Log_Level uint32_t uint32_t numArgs
Definition: Log.h:1200
Log_Level uint32_t uint8_t size_t size
Definition: Log.h:1293
Log module.
Definition: Log.h:1153
void * sinkConfig
Definition: Log.h:1154
Log_Level uint32_t uint8_t * data
Definition: Log.h:1289
Definition: Log.h:1087
const Log_printfN_fxn printf1
Definition: Log.h:1161
const Log_buf_fxn buf
Definition: Log.h:1170
__attribute__((weak)) void LogSinkDummy_printf(const Log_Module *handle
Dummy Log_printf delegate function implementation.
#define Log_TI_LOG_VERSION
Log version.
Definition: Log.h:529
const Log_printfN_fxn printf3
Definition: Log.h:1167
void(* Log_printf_fxn)(const Log_Module *handle, Log_Level level, uint32_t headerPtr, uint32_t numArgs,...)
Definition: Log.h:1131
Definition: Log.h:1103
© Copyright 1995-2025, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale