sim: Allow Rust logging level to control C logging
Change the C logging code, when in the simulator, to query what the rust
logging level is set to. This allows the level of logging from the C
code to be set through the environment. For example
RUST_LOG=bootsim=info cargo run --release runall
will enable logging at the "info" level for all of the C code as well as
the simulator code. The C code's logging can be selected specifically
by using bootsim::api instead of just bootsim in the above.
diff --git a/boot/bootutil/include/bootutil/bootutil_log.h b/boot/bootutil/include/bootutil/bootutil_log.h
index 3cd03a3..e889397 100644
--- a/boot/bootutil/include/bootutil/bootutil_log.h
+++ b/boot/bootutil/include/bootutil/bootutil_log.h
@@ -78,30 +78,48 @@
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
#endif
+int sim_log_enabled(int level);
+
#if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_ERROR
-#define BOOT_LOG_ERR(_fmt, ...) \
- do { printf("[ERR] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_ERR(_fmt, ...) \
+ do { \
+ if (sim_log_enabled(BOOT_LOG_LEVEL_ERROR)) { \
+ printf("[ERR] " _fmt "\n", ##__VA_ARGS__); \
+ } \
+ } while (0)
#else
#define BOOT_LOG_ERR(...) IGNORE(__VA_ARGS__)
#endif
#if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_WARNING
-#define BOOT_LOG_WRN(_fmt, ...) \
- do { printf("[WRN] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_WRN(_fmt, ...) \
+ do { \
+ if (sim_log_enabled(BOOT_LOG_LEVEL_WARNING)) { \
+ printf("[WRN] " _fmt "\n", ##__VA_ARGS__); \
+ } \
+ } while (0)
#else
#define BOOT_LOG_WRN(...) IGNORE(__VA_ARGS__)
#endif
#if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_INFO
-#define BOOT_LOG_INF(_fmt, ...) \
- do { printf("[INF] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_INF(_fmt, ...) \
+ do { \
+ if (sim_log_enabled(BOOT_LOG_LEVEL_INFO)) { \
+ printf("[WRN] " _fmt "\n", ##__VA_ARGS__); \
+ } \
+ } while (0)
#else
#define BOOT_LOG_INF(...) IGNORE(__VA_ARGS__)
#endif
#if BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_DEBUG
-#define BOOT_LOG_DBG(_fmt, ...) \
- do { printf("[DBG] " _fmt "\n", ##__VA_ARGS__); } while (0)
+#define BOOT_LOG_DBG(_fmt, ...) \
+ do { \
+ if (sim_log_enabled(BOOT_LOG_LEVEL_DEBUG)) { \
+ printf("[DBG] " _fmt "\n", ##__VA_ARGS__); \
+ } \
+ } while (0)
#else
#define BOOT_LOG_DBG(...) IGNORE(__VA_ARGS__)
#endif
diff --git a/sim/src/api.rs b/sim/src/api.rs
index ec502a2..21806ce 100644
--- a/sim/src/api.rs
+++ b/sim/src/api.rs
@@ -2,6 +2,7 @@
use flash::{Result, Flash};
use libc;
+use log::LogLevel;
use std::slice;
// This isn't meant to call directly, but by a wrapper.
@@ -35,3 +36,25 @@
},
}
}
+
+/// Called by C code to determine if we should log at this level. Levels are defined in
+/// bootutil/bootutil_log.h. This makes the logging from the C code controlled by bootsim::api, so
+/// for example, it can be enabled with something like:
+/// RUST_LOG=bootsim::api=info cargo run --release runall
+/// or
+/// RUST_LOG=bootsim=info cargo run --release runall
+#[no_mangle]
+pub extern fn sim_log_enabled(level: libc::c_int) -> libc::c_int {
+ let res = match level {
+ 1 => log_enabled!(LogLevel::Error),
+ 2 => log_enabled!(LogLevel::Warn),
+ 3 => log_enabled!(LogLevel::Info),
+ 4 => log_enabled!(LogLevel::Trace),
+ _ => false,
+ };
+ if res {
+ 1
+ } else {
+ 0
+ }
+}