Git Product home page Git Product logo

probe-run's People

Contributors

andresovela avatar berkowski avatar bobmcwhirter avatar bobo1239 avatar bors[bot] avatar briocheberlin avatar burrbull avatar davidlattimore avatar dirbaio avatar eboskma avatar elpiel avatar haata avatar hasheddan avatar hoverbear avatar huntc avatar jannic avatar japaric avatar javier-varez avatar jonas-schievink avatar jonathanpallant avatar justahero avatar koba789 avatar korken89 avatar mattico avatar suyashb95 avatar therealprof avatar urhengulas 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  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  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

probe-run's Issues

`release/debug=false` works but `dev/debug=false` doesn't

If release works then dev should also work.

STR: with defmt's log example (all the other examples produce similar errors)

$ # dev/debug=false
$ cargo run --bin log
(..)
stack backtrace:
   0: 0x00000bec - __bkpt
   1: 0x00000632 - log::__cortex_m_rt_main
   2: 0x000002d6 - main
   3: 0x0000261a - Reset
Error: debug information is missing. Likely fixes:
1. compile the Rust code with `debug = 1` or higher. This is configured in the `profile.*` section of Cargo.toml
2. use a recent version of the `cortex-m` crates (e.g. cortex-m 0.6.3 or newer). Check versions in Cargo.lock
3. if linking to C code, compile the C code with the `-g` flag

Caused by:
    Do not have unwind info for the given address.

$ # release/debug=false
$ cargo run --release --bin log
stack backtrace:
   0: 0x00000974 - __bkpt
   1: 0x0000080e - log::__cortex_m_rt_main
   2: 0x00000108 - main
   3: 0x000008c2 - Reset

$ # dev/debug=true
$ cargo run --bin log
stack backtrace:
   0: 0x00000ede - __bkpt
   1: 0x000009ea - log::__cortex_m_rt_main
   2: 0x0000065c - main
   3: 0x00002b2a - Reset

What would it take to allow debugging?

Hi,
thank you for the runner, it is something I've been waiting for a long time.

I ma just wondering what would need to be done to allow for debugging with standard IDEs, such as CLion, or VS code, in the past the runner was configured to arm-none-eabi-gdb.

I've seen that there are limitations in running RTT alongside with GDB in probe-rs, but I do not know enough to figure out the consequences for the runner.

Thanks!
I'll gladly contribute if the implementation will be something I can handle.

Check the selected processor and target for compatability.

After spending an inordinate amount of time trying to work out why RTT wasn't working, I discovered that I had set the wrong target.

As probe-run knows both the source target (through the path) and the target IC, it should be possible to show a warning if the two aren't compatible with each other.

JtagGetIdcodeError

Hi. Where should I start debugging this? On STM32F3, and switching from openocd:

    Finished release [optimized + debuginfo] target(s) in 23.16s
     Running `probe-run --chip STM32F303CCTx target\thumbv7em-none-eabihf\release\anyleaf_watermonitor`
Error: An error with the usage of the probe occured

Caused by:
    0: An error specific to a probe type occured
    1: Command failed with status JtagGetIdcodeError
error: process didn't exit successfully: `probe-run --chip STM32F303CCTx target\thumbv7em-none-eabihf\release\anyleaf_watermonitor` (exit code:
 1)

./cargo/config:

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-run --chip STM32F303CCTx" # to list chips, run `probe-run --list-chips.`
rustflags = [
  "-C", "link-arg=-Tlink.x",
]

[build]
target = "thumbv7em-none-eabihf"

edit: After removing the

rustflags = [
  "-C", "link-arg=-Tlink.x",
]

line, the error is Error: .vector_table section is missing.

Error: `_defmt_*` symbol not found

> probe-run --chip STM32H743BITx --defmt .\target\thumbv7em-none-eabihf\debug\mainboardfw-rs
Error: `_defmt_*` symbol not found

Probably related: knurling-rs/defmt#132

Using defmt HEAD.

I'm building probe-run HEAD with probe-rs HEAD to work around #15.

[patch.crates-io]
probe-rs = { git = "https://github.com/probe-rs/probe-rs", rev = "0f3a2856365304dd6c04fc8c28dc82f8ac06e8bb" }
probe-rs-rtt = { git = "https://github.com/probe-rs/probe-rs-rtt" }

My firmware is linked with GCC like so:

[build]
target = "thumbv7em-none-eabihf"
rustflags = [
  "-C", "inline-threshold=225",
  "-C", "linker=arm-none-eabi-gcc",
  "-C", "link-arg=-Wl,-Tlink.x",
  "-C", "link-arg=-Wl,-Tdefmt.x",
  "-C", "link-arg=-nostartfiles",
  "-C", "link-arg=-specs=nano.specs",
  "-C", "link-arg=-lc",
  "-C", "link-arg=-mcpu=cortex-m7",
  "-C", "link-arg=-mfpu=fpv5-d16",
  "-C", "link-arg=-mfloat-abi=hard",
  "-C", "link-arg=-mthumb",
]

The symbols do seem to be present:

