Giter VIP home page Giter VIP logo

espmonitor's Introduction

ESPMonitor

ESP32 and ESP8266 serial monitor.

Features

  • Resets chip on startup.
  • Can match hex sequences in output to function names in a binary.
  • Optionally builds and flashes before starting the monitor.
  • cargo integration.

Usage

Install with:

cargo install cargo-espmonitor

Run cargo espmonitor --help for details.

If you prefer the standalone monitor app without cargo integration, you can instead install espmonitor.

Keyboard Commands

While monitoring, ESPMonitor accepts the following keyboard commands:

  • CTRL+R: Reset chip
  • CTRL+C: Quit

Contributing

Hooks

Before you start writing code, run this in the root of the repo:

mkdir -p .git/hooks && (cd .git/hooks && ln -s ../../hooks/* .)

This will set up a pre-commit hook that will run cargo clippy and cargo fmt before each commit, to save you some time getting frustrated with failed PR checks.

Releasing

See RELEASING for instructions.

espmonitor's People

Contributors

20051231 avatar alyoshavasilieva avatar dependabot[bot] avatar forsakenharmony avatar har7an avatar ivmarkov avatar kelnos avatar mabezdev avatar mchodzikiewicz avatar sergiogasquez avatar tcbennun avatar waywardmonkeys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

espmonitor's Issues

Cannot reset ESP32-C3 on Windows

On Windows, the program on my ESP32-C3 (connected via builtin USB) continues uninterrupted when Ctrl+R is pressed.

Furthermore I can't reset using the button on the board, because it causes the error reported in #50, closing espmonitor.

Keyboard events lock up in release build

Just tested out 0.5.0...

On my Linux system, Rust stable, with --release build, the keyboard events lock up for seconds at a time. It's not precisely repeatable. Sometimes, the event will go through maybe half a second after the keypress, then sometimes, it'll take several seconds.

On occasion, I'll hit CTRL+R five times in quick succession, then a few seconds later, they'll all be detected at once.

I haven't been able to reproduce this in debug build.

Error: The device does not recognize the command. (os error 22)

I've been happily using espmonitor with several ESP32s, but with a FeatherS3 from UM, it crashes when winding down.

I (2870) esp_idf_svc::wifi: Stopping
I (2880) wifi:state: run -> init (0)
I (2880) wifi:pm stop, total sleep time: 1454770 us / 2006276 us
W (2890) wifi:<ba-del>idx
I (2890) wifi:new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:1
I (2900) esp_idf_svc::wifi: Disconnect requested
I (2900) wifi:flush txq
I (2900) wifi:stop sw txq
I (2900) wifi:lmac stop hw txq
I (2910) esp_idf_svc::wifi: Stop requested
I (2910) esp_idf_svc::wifi: Got wifi event: StaDisconnected
Error: The device does not recognize the command. (os error 22)

$ espmonitor --version
ESPMonitor 0.7.0

idf.py monitor behaves as expected

I (2870) esp_idf_svc::wifi: Stopping
I (2880) wifi:state: run -> init (0)
I (2880) wifi:pm stop, total sleep time: 1363234 us / 2000715 us

W (2890) wifi:<ba-del>idx
I (2890) wifi:new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:1
I (2900) esp_idf_svc::wifi: Disconnect requested
I (2900) wifi:flush txq
I (2900) wifi:stop sw txq
I (2900) wifi:lmac stop hw txq
I (2910) esp_idf_svc::wifi: Stop requested
I (2910) esp_idf_svc::wifi: Got wifi event: StaDisconnected
I (2920) esp_idf_svc::wifi: STA event StaDisconnected handled, set status: Status(Started(Disconnected), Stopped)
I (2920) esp_idf_svc::wifi: About to wait for status
I (2940) esp_idf_svc::wifi: Got wifi event: StaStopped
I (2940) esp_idf_svc::wifi: STA event StaStopped handled, set status: Status(Stopped, Stopped)
I (2950) esp_idf_svc::wifi: Waiting for status done - success
I (2960) esp_idf_svc::wifi: Stopped
I (2960) esp_idf_svc::wifi: Event handlers deregistered
I (2970) wifi:Deinit lldesc rx mblock:10
I (2980) esp_idf_svc::wifi: Driver deinitialized
I (2980) esp_idf_svc::wifi: Deinitialization complete
I (2980) esp_idf_svc::wifi: Dropped
I (2990) esp_idf_svc::netif: Dropped
I (2990) esp_idf_svc::nvs: Dropped
I (2990) esp_idf_svc::eventloop: Dropped
we've been up for 2993154 ms.
going to sleep...
ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22))
Waiting for the device to reconnect....

OS: MINGW64 on Windows 11

Keypresses cause output to halt

I find that any keypress input while monitoring causes serial data to stop arriving into stdout. This includes CTRL+R, in which case I see Resetting device... done immediately before it stops.

My system:

  • Distro: Debian testing
  • Kernel: 5.10.46

My device: ESP32-PICO-D4, using USB serial chip CH340.

v0.4.0 works fine. The first bad commit is 0ab7587, where the loops within handle_stdin and handle_serial.

This appears to be because io::stdin().read() blocks if no data is available, meaning the outermost loop in handle_stdin never stops.

The following patch fixes it for me (whitespace omitted, I'll post a PR).

diff --git a/espmonitor/src/lib.rs b/espmonitor/src/lib.rs
index a880711..a9c5ea1 100644
--- a/espmonitor/src/lib.rs
+++ b/espmonitor/src/lib.rs
@@ -274,7 +274,6 @@ fn reset_chip(dev: &mut SerialStream) -> io::Result<()> {
 
 fn handle_stdin(reader: &mut SerialReader) -> io::Result<()> {
     let mut buf = [0; 32];
-    loop {
     match io::stdin().read(&mut buf)? {
         bytes if bytes > 0 => {
             for b in buf[0..bytes].iter() {
@@ -284,9 +283,9 @@ fn handle_stdin(reader: &mut SerialReader) -> io::Result<()> {
                     _ => (),
                 }
             }
+            Ok(())
         },
-            _ => return Ok(()),
-        }
+        _ => Ok(()),
     }
 }

I see no issue with this - now we loop over however much data is available, before returning to polling.

Inline backtraces very hard to read

Perhaps it is just me, but NOT printing the decoded program counter information on a new line results in stacktraces which are basically human-unparseable.

I mean, spotting the stack frame before the one where the panic happened is almost mission impossible. Case in point:

thread 'blocking-2' panicked at 'attempt to subtract with overflow', /home/ivan/ldev/ruwm/ruwm/src/screen/shapes/battery.rs:169:23
abort() was called at PC 0x40124122 [_ZN11panic_abort18__rust_start_panic5abort17hc831f809d7a5881dE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/panic_abort/src/lib.rs:44] on core 0
Backtrace:0x40083916 [panic_abort:/home/ivan/ldev/ruwm/.embuild/espressif/esp-idf-release/v4.4/components/esp_system/panic.c:402]:0x3ffd35900x40088a05 [esp_system_abort:/home/ivan/ldev/ruwm/.embuild/espressif/esp-idf-release/v4.4/components/esp_system/esp_system.c:128]:0x3ffd35b0 0x4008f7fe [abort:/home/ivan/ldev/ruwm/.embuild/espressif/esp-idf-release/v4.4/components/newlib/abort.c:46]:0x3ffd35d0 0x40124122 [_ZN11panic_abort18__rust_start_panic5abort17hc831f809d7a5881dE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/panic_abort/src/lib.rs:44]:0x3ffd3640 0x40124116 [__rust_start_panic:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/panic_abort/src/lib.rs:39]:0x3ffd3660 0x40108199 [rust_panic:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/std/src/panicking.rs:654]:0x3ffd3680 0x40108186 [_ZN3std9panicking20rust_panic_with_hook17h7e41cb7f9ac6853dE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/std/src/panicking.rs:624]:0x3ffd3700 0x40103f83 [_ZN3std9panicking19begin_panic_handler28_$u7b$$u7b$closure$u7d$$u7d$17h5006254263c1cbafE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/std/src/panicking.rs:??]:0x3ffd3770 0x40103d99 [_ZN3std10sys_common9backtrace26__rust_end_short_backtrace17h05cd6519869595bbE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:139]:0x3ffd37a0 0x40107ec0 [rust_begin_unwind:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/std/src/panicking.rs:498]:0x3ffd37d0 0x40132583 [_ZN4core9panicking9panic_fmt17h4cdbd6d50cb773cdE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/core/src/panicking.rs:107]:0x3ffd3800 0x40132527 [_ZN4core9panicking5panic17h8638f101d46064a1E:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/core/src/panicking.rs:48]:0x3ffd3830 0x400db98d [_ZN4ruwm6screen6shapes7battery7Battery10draw_shape17h9026f99cbb5a6f72E:/home/ivan/ldev/ruwm/ruwm/src/screen/shapes/battery.rs:??]:0x3ffd3870 0x400eb9b9 [_ZN4ruwm6screen5pages7summary7Summary4draw17h53b8d08f928f8b31E:/home/ivan/ldev/ruwm/ruwm/src/screen/pages/summary.rs:54]:0x3ffd3940 0x400d6736 [_ZN4ruwm6screen27DrawEngine$LT$U$C$N$C$D$GT$4draw17h8dd767d7e23cbd18E:/home/ivan/ldev/ruwm/ruwm/src/screen.rs:209]:0x3ffd3980 0x400d6823 [_ZN4ruwm6screen27DrawEngine$LT$U$C$N$C$D$GT$3run28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h8aedf44405b61bd8E:/home/ivan/ldev/ruwm/ruwm/src/screen.rs:190]:0x3ffd3a60 0x400d9575 [_ZN90_$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$9call_once17h9130dc4d6314c25cE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1694]:0x3ffd3b00 0x400d7527 [_ZN8blocking7unblock28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17hf4c0571251e45551E:/home/ivan/.cargo/registry/src/github.com-1ecc6299db9ec823/blocking-1.1.0/src/lib.rs:274]:0x3ffd3b20 0x400da2b5 [_ZN10async_task3raw24RawTask$LT$F$C$T$C$S$GT$3run17h97c2718a11a706e2E:/home/ivan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.1.0/src/raw.rs:489]:0x3ffd3ba0 0x401b01ad [_ZN10async_task8runnable8Runnable3run17h928568e2245def82E:/home/ivan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.1.0/src/runnable.rs:309]:0x3ffd3c50 0x400ebd3a [_ZN8blocking8Executor9main_loop28_$u7b$$u7b$closure$u7d$$u7d$17h3bd3eb18aa743d9aE:/home/ivan/.cargo/registry/src/github.com-1ecc6299db9ec823/blocking-1.1.0/src/lib.rs:186]:0x3ffd3c70 0x400ece40 [_ZN8blocking8Executor9grow_pool28_$u7b$$u7b$closure$u7d$$u7d$17h884cc7db93eede47E:/home/ivan/.cargo/registry/src/github.com-1ecc6299db9ec823/blocking-1.1.0/src/lib.rs:238]:0x3ffd3cd0 0x400ec93d [_ZN3std6thread7Builder15spawn_unchecked28_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17ha8cf46191646e17eE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/std/src/thread/mod.rs:484]:0x3ffd3cf0 0x40121c1f [_ZN90_$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$9call_once17h7c215fd0622c2b92E:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1694]:0x3ffd3d20 0x40121c46 [_ZN90_$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$9call_once17hebef1896a4b359bfE:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1694]:0x3ffd3d40 0x4011c4b4 [_ZN3std3sys4unix6thread6Thread3new12thread_start17h37b3771fd6f72b91E:/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/std/src/sys/unix/thread.rs:106]:0x3ffd3d60 0x4013a41c [pthread_task_func:/home/ivan/ldev/ruwm/.embuild/espressif/esp-idf-release/v4.4/components/pthread/pthread.c:195]:0x3ffd3d80

Exercise: which is the stack frame before /home/ivan/ldev/ruwm/ruwm/src/screen/shapes/battery.rs:169:23?

I think the solution would be to follow what the ESP-IDF monitor does:

  • Process output on a line-by-line basis
  • If the current process line contains X program counters (where X > 0), grab them all
  • After the current line, print exactly X lines, where each line contains a PC counter in HEX + its decoding.
    I.e. something like:
Decoded PC [0x4XXXYYYY]: _ZN90_$LT$alloc..boxed..Box$LT$F$C$A$GT$$u20$as$u20$core..ops..function..FnOnce$LT$Args$GT$$GT$9call_once17hebef1896a4b359bfE (/home/ivan/ldev/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1694)

When run in workspace, an error occurs.

When I run cargo espmonitor in workspace, I get an error and
If I cd to the flushed package directory and then run it, it works fine.

I want to run espmonitor by specifying the package from the workspace directory.

> cargo espmonitor com4
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { inner: ErrorInner { kind: Custom, line: None, col: 0, message: "missing field `package`", key: [] 
} }', C:\Users\<user name>\.cargo\registry\src\github.com-1ecc6299db9ec823\cargo-espmonitor-0.9.0\src\main.rs:141:39
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

> cd .\<sub package>\

<subpackage > cargo espmonitor com4
ESPMonitor 0.9.0

Commands:
    CTRL+R    Reset chip
    CTRL+C    Exit

Opening com4 with speed 115200
WARNING: Unable to open flash image \\?\C:\<workspace dir>\<subpackage>\target\xtensa-esp32-espidf\debug\<subpackage>: 指定されたパスが見つかりません。 (os error 3)
Resetting device... done
ets Jul 29 2019 12:21:46

~
~
~

It worked properly.

Wait for board to enter flashing mode

Some boards have hard buttons to manually switch to flashing mode. In that case, espmonitor often fails because it doesn't wait for human to press the button.

Please support this case.

espmonitor can't work under WSL

Under WSL1, the serial port COMX of the host can be accessed through /dev/ttySX. For example access COM11 via /dev/ttyS11. This mechanism works fine in esptool.py of esp-idf, but espmonitor can't work.

espmonitor /dev/ttyS10error log:

ESPMonitor 0.7.0

Commands:
    CTRL+R    Reset chip
    CTRL+C    Exit

Opening /dev/ttyS11 with speed 115200
Error: Inappropriate ioctl for device

strace espmonitor /dev/ttyS10 strace log:

frank@DESKTOP-MMN9PRD:~$ strace espmonitor /dev/ttyS10
execve("/home/frank/.cargo/bin/espmonitor", ["espmonitor", "/dev/ttyS10"], 0x7fffd016aae8 /* 23 vars */) = 0
brk(NULL)                               = 0x7fffeb143000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffff21d32b0) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=47534, ...}) = 0
mmap(NULL, 47534, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f125df73000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\363\377?\332\200\270\27\304d\245n\355Y\377\t\334"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f125df70000
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\363\377?\332\200\270\27\304d\245n\355Y\377\t\334"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f125dd40000
mprotect(0x7f125dd65000, 1847296, PROT_NONE) = 0
mmap(0x7f125dd65000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7f125dd65000
mmap(0x7f125dedd000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7f125dedd000
mmap(0x7f125df28000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f125df28000
mmap(0x7f125df2e000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f125df2e000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3405\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=104984, ...}) = 0
mmap(NULL, 107592, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f125dd20000
mmap(0x7f125dd23000, 73728, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f125dd23000
mmap(0x7f125dd35000, 16384, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f125dd35000
mmap(0x7f125dd39000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f125dd39000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 7\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=40040, ...}) = 0
mmap(NULL, 44000, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f125dd10000
mprotect(0x7f125dd13000, 24576, PROT_NONE) = 0
mmap(0x7f125dd13000, 16384, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f125dd13000
mmap(0x7f125dd17000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f125dd17000
mmap(0x7f125dd19000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x8000) = 0x7f125dd19000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\201\0\0\0\0\0\0"..., 832) = 832
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0O\305\3743\364B\2216\244\224\306@\261\23\327o"..., 68, 824) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=157224, ...}) = 0
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0O\305\3743\364B\2216\244\224\306@\261\23\327o"..., 68, 824) = 68
mmap(NULL, 140408, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f125dced000
mmap(0x7f125dcf4000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7f125dcf4000
mmap(0x7f125dd05000, 20480, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f125dd05000
mmap(0x7f125dd0a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x7f125dd0a000
mmap(0x7f125dd0c000, 13432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f125dd0c000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \22\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18816, ...}) = 0
mmap(NULL, 20752, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f125dce0000
mmap(0x7f125dce1000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f125dce1000
mmap(0x7f125dce3000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f125dce3000
mmap(0x7f125dce4000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f125dce4000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f125dcd0000
arch_prctl(ARCH_SET_FS, 0x7f125dcd1240) = 0
mprotect(0x7f125df28000, 12288, PROT_READ) = 0
mprotect(0x7f125dce4000, 4096, PROT_READ) = 0
mprotect(0x7f125dd0a000, 4096, PROT_READ) = 0
mprotect(0x7f125dd19000, 4096, PROT_READ) = 0
mprotect(0x7f125dd39000, 4096, PROT_READ) = 0
mprotect(0x7f125e172000, 167936, PROT_READ) = 0
mprotect(0x7f125df6d000, 4096, PROT_READ) = 0
munmap(0x7f125df73000, 47534)           = 0
set_tid_address(0x7f125dcd1510)         = 20106
set_robust_list(0x7f125dcd1520, 24)     = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7f125dcf4bf0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f125dd023c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7f125dcf4c90, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f125dd023c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=8192*1024}) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 0 (Timeout)
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f125dd86210}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f66d5826210}, 8) = 0
rt_sigaction(SIGSEGV, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f66d5826210}, 8) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x7f125e0d1440, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f125dd86210}, NULL, 8) = 0
rt_sigaction(SIGBUS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f66d5826210}, 8) = 0
rt_sigaction(SIGBUS, {sa_handler=0x7f125e0d1440, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x7f125dd86210}, NULL, 8) = 0
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f125dcc0000
mprotect(0x7f125dcc0000, 4096, PROT_NONE) = 0
sigaltstack({ss_sp=0x7f125dcc1000, ss_flags=0, ss_size=8192}, NULL) = 0
brk(NULL)                               = 0x7fffeb143000
brk(0x7fffeb164000)                     = 0x7fffeb164000
openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=8192*1024}) = 0
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(3, "7f125dcc0000-7f125dcc1000 ---p 0"..., 4096) = 4096
read(3, ":00 731285             /home/fra"..., 4096) = 769
close(3)                                = 0
sched_getaffinity(20106, 32, [0, 1, 2, 3, 4, 5, 6, 7]) = 32
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 -opost -isig -icanon -echo ...}) = 0
                                                                                 ioctl(0, TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
                                                                                                                                              clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f125dcd1510) = 20107
                                                     ESPMonitor 0.7.0
wait4(20107,
Commands:
    CTRL+R    Reset chip
    CTRL+C    Exit

Opening /dev/ttyS10 with speed 115200
Error: Inappropriate ioctl for device

                                     [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 20107
                                                                                              --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20107, si_uid=1000, si_status=1, si_utime=0, si_stime=0} ---
        ioctl(0, TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
                                                                     ioctl(0, TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
                                                                                                                                  ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x7f125dcc0000, 12288)           = 0
exit_group(1)                           = ?
+++ exited with 1 +++

espmonitor spins in a tight loop if USB device unplugged on Linux

When running espmonitor on /dev/tty{USB,ACM}* it will go into a tight loop consuming 100% CPU if you unplug the device.

This happens because after the device is unplugged, dev.read will return immediately with Ok(0) to reflect that EOF has been reached, so the code never blocks for the 200ms serial timeout. Polling for the keyboard input has a zero duration, so that also doesn't block, and it just goes around the loop like that forever.

Plugging the device back in also doesn't fix it since the device would have to be reopened, and in fact since espmonitor still has the character device open the kernel will just give the device a new device number so even reopening it usually won't work as the path to the device has probably changed.

It looks like on *nix the read will only return Ok(0) when the device has actually gone away, as if there's just no data it will just return Err(TimedOut) after 200ms. So.. just exiting when this happens should be okay, but I don't know if there's any other case (on Windows, or some other edge case I'm not thinking of) where Ok(0) might be returned during normal operation...

Support `defmt`

I will be transitioning from defmt-rtt to using the USB Jtag peripheral as my defmt printer since I cannot use direct-boot.

Would it be possible to add defmt decoding support to espmonitor? To be clear, I'm suggesting that there is a commandline flag or something that treats the serial output from the device as being in defmt encoding.

Demangling not working correctly

I believe the trace should be demangling symbols, as per

.and_then(|f| f.demangle().ok().map(|c| c.into_owned()))
.

Sadly it doesn't seem to be working correctly:

Backtrace:
 
0x400d8652
0x400d8652 - _ZN4core3num7flt2dec17digits_to_dec_str17hc32606d1079c94d2E
    at ??:??
0x400d886d
0x400d886d - _ZN4core3num7flt2dec15to_shortest_str17h654526032c2cd997E
    at ??:??
0x400d710c
0x400d710c - _ZN4core3fmt5float32float_to_decimal_common_shortest17h41be84e596d8a6caE.llvm.13434864130540073215
    at ??:??
0x400d717b
0x400d717b - _ZN4core3fmt5float52_$LT$impl$u20$core..fmt..Display$u20$for$u20$f64$GT$3fmt17h59c8e4b96a25ec7cE
    at ??:??
0x400d72be
0x400d72be - _ZN4core3fmt5write17h0ac2b54e9e860323E
    at ??:??
0x400d0bb5
0x400d0bb5 - main
    at ??:??
0x400d12c2
0x400d12c2 - Reset
    at ??:??
0x400d0f60
0x400d0f60 - ESP32Reset
    at ??:??

Improve addr2line support/behaviour

Support Rust demangling

When addr2line demangles Rust symbols, you end up with spaces in a bunch of places, so the current ADDR2LINE_RE doesn't match the output. Example output:

0x400de4eb: core::fmt::num::imp::<impl core::fmt::Display for i32>::fmt at /home/tcb/build/esp-rs/rust/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/src/rust/library/core/src/fmt/num.rs:280

It might be easiest to just match 0x[0-9a-f]+:.* and print the whole thing?

Print inline or out of line?

Currently the behaviour is to replace addresses with addr2line output inline. Maybe it's a personal thing but I prefer the idf_monitor approach of printing the output on the line(s) below the one containing the address(es), in a distinct colour/style. Something like the following, maybe... (using console for colour control):

image

(Yeah, it's ugly, but at least I'm not gonna mistake it for the real program output.)

Thoughts?

Archive the project?

@kelnos, thanks again for your hard work on this project! I believe that most (all?) of the functionality of this crate has been implemented in espflash itself, under the espflash monitor command. What are your thoughts on deprecating and archiving this project?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.