> arm-none-eabi-readelf.exe --sections --symbols .\target\thumbv7em-none-eabihf\debug\mainboardfw-rs | grep -i defmt
  [13] .defmt            PROGBITS        20001f1c 020218 00001f 00      0   0  1
  7363: 08006941   302 FUNC    LOCAL  DEFAULT    2 _ZN50_$LT$defmt_rtt..Logg
  7370: 08000993    82 FUNC    LOCAL  DEFAULT    2 _ZN5defmt9Formatter3fmt17
  7371: 08006903    62 FUNC    LOCAL  DEFAULT    2 _ZN5defmt9Formatter4istr1
  7372: 08006857   172 FUNC    LOCAL  DEFAULT    2 _ZN5defmt9Formatter5leb64
  7384: 2000021d     1 OBJECT  LOCAL  DEFAULT    5 _ZN9defmt_rtt17INTERRUPTS
  7385: 2000021c     1 OBJECT  LOCAL  DEFAULT    5 _ZN9defmt_rtt5TAKEN17h13d
  7386: 20001b1c  1024 OBJECT  LOCAL  DEFAULT   12 _ZN9defmt_rtt6handle6BUFF
  8134: 20001f28     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_info_start
  8135: 20001f1c     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_error_start
  8153: 20001f31     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_trace_start
  8163: 20001f28     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_warn_end
  8168: 20001f1d     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_version_ = 82dd53f
  8221: 080010c3    36 FUNC    GLOBAL DEFAULT    2 _defmt_timestamp
  8247: 08006a71   102 FUNC    GLOBAL DEFAULT    2 _defmt_acquire
  8269: 20001f27     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_warn_start
  8293: 20001f33     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_trace_end
  8354: 08006ad7    32 FUNC    GLOBAL DEFAULT    2 _defmt_release
  8363: 20001f2b     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_debug_start
  8412: 20001f27     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_error_end
  8428: 20001f31     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_debug_end
  8515: 20001f2b     0 NOTYPE  GLOBAL DEFAULT   13 _defmt_info_end

Going to try searching for the source of the error message.

Stack backtrace is printed after shell prompt

...
0.000000 INFO  (7/10) running `filter_list32_std`...
└─ integration::tests::__defmt_test_entry @ tests/integration.rs:73
0.000000 INFO  (8/10) running `filter_list32_ext`...
└─ integration::tests::__defmt_test_entry @ tests/integration.rs:73
0.000000 INFO  (9/10) running `dequeue_lower_priority_frame`...
└─ integration::tests::__defmt_test_entry @ tests/integration.rs:73
0.000000 INFO  (10/10) running `ext_roundtrip`...
└─ integration::tests::__defmt_test_entry @ tests/integration.rs:73
^C⏎
~/dev/bxcan/testsuite *master> stack backtrace:
   0: core::ptr::read_volatile
        at /home/jonas/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:1042
   1: vcell::VolatileCell<T>::get
        at /home/jonas/.cargo/registry/src/github.com-1ecc6299db9ec823/vcell-0.1.2/src/lib.rs:32
   2: bxcan::pac::generic::Reg<U,REG>::read
        at /home/jonas/dev/bxcan/src/pac/generic.rs:52
   3: bxcan::Tx<I>::is_idle
        at /home/jonas/dev/bxcan/src/lib.rs:589
   4: bxcan::Can<I>::is_transmitter_idle
        at /home/jonas/dev/bxcan/src/lib.rs:385
   5: integration::tests::ext_roundtrip
        at tests/integration.rs:417
   6: main
        at tests/integration.rs:73
   7: Reset
        at /home/jonas/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.13/src/lib.rs:526

Note how the shell prompt shows up between the defmt output and the stacktrace. Not really sure what causes this behavior, but we might need to add a flush somewhere?

Diagnose probable lack of linker script

It's a common problem that users forget to pass -Tlink.x to the linker, since this currently needs to be done in every embedded application. The result is an ELF that is missing most sections. I think we do currently catch that, but we should try to include the likely cause and a suggestion in the error message.

--features defmt precludes running firmware without it

When probe-run has the defmt feature enabled, using it to run a firmware that uses rtt-target results in Error: defmt version symbol not found then probe-run exits.

To Reproduce
Steps to reproduce the behavior:

  1. Install probe-run with --features defmt
  2. Build an ELF that uses RTT, but not defmt
  3. probe-run elf_from_step_2 --chip SOMECHIP

Expected and observed behavior
I'd expect to see either the same behaviour as when probe-run is not built with --features defmt, perhaps with a warning to the effect of "defmt version symbol not found, falling back to raw RTT". Actually, an error message is displayed and probe-run exits.

config.toml

[build]
target = "thumbv6m-none-eabi"

[target.thumbv6m-none-eabi]
runner = "probe-run --chip ATSAMD21G18AU"
rustflags = [
  "-C", "link-arg=-Tlink.x",
]

Probe details

main git:((aba2ddc...)) ✗ probe-run --list-probes
The following devices were found:
[0]: STLink V2-1 (VID: 0483, PID: 374b, Serial: 0670FF505055877267123015, STLink)

Operating System:
Linux (Ubuntu 20.04)

ELF file (attachment)
codecraft_demo.zip

Additional context
I'm totally digging probe-run and defmt, thanks for making and sharing it!

Runner hangs at resetting device when using async-embedded.

Hi,
I know that async is extremely experimental, however when exprimenting with it, I stumbled upon the problem that when I was trying to run the code wit probe-run nothing was printed using RTT, but when I ran it using cargo embed, RTT work normally.
The code with respective outputs is here:

#![no_std]
#![no_main]

use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics

use cortex_m::asm::bkpt;
use cortex_m_rt::entry;
use rtt_target::{rprintln,rtt_init_print};
use async_embedded::task;

#[entry]
fn main() -> ! {
    rtt_init_print!();
    rprintln!("Hello, world!");

    task::spawn(async move {```
        loop {
            rprintln!("a");
            task::r#yield().await;
        }
    });

    task::block_on(async {
        loop {
            rprintln!("b");
            task::r#yield().await;
        }
    })
}

probe-run (when stopped):

flashing program ..
DONE
resetting device
stack backtrace:
   0: 0x08000410 - core::future::get_context
   1: 0x08000a8c - async_embedded::task::yield::{{closure}}
   2: 0x0800092c - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   3: 0x080015a2 - runner_test::__cortex_m_rt_main::{{closure}}
   4: 0x080008c8 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   5: 0x08000c60 - async_embedded::executor::Node<dyn core::future::future::Future+Output = ()>::new::{{closure}}
   6: 0x08000864 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   7: 0x08000f84 - async_embedded::executor::Executor::block_on
   8: 0x08000b48 - async_embedded::task::block_on
   9: 0x08001254 - runner_test::__cortex_m_rt_main
  10: 0x080010a8 - main
  11: 0x08003c76 - ResetTrampoline
  12: 0x08003c6c - Reset
Error: RTT control block not found in target memory. Make sure RTT is initialized on the target.

Process finished with exit code 1

Cargo embed: correctly showing alternating 'a' and 'b'.

What would it take to support Teensy 3 & 4?

What would it take to support the Teensy series of chips - especially the newer 3.x and 4.x families based on Cortex M families?

  • Teensy 4.0 and 4.1: "an ARM Cortex-M7 processor at 600 MHz, with a NXP iMXRT1062 chip, the fastest microcontroller available today"
  • Teensy 3.6: "a 32 bit 180 MHz ARM Cortex-M4 processor with floating point unit"
  • Teensy 3.5: "a 32 bit 120 MHz ARM Cortex-M4 processor with floating point unit"
  • (Teensy 3.1 and 3.2: "a 32 bit ARM processor")
  • (Teensy 2.0: AVR)

Some possibly-relevant work e.g.

  • teensy 4
  • teensy 3.5, 3.6 ?
  • teensy 3.1, 3.2 "This crate is meant to be consumed by a binary for a PJRC Teensy 3.1 or 3.2. Support for Teensy 3.0, 3.5, and 3.6 boards is planned, but not implemented."

The newer Teensy chips provide a fun amount of compute power not commonly seen in other boards, I'd love to see better Rust support for these boards ❤️

`<exception entry>` printed twice on UDF

STR

#[cortex_m_rt::entry]
fn main() -> ! {
    cortex_m::asm::udf();
}
$ cargo rb abort
stack backtrace:
   0: 0x000003e0 - HardFaultTrampoline
      <exception entry>
      <exception entry>
   1: 0x00000140 - __udf
   2: 0x00000118 - cortex_m::asm::udf
   3: 0x0000012c - abort::__cortex_m_rt_main
   4: 0x00000122 - main
   5: 0x000000fa - Reset

Detect when the `rt` feature was not enabled

I'm not sure if this can be detected, but if it can, we should totally try to do it, since everyone forgets to enable the "rt" feature from time to time and the symptoms are just "stuff's broken yo", which isn't very easy to debug.

Document CLI options

Current output:

$ probe-run --help
probe-run 0.1.3

USAGE:
    probe-run [FLAGS] <ELF> --chip <chip>

FLAGS:
        --defmt
    -h, --help          Prints help information
        --list-chips
    -V, --version       Prints version information

OPTIONS:
        --chip <chip>

ARGS:
    <ELF>

backtrace: report real path to core / std source code

if the rust-std component is installed.

currently we report the build machine paths:

   2: core::panicking::panic_fmt
        at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/panicking.rs:85
   3: core::panicking::panic
        at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/panicking.rs:50

but we could do what the standard library does and report the path to $(rustc --print sysroot)

  11: std::panicking::begin_panic
             at /home/japaric/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/panicking.rs:456

the goal is to make VS code's "open file location in editor" work

Allow GDB connection

I was wondering whether it will be possible to include gdb-server stub from probe-rs to probe-run. The idea is to allow GDB connection and use regular debugging while maintain display of defmt log messages.

When the probe-run is running it is not possible to access the st-link probe from the gdb-server nor OpenOCD. So to allow this to work a GDB session has to be somehow integrated into the probe-run.

blocking rtt hangs process

Any thoughts against servicing the rtt buffer the entire time? Im trying to print large buffers on exit, but theyre either truncated because the buffer is full (and youd hate to set the rtt buffer to 10k or something) or in rtt blocking deadlock because the buffer inst serviced until the breakpoint is reached.

Any architectural reasons or?

Semihosting support

Semihosting provides a canonical way to exit the program with a firmware-controlled exit status. This could replace our current scheme, where we terminate the program after any breakpoint was hit, and look at the stack backtrace to determine whether to use an exit status that indicates failure (being in the HardFault exception handler is treated as a failure).

Using semihosting seems more robust and flexible to me.

Decorate backtrace with location information (file+line)

The libstd implementation prints file and line number for each (non-inlined) call in the backtrace. We should do the same, as it makes finding the relevant locations easier.

If the format is right, VS Code should even make the locations clickable.

STM32F407VGTx Do not have unwind info for the given address

Do we think its a configuration error or unsupported arch somewhere?

$ cargo run --release --example cycle_count
    Finished release [optimized] target(s) in 0.01s
     Running `probe-run --chip STM32F407VGTx target/thumbv7em-none-eabi/release/examples/cycle_count`
flashing program ..
DONE
resetting device
ticks: 16800059
stack backtrace:
   0: 0x0800132e - <unknown>
Error: Do not have unwind info for the given address.

Build failure with defmt on current main head

Describe the bug
Since last night I can't compile it because of some issues with defmt code it calls.

This is on OSX, probe-run hash 4ee681e

To Reproduce

cargo install probe-run --git https://github.com/knurling-rs/probe-run.git --branch main -f --features defmt

Output:

 ... all fine until here ...
  Compiling probe-rs-t2rust v0.6.0
   Compiling defmt-elf2table v0.1.0 (https://github.com/knurling-rs/defmt?branch=main#91f33fc4)
   Compiling probe-rs v0.8.0
   Compiling probe-rs-rtt v0.3.0
   Compiling probe-run v0.1.3 (/Users/daschl/.cargo/git/checkouts/probe-run-31a04fec2ca67672/4ee681e)
error[E0425]: cannot find function `parse` in crate `defmt_elf2table`
   --> src/main.rs:140:38
    |
140 |         let table = defmt_elf2table::parse(&bytes)?;
    |                                      ^^^^^ not found in `defmt_elf2table`

error[E0425]: cannot find function `get_locations` in crate `defmt_elf2table`
   --> src/main.rs:150:41
    |
150 |             let locs = defmt_elf2table::get_locations(&bytes, table)?;
    |                                         ^^^^^^^^^^^^^ not found in `defmt_elf2table`

error[E0603]: enum `Level` is private
  --> src/logger.rs:32:24
   |
32 |         defmt_decoder::Level::Trace => Level::Trace,
   |                        ^^^^^ private enum
   |
note: the enum `Level` is defined here
  --> /Users/daschl/.cargo/git/checkouts/defmt-7f5b74b4e6ff55d4/91f33fc/decoder/src/lib.rs:21:30
   |
21 | use defmt_parser::{Fragment, Level, Type};
   |                              ^^^^^

error[E0603]: enum `Level` is private
  --> src/logger.rs:33:24
   |
33 |         defmt_decoder::Level::Debug => Level::Debug,
   |                        ^^^^^ private enum
   |
note: the enum `Level` is defined here
  --> /Users/daschl/.cargo/git/checkouts/defmt-7f5b74b4e6ff55d4/91f33fc/decoder/src/lib.rs:21:30
   |
21 | use defmt_parser::{Fragment, Level, Type};
   |                              ^^^^^

error[E0603]: enum `Level` is private
  --> src/logger.rs:34:24
   |
34 |         defmt_decoder::Level::Info => Level::Info,
   |                        ^^^^^ private enum
   |
note: the enum `Level` is defined here
  --> /Users/daschl/.cargo/git/checkouts/defmt-7f5b74b4e6ff55d4/91f33fc/decoder/src/lib.rs:21:30
   |
21 | use defmt_parser::{Fragment, Level, Type};
   |                              ^^^^^

error[E0603]: enum `Level` is private
  --> src/logger.rs:35:24
   |
35 |         defmt_decoder::Level::Warn => Level::Warn,
   |                        ^^^^^ private enum
   |
note: the enum `Level` is defined here
  --> /Users/daschl/.cargo/git/checkouts/defmt-7f5b74b4e6ff55d4/91f33fc/decoder/src/lib.rs:21:30
   |
21 | use defmt_parser::{Fragment, Level, Type};
   |                              ^^^^^

error[E0603]: enum `Level` is private
  --> src/logger.rs:36:24
   |
36 |         defmt_decoder::Level::Error => Level::Error,
   |                        ^^^^^ private enum
   |
note: the enum `Level` is defined here
  --> /Users/daschl/.cargo/git/checkouts/defmt-7f5b74b4e6ff55d4/91f33fc/decoder/src/lib.rs:21:30
   |
21 | use defmt_parser::{Fragment, Level, Type};
   |                              ^^^^^

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0425, E0603.
For more information about an error, try `rustc --explain E0425`.
error: failed to compile `probe-run v0.1.3 (https://github.com/knurling-rs/probe-run.git?branch=main#4ee681e6)`, intermediate artifacts can be found at `/var/folders/2t/p_gqr4sn1qb75zjtt673kx000000gr/T/cargo-installLdrOuP`

Caused by:
  could not compile `probe-run`.

To learn more, run the command again with --verbose.

virtual unwind support for hard-float targets

general comment: the Thumb targets are backwards compatible. Both thumbv7em-none-eabi and thumbv7em-none-eabihf work fine on Cortex-M4F devices. If you are not doing floating point operations (f32 math) then you can use the thumbv7em-none-eabi target, which is supported by probe-run, without any performance degradation.


The virtual unwinder doesn't expect floating pointer (FP) registers to be pushed on exception entry.

The Cortex-M is smart about this: it only pushes FP registers if the preempted context was using them.
The unwinder will need to compute at runtime whether the FP registers were pushed or not (there should be some flag/register pushed onto the stack that contains this info) and update the per-frame SP value accordingly while walking up the stack.

backtrace can infinte-loop.

I'm seeing this behavior with -C force-frame-pointers=no.

I think it's to be expected that backtracing doesn't work correctly with it, but I think at least this should be detected and fail with error: the stack appears to be corrupted beyond this point instead of looping forever.

If there's interest I can try cooking a binary that reproduces this.

stack backtrace:
   0: HardFaultTrampoline
      <exception entry>
   1: tester_gwc::sys::__cortex_m_rt_WDT
        at ak/src/bin/../sys.rs:556
   2: WDT
        at ak/src/bin/../sys.rs:553
      <exception entry>
   3: <futures_util::future::select::Select<A,B> as core::future::future::Future>::poll
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.8/src/future/select.rs:95
   4: tester_gwc::common::abort_on_keypress::{{closure}}
        at ak/src/bin/../tester_common.rs:26
   5: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
        at /home/dirbaio/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80
   6: tester_gwc::test_network::{{closure}}
        at ak/src/bin/tester_gwc.rs:61
   7: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
        at /home/dirbaio/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80
   8: tester_gwc::main::{{closure}}
        at ak/src/bin/tester_gwc.rs:43
   9: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
  10: tester_gwc::sys::main_task::task::{{closure}}
        at ak/src/bin/../sys.rs:196
  11: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
        at /home/dirbaio/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:80
  12: embassy::executor::Task<F>::poll
        at /home/dirbaio/akiles/embassy/embassy/src/executor/mod.rs:132
  13: core::cell::Cell<T>::get
        at /home/dirbaio/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/cell.rs:432
  14: embassy::executor::timer_queue::TimerQueue::update
        at /home/dirbaio/akiles/embassy/embassy/src/executor/timer_queue.rs:34
  15: embassy::executor::Executor::run::{{closure}}
        at /home/dirbaio/akiles/embassy/embassy/src/executor/mod.rs:241
  16: embassy::executor::run_queue::RunQueue::dequeue_all
        at /home/dirbaio/akiles/embassy/embassy/src/executor/run_queue.rs:65
  17: embassy::executor::Executor::run
        at /home/dirbaio/akiles/embassy/embassy/src/executor/mod.rs:223
  18: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  19: real_main
        at ak/src/bin/../sys.rs:478
  20: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  21: real_main
        at ak/src/bin/../sys.rs:478
  22: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  23: real_main
        at ak/src/bin/../sys.rs:478
  24: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  25: real_main
        at ak/src/bin/../sys.rs:478
  26: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  27: real_main
        at ak/src/bin/../sys.rs:478
  28: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  29: real_main
        at ak/src/bin/../sys.rs:478
  30: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  31: real_main
        at ak/src/bin/../sys.rs:478
  32: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  33: real_main
        at ak/src/bin/../sys.rs:478
  34: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  35: real_main
        at ak/src/bin/../sys.rs:478
  36: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  37: real_main
        at ak/src/bin/../sys.rs:478
  38: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  39: real_main
        at ak/src/bin/../sys.rs:478
  40: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  41: real_main
        at ak/src/bin/../sys.rs:478
  42: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  43: real_main
        at ak/src/bin/../sys.rs:478
  44: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  45: real_main
        at ak/src/bin/../sys.rs:478
  46: cortex_m::asm::wfe
        at /home/dirbaio/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.6.4/src/asm.rs:117
  47: real_main
        at ak/src/bin/../sys.rs:478
... this goes on forever

backtrace: Shorten paths to crates/libcore

It would be nice to shorten long paths to rust libraries or published dependency crate versions, so your backtrace lines are better human-readable:

For core/alloc/std libraries, a format stating the version of the compiler used in a format similar to rust-toolchain file specifications would be good

[stable-1.46.0]/lib/rustlib/src/foo.rs

For published library dependencies, it would be good to use a similar format, with `$crate_name-$crate_version:

[heapless-0.5.2]/src/vec.rs

I think it would be reasonable to make this an option (perhaps the default?), as it may interfere with vscode's ability to jump to source. However, this would drastically reduce line lengths when that functionality is not needed.

ST-Link v2.1 crashing?

Describe the bug
I'm using a ST-Link v2.1 with an ATSAMD21, this combination has been working fine for a few weeks with probe-run and defmt. The first time I do probe-run --verbose --chip ATSAMD21G18AU path/to/firmware, it flashes and successfully opens up the defmt-rtt console successfully. After about 20 seconds, probe-run exits with:

<normal defmt RTT output>
RTT error: Error communicating with probe: An error with the usage of the probe occured
Error: An error with the usage of the probe occured

Caused by:
    0: An error specific to a probe type occured
    1: Command failed with status JtagNoDeviceConnected

Once this failure has happened, subsequent probe-run invocations give:

  (HOST) DEBUG RAM region: 0x20000000-0x20007FFF
└─ probe_run @ src/main.rs:144
  (HOST) WARN  insufficient DWARF info; compile your program with `debug = 2` to enable location info
└─ probe_run @ src/main.rs:169
  (HOST) DEBUG section `.data` is in RAM at 0x20000000-0x20000147
└─ probe_run @ src/main.rs:204
  (HOST) DEBUG section `.bss` is in RAM at 0x20000150-0x20004C07
└─ probe_run @ src/main.rs:204
  (HOST) DEBUG section `.uninit` is in RAM at 0x20004C08-0x20005007
└─ probe_run @ src/main.rs:204
  (HOST) DEBUG vector table: VectorTable { location: 0, initial_sp: 20008000, reset: b1, hard_fault: 55a9 }
└─ probe_run @ src/main.rs:268
  (HOST) DEBUG found 1 probes
└─ probe_run @ src/main.rs:298
  (HOST) DEBUG opened probe
└─ probe_run @ src/main.rs:303
Error: An error with the usage of the probe occured

Caused by:
    0: An error specific to a probe type occured
    1: Command failed with status JtagNoDeviceConnected

To get a successful flash, disconnecting and reconnecting the USB to the ST-Link seems necessary.

Expected and observed behavior
I'd expect the session to not fail, but if it did I would expect to get some more detailed logging out with the --verbose flag specified, to be able to dig deeper in to the issue.

config.toml

[build]
target = "thumbv6m-none-eabi"

[target.thumbv6m-none-eabi]
runner = "probe-run --verbose --chip ATSAMD21G18AU"
rustflags = [
  "-C", "link-arg=-Tlink.x",
  "-C", "link-arg=-Tdefmt.x"
]

Probe details
ST-Link v2.1, just updated to firmware v2j37m26 which appears to be the latest, upgrade didn't change symptoms.

probe-rs-cli list
The following devices were found:
[0]: STLink V2-1 (VID: 0483, PID: 3752, Serial: 0670FF505055877267123015, STLink)

Operating System:
Ubuntu 20.04.1 LTS

include module path info in the output

depends on knurling-rs/defmt#151
Example input:

// src/bin/hello.rs
fn main() -> ! {
    defmt::info!("program start");
    // ..
}
// src/hal.rs
fn init() {
    defmt::debug!("initializing the HAL");
    // ..
}

Example output:

0.000000 INFO  [my_app::hello::main] program start
└─ src/bin/hello.rs:8
0.000001 DEBUG [my_app::hal::init] initializing the HAL
└─ src/hal.rs:8

Approximated stack overflow detection via stack canaries

While it is possible to link an embedded app in a way that will detect stack overflows immediately and (mostly) reliably, few people actually do this as it requires using a linker wrapper to link the app twice. cortex-m-rt also doesn't do it by default at the moment.

However, we can still do our best to help out when no built-in stack overflow protection is used: After uploading the program, but before starting it, we can fill the space in RAM right after the data used by ELF sections with a unique pattern. Then, after the program exits (or even while it still runs), we scan the filled area and look for bytes that were changed from our pattern. If we find any changed bytes, there is a high probability that the program has used too much stack and overwrote its own data sections.

There are a few things to keep in mind here:

  • When "real" stack overflow protection is used, the ELF sections will be at the end of RAM, and our canary won't fit anywhere (but is also unnecessary).
  • This is all relying on luck and is a post-mortem technique: The program state is already undefined when we detect the stack overflow.
  • We need to fill "enough" RAM with the canary to get a high chance of detecting the overflow, but only as much RAM as is needed (otherwise, even regular stack usage will trip the canary).
  • It is currently unclear how this interacts with program that use the heap. It probably has to be disabled then, as the heap usually starts right after the fixed ELF sections.
  • While this feature has both false positives and negatives, I believe it can be enabled by default if the message is worded right. Something like "program has used at least N bytes of stack space, collision with data segments is likely". This can be worded differently based on where in the canary the modification was detected.

Report defmt decoder errors

Decoding failure is currently ignored by probe-run, which is problematic. It makes it look like the program stops outputting anything.

Text not printed with rprint without newline

I have a strange bug where rprint!(".") doesn't print anything until I print a newline \n later. For instance rprint!(".\n"); works, rprint!("."); rprint!("\n"); works too, and of course rprintln!("."); works. Characters are not missed, it's just as if some buffer is flushed only when newline is met.

This doesn't happen with cargo-embed so I created the issue here

Unable to flash STM32H7 MCU

Running `probe-run --chip STM32H743BITx --defmt target\thumbv7em-none-eabihf\release\mainboardfw-rs`
flashing program ..
Error: Error while flashing

Caused by:
    No flash memory contains the entire requested memory range 0x8000000..0x8005904.

This is caused by probe-rs having an incorrect memory map for the flash, which was fixed in probe-rs/probe-rs#314.

WFI/WFE after print results in the same message printed multiple times

I'm implementing an embedded async runtime on an stm32f103. Inside a future I am calling defmt::info!, before waiting on a timer (via an interrupt). Therefore, the future returns Poll::Pending and I call asm::wfi() to sleep the CPU.
Then, the message printed before the wait gets sent a ton of times, all with the same timestamp. Is this expected? How does your printing mechanism interact with sleep modes?

I've tried setting the DBGMCU_CR.DEBUG_SLEEP flag but it doesn't do anything.

This is on Windows 10 with an STLink v2. I don't have a small reproducer at the moment because the code is tied into all sorts of unrelated stuff. Maybe there's an underlying reason this doesn't work and you don't need an example, let me know.

Output size info when flashing

The flashing step currently just outputs "flashing program", it would be nice if it contained a bit more info pertaining to the program it is flashing.

In particular, total flash usage is a small but important piece of info – it lets you estimate how long the flashing step might take, and is a useful metric to keep in mind while developing in general.

Add --connect-under-reset option

Describe the bug
probe-run is not able to connect to device if wfi is used.
It was tested with stlink v2 and stm32f411.

To Reproduce
Lets say I have following program where TIM5 fires with 1 Hz.

    #[idle]
    fn idle(_: idle::Context) -> ! {
        loop {
            // cannot connect if wfi is used
            cortex_m::asm::wfi();
            // this works
            //cortex_m::asm::nop();
        }
    }
    
    #[task(binds = TIM5, resources = [led, timer])]
    fn timer5_tick(ctx: timer5_tick::Context) {
        defmt::info!("tick");
        ctx.resources.timer.clear_interrupt(Event::TimeOut);
        ctx.resources.led.toggle().unwrap();
    }

It is only possible to reflash device using --connect-under-reset option which uses external reset pin.

cargo flash --chip STM32F411CEUx --release --bin app  --connect-under-reset

config.toml defines:

runner = "probe-run --chip STM32F411CEUx --defmt"

The problem is that probe-run does not have similar option like --connect-under-reset and therefore it fails to connect to target:

>cargo rrb app                                                                                                                                                                                                                                                                                           
    Finished release [optimized + debuginfo] target(s) in 0.04s
     Running `probe-run --chip STM32F411CEUx --defmt target/thumbv7em-none-eabihf/release/app`
Error: An error with the usage of the probe occured

Caused by:
    0: An error specific to a probe type occured
    1: Command failed with status JtagNoDeviceConnected

add flag / env-var to select the probe by serial number

This is helpful when you want to cargo-run firmware on two or more different devices in parallel.

$ # terminal 1
$ cd path/to/firmware
$ PROBE_RUN_SN=abcdef012345 cargo run --bin radio-tx

$ # terminal 2
$ cd path/to/firmware
$ PROBE_RUN_SN=012345abcdef cargo run --bin radio-rx

In the above case the firmware can live in the same Cargo project.

When the firmware lives in different Cargo projects you can use the flag version.

$ # terminal 1
$ cd path/to/firmware-a
$ head .cargo/config
[target.thumbv7em-none-eabihf]
runner = "probe-run --serial-number abcdef012345 --chip nrf52"

$ cargo run --bin radio-tx

$ # terminal 2
$ cd path/to/firmware-b
$ head .cargo/config
[target.thumbv7em-none-eabihf]
runner = "probe-run --serial-number 012345abcdef --chip nrf52"

$ cargo run --bin radio-rx

Freeze with RTIC pend

I have tried basic example from RTIC, just updated to use defmt and hardware that I have available and it freezes on the pend call for some reason. Any idea what might be wrong?

#[app(device = stm32l0x1_minihal::pac)]
const APP: () = {
    #[init]
    fn init(_: init::Context) {
        rtic::pend(Interrupt::USART1);

        defmt::debug!("Init!");
    }

    #[idle]
    fn idle(_: idle::Context) -> ! {
        defmt::debug!("Idle!");

        rtic::pend(Interrupt::USART1);

        l0::exit();

        loop {
            cortex_m::asm::nop();
        }
    }

    #[task(binds = USART1)]
    fn uart0(_: uart0::Context) {
        static mut TIMES: u32 = 0;

        *TIMES += 1;
        defmt::debug!("Called: {:u32}", TIMES);
    }
};

The output from cargo-run is:

Finished dev [optimized + debuginfo] target(s) in 0.03s
     Running `probe-run --chip STM32L031K6Tx --defmt target/thumbv6m-none-eabi/debug/l0`
  (HOST) INFO  flashing program
  (HOST) INFO  success!
────────────────────────────────────────────────────────────────────────────────
0.000000 DEBUG Init!
└─ l0::init @ src/bin/main.rs:67

Could not compile probe-run v0.1.6 on macOS 10.15.7

So far I have installed probe-run without problems on macOS (x86_64) with:

cargo install --git https://github.com/knurling-rs/probe-run --branch main --features defmt

Now I tried to install release version with:

cargo install probe-run

And got following error:

  = note: Undefined symbols for architecture x86_64:
            "_NSAppKitVersionNumber", referenced from:
                _hid_init in libhidapi-6c82a0d52f552184.rlib(hid.o)
                _hid_enumerate in libhidapi-6c82a0d52f552184.rlib(hid.o)
                _hid_open_path in libhidapi-6c82a0d52f552184.rlib(hid.o)
          ld: symbol(s) not found for architecture x86_64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)


error: aborting due to previous error

error: failed to compile `probe-run v0.1.6 (https://github.com/knurling-rs/probe-run?branch=main#013c0bd3)`, intermediate artifacts can be found at `/var/folders/5b/jlxfj70x1fb_n2l6qh21xxfh0000gn/T/cargo-installcEziMp`

Caused by:
  could not compile `probe-run`.

To learn more, run the command again with --verbose.

Full log

Rust version:

rustc 1.46.0 (04488afe3 2020-08-24)

display filter via env variable

use case: defmt supports emission filters on the target side (via Cargo features like defmt-info) but these have crate granularity via the DEFMT_LOG environment variable, which supports crate level granulartiy. To filter that further at module level granularity we can use an env variable like env_logger's RUST_LOG.

user interface: We can reuse RUST_LOG's syntax: krate::module=level,krate2::module2=level2 for familiarity.

implementation: log messages include the module in their call site info. probe-run can read the env var, parse it, filter out incoming log messages and print to the console only those that pass the filter.

unresolved questions:

  • env var name? DEFMT_DISPLAY_FILTER? PROBE_RUN_FILTER?
$ DEFMT_DISPLAY_FILTER=krate::module=info cargo run --bin my-app
0.000000 INFO  message1
└─ krate::module::function1 @ src/module/foo.rs:8
0.000001 INFO  message2
└─ krate::module::function2 @ src/module/bar.rs:9
(..)

stack trace infinite loop

I'm just getting started using probe-run, testing a threading crate I'm building.

So (on Cortex-M), the thread stacks are populated with a frame like an exception would do, [r0-r4, r12, LR, PC, APSR].

LR is set to the location of a cleanup(), which does some house-keeping, then triggers the scheduler to switch away, then does a loop {}, which is practically unreachable.

Now when I run something with probe-run, the resulting stack trace endlessly repeats in cleanup():

[...]
    Finished dev [optimized + debuginfo] target(s) in 0.01s              
     Running `probe-run --chip nRF52840_xxAA /home/kaspar/src/own/rust/riot_core/target/thumbv7em-none-eabi/debug/examples/bench_lock`             
flashing program ..                                                      
^[[CDONE                                                                 
resetting device                                                         
stack backtrace:                                                         
   0: 0x00001752 - <unknown>                                             
   1: 0x000016b6 - cortex_m_semihosting::hio::hstdout
   2: 0x00001650 - cortex_m_semihosting::export::hstdout_fmt::{{closure}}                                                                          
   3: 0x00001558 - cortex_m::interrupt::free                             
   4: 0x00001638 - cortex_m_semihosting::export::hstdout_fmt
   5: 0x000007b6 - user_main                                             
   6: 0x0000112a - riot_core::main_trampoline                            
   7: 0x00000d20 - riot_core::thread::cleanup                                                                                                      
   8: 0x00000d20 - riot_core::thread::cleanup                            
   9: 0x00000d20 - riot_core::thread::cleanup       
  10: 0x00000d20 - riot_core::thread::cleanup                            
  11: 0x00000d20 - riot_core::thread::cleanup            
  12: 0x00000d20 - riot_core::thread::cleanup
  13: 0x00000d20 - riot_core::thread::cleanup
[...]

The lines <N>: 0x00000d20 - riot_core::thread::cleanup repeat extremely fast, and the process cannot be cancelled with CTRL-C.

While I might have messed up something on the stack to make it invalid and look like this to probe-run, I'd expect it to stop after maybe the second iteration, letting the user know that this would repeat.

(I'm assuming that probe-run's rtt support uses a different BKPT scheme than traditional semihosting, and that's why this exits on the first hprintln!(), but that is a unrelated to this issue.)

This is on probe-run 0.1.3 installed today via "cargo install probe-run".

Using probe-run with bootloader

Hi Guys!

I am attempting to use probe-run to run my application on top of a custom bootloader.. It flashes successfully, and the application boots as expected. I don't expect to have defmt logging from both the bootloader and the application at the same time, as they are two different ELF files.

Looking at my application, i can verify that it looks to be built correctly:

➜  release git:(master) ✗ arm-none-eabi-nm -CSn output | head -n 30                                                                                                                                                                                                                                        [20/08/26|8:45:41]
00000000 00000001 N {:u32}
00000001 N _defmt_error_start
00000001 A "_defmt_version_ = 5a1047ba740398184fbe26b58fe504c0b918c6bb"
00000001 00000001 N panicked at {:str}:{:u32}:{:u32}
00000002 00000001 N Network init
00000003 00000001 N Failed to obtain time!
00000004 00000001 N Failed to obtain time!
00000005 00000001 N Abort error
00000006 00000001 N Failed to obtain ntp time!
00000007 00000001 N Buffer too small!!!
00000008 N _defmt_error_end
00000008 N _defmt_warn_start
00000008 00000001 N OTA Job removed!
00000009 00000001 N @#25 bytes(5709..5726)
00000009 N _defmt_info_start
00000009 N _defmt_warn_end
0000000a 00000001 N Copyright Mathias Koch 2020
0000000b 00000001 N Network initialized!
0000000c 00000001 N Time delta: {:?} ms
0000000d 00000001 N Re-attaching!
0000000e 00000001 N Re-registering & attaching!
0000000f N _defmt_debug_end
0000000f N _defmt_debug_start
0000000f N _defmt_info_end
0000000f N _defmt_trace_end
0000000f N _defmt_trace_start
08004404 00000004 R __RESET_VECTOR
08004408 00000038 R __EXCEPTIONS
08004408 R __reset_vector
08004440 R __eexceptions
...

And running RUST_LOG=info probe-run --chip STM32L475VGTx --defmt output flashes the device and ends up with:

[2020-08-26T06:42:31Z INFO  probe_run] flashed program
[2020-08-26T06:42:31Z INFO  probe_run] attached to core
DONE
resetting device
[2020-08-26T06:42:31Z INFO  probe_run] Could not attach because the target's RTT control block isn't initialized (yet). retrying
[2020-08-26T06:42:31Z INFO  probe_run] Successfully attached RTT

Then nothing more happens. I can verify that the application is running as expected, so only the logging is missing.. (built with default = ["defmt-default"])

Searching some more, it seems to be caused by this piece:

for try_index in 0..=NUM_RETRIES {
    rtt_res = Rtt::attach_region(sess.clone(), &ScanRegion::Exact(rtt_addr_res));
    match rtt_res {
        Ok(_) => {
            log::info!("Successfully attached RTT");
            break;
        }
        Err(probe_rs_rtt::Error::ControlBlockNotFound) => {
            if try_index < NUM_RETRIES {
                log::info!("Could not attach because the target's RTT control block isn't initialized (yet). retrying");
            } else {
                log::info!("Max number of RTT attach retries exceeded.");
                return Err(anyhow!(probe_rs_rtt::Error::ControlBlockNotFound));
            }
        }
        Err(e) => {
            return Err(anyhow!(e));
        }
    }
}

not delaying enough for the bootloader to jump to application before giving up on the RTT attachment.

A simple 1 second sleep between retries seems to fix my issue.

Error with STM32F723IEKx

Here's what i get when i try using the provided "app-template" with the stm32f723 disco board via the onboard ST-LINK/V2-1

probe-run --chip STM32F723IEKx --defmt target/thumbv7em-none-eabihf/debug/hello`
flashing program ..
DONE
resetting device
Error: Error communicating with probe: A core architecture specific error occured

Caused by:
    0: A core architecture specific error occured
    1: Failed to read register DRW at address 0x0000000c because: An error specific to a probe type occured
    2: An error specific to a probe type occured
    3: Command failed with status SwdDpFault

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.