Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Carl Peto
    @carlos4242
    yeah, it seems to be borked... got developers complaining to me they are getting totally unstable results with any large structs :(
    i_am_the_carl
    @i_am_the_carl:matrix.org
    [m]

    Good morning.
    I followed the avr book this morning and came across an issue.
    I managed to solve it but it does need to be reported.

    Using the latest version of nightly I can't build the compiler_builtins crate that builds with the core crate.
    I get the following error:

       Compiling compiler_builtins v0.1.43
    LLVM ERROR: Not supported instr: <MCInst 296 <MCOperand Reg:1> <MCOperand Imm:15> <MCOperand Reg:40>>
    error: could not compile `compiler_builtins`

    By switching to an older version of nightly (To be specific, 1.47.0-nightly (0820e54a8 2020-07-23)) and adjusting for it's different name for the avr target, I got those two crates to compile.

    At first I opened an issue for the AVR book because I thought it should say to do this... but is this actually a bug in rustc that needs to be fixed?
    Should I open issues in both repos?

    rahix
    @rahix:matrix.org
    [m]
    This is a known bug in LLVM, there is a patch awaiting review already
    rahix
    @rahix:matrix.org
    [m]
    i_am_the_carl
    @i_am_the_carl:matrix.org
    [m]
    Fantastic, then I'll just stand by.
    Carl Peto
    @carlos4242
    wait...what? Another Carl!
    Well that's just Carl tastic! Welcome!
    i_am_the_carl
    @i_am_the_carl:matrix.org
    [m]
    Haha, thank you.
    Jesús Hernández
    @jhg

    Hi, I'm playing with AVR boot section and trying to jump to program section with:

    const PROGRAM_START: u16 = 0x0000;
    let application: unsafe extern "C" fn() -> ! = unsafe { core::mem::transmute(PROGRAM_START) };
    unsafe { application() };

    Compiler is optimizing that removing the call when the address is 0x0000, that as far as I know is just the start of the program section, then where I want to jump. Also I tried to do with inline asm but the compiler complain about that target does not support inline asm.

    Is there some way to do this? or is this a compiler error?

    jwagen
    @jwagen:matrix.org
    [m]
    Have you tried the llvm_asm macro. That was the old way of dooing inline assembly in rust.
    Jesús Hernández
    @jhg
    No, I didn't, I'll try. Thanks! Anyway, is normal the compiler delete the call? OR even if llvm_asm macro works it must be a issue in the compiler github?
    jwagen
    @jwagen:matrix.org
    [m]
    I dont't know. Yes it does sound a bit strange. My knowlage what is and is not allowed by the compiler to optimise is limited.
    Which rustc version are you using?
    Jesús Hernández
    @jhg
    toolchain: nightly-2021-01-07 (because an regresion)
    rustc 1.51.0-nightly (c2de47a9a 2021-01-06)
    @jwagen:matrix.org thanks! llvm_ams works well (at least until have asm macro or the compiler does not delete the call)
    Ayke
    @aykevl:matrix.org
    [m]
    I think there is a good chance the compiler assumes calling a nil pointer is undefined behavior, just like dereferencing a nil pointer is undefined behavior.
    Compilers usually respond to undefined behavior by deleting code.
    Using inline assembly seems like a good workaround to me. The compiler won't look at that.
    Aidan
    @quantumferret

    Hi, so I've been trying to use the milllis() function from Rahix's arduino uno millis() example, and I've run into the issues regarding u32 types acting like u16 types.

    I've tried setting overflow-checks = false and debug-assertions = false under the compiler_builtins package in Cargo.toml, to no avail, as well as setting "no-builtins": true in avr-atmega328p.json.

    Is using two u16s and manually handling overflow still the best workaround for this? Are there other tweaks to the target json file that would be worth trying? I've been digging into linker configuration and the like, but my knowledge of the topic is very limited.

    rahix
    @rahix:matrix.org
    [m]

    Is using two u16s and manually handling overflow still the best workaround for this?

    I think it is, unfortunately.

    Aidan
    @quantumferret
    Darn, well it's good to know for sure. Would using a struct to hold the u16 pair help with the ergonomics? I'll likely have to use millis() or micros() as a seed for a (pseudo)random number generator, since any button press or release should perturb the generator's state.
    Aidan
    @quantumferret
    Hrmm, would I actually need to care about millis() for that purpose, if using Rust? I'm going off of an assignment specification that's intended for use with Arduino's C++ and the Arduino IDE, so perhaps there is a cleaner approach available since I'm free from the Arduino language's clutches.
    rahix
    @rahix:matrix.org
    [m]
    Maybe just use a 16bit timer and have it count up as fast as possible. Whenever a button is pressed you read out the current value which is going to be quite unpredictable this way.
    riskable
    @riskable:matrix.org
    [m]
    Is nightly-2021-01-07 still required for all the avr stuff?
    rahix
    @rahix:matrix.org
    [m]
    yes...
    Aidan
    @quantumferret

    I tried again to make millis() use u32 and just didn't write anything to Serial, but instead displayed the count in seconds on a 7-segment display, and it's counting well past 65 seconds now, despite that meaning that MILLIS_COUNTER should be holding a value much larger than a u16 could store.

    Stupidly, I don't think I actually tried using u32 without writing to Serial before, and this time around I also added "linker-flavor": "gcc" and "no-builtins": true to `avr-atmega328p.json, which may or may not have helped. I'm cautiously rejoicing now.

    rahix
    @rahix:matrix.org
    [m]
    the problem might be in the code which converts the u32 to a string then
    i.e. some intrinsic which is called from that algorithm might not behave as it should
    Aidan
    @quantumferret
    so the u32 miscompilation likely comes from ufmt, and is itself a symptom of the linking issues involving compiler-builtins/LLVM?
    rahix
    @rahix:matrix.org
    [m]
    more likely compiler, not linker, but yes, so it seems
    Jesús Hernández
    @jhg

    I think there is a good chance the compiler assumes calling a nil pointer is undefined behavior, just like dereferencing a nil pointer is undefined behavior.
    Compilers usually respond to undefined behavior by deleting code.

    From C, 0 is used as value for pointer to nothing, and let that address without use even if that exists physically.
    In Rust there are variants like Option<T>, and in AVR a pointer to the first address is not a nil pointer neither pointer to nothing. It's defined and valid, at least for the boot loader.

    But the problem is in LLVM https://godbolt.org/z/r1K87Tfnz (I guess), avr-gcc does'n delete it. https://godbolt.org/z/5fa3Y18TE
    About the workaround I agree, it works. I was thinking put it in a crate using an enum similar to Option<T>.

    Aidan
    @quantumferret
    Has anyone recently successfully used a pseudorandom number generator crate with the Uno? I've tried a growing list of them and keep on getting the linking withavr-gccfailed: exit code: 1 error due to undefined reference to__lshrsi3'and similar undefined references. I only need to generate small numbers, but even minimal crates likeoorandomorrandom-fast-rng` seem to be causing issues due to (I think) bit shift operations on, u32 and/or u64.
    Ayke
    @aykevl:matrix.org
    [m]
    @jhg: sure, address 0 is defined by the architecture as something meaningful. But that's separate from the compiler, which also looks at it and sees a call of address 0, sees it as being undefined behavior, and deletes it.
    Remember that LLVM is originally used for C-like languages, and thus many unsafe behaviors in Rust probably have C-like semantics.
    Ayke
    @aykevl:matrix.org
    [m]
    If you are working with address 0, I think it's best to just stick to assembly as the compilers are going to think you are invoking undefined behavior. Address 0 is often treated specially by compilers (see e.g. the LLVM null_pointer_is_valid flag).
    With some more tests, it appears that even recent GCC versions on other architectures also don't delete the null pointer, while LLVM does. I wonder why. Maybe the GCC developers never really cared about this particular optimization.
    Jesús Hernández
    @jhg
    @aykevl:matrix.org I totally agree, I made the clarification only coz with folks I realize about many confusions often because the influence of C
    Yes, I'll stick in the end to assembly as solution but I want to remove it from the crate where I need and move it to one separate crate only for it, to expose it as an rust enum
    jaxter184
    @jaxter184:matrix.org
    [m]
    whats the current plan on how to split the crates? i havent checked in in a long time, and last i heard, the crates were gonna be split into atmega/attiny/avrxmega, and the issues seem to point that way, but that was a long time ago
    i read an article today that changed my mind on how i think they should be split; it was about when to use rust feature flags and when to not. i feel like while it might be easier to maintain and update the crates when theyre combined like this, i think its better for usability to split them into separate crates as much as possible
    rahix
    @rahix:matrix.org
    [m]
    I do not see the benefit... For users it's just the difference between [dependencies.arduino-uno] version = "..." and [dependencies.arduino-hal] version = "..." features = ["arduino-uno"]. What does the former bring that the latter can't? The other way around, however, I see a lot: A unified crate means switching from one board to another is a single change in Cargo.toml; it allows writing "addon" crates that work with any of the arduino-hal supported boards without needing even more feature hell; it eases maintenance a lot because we do not duplicate the HAL for each supported device, but keep a single version for all. And because of that, we also don't run into the risk that individual HALs start to diverge - with a single source of truth, we can be certain that the API looks the same for everyone; no features which are only supported by one but not the others.
    jaxter184
    @jaxter184:matrix.org
    [m]

    For users it's just the difference between [dependencies.arduino-uno] version = "..." and [dependencies.arduino-hal] version = "..." features = ["arduino-uno"]. What does the former bring that the latter can't?

    im thinking about it less in terms of what each option is capable of and more about what is more intuitive to the user. imo, calling a chip or board a "feature" isnt really intuitive, but theres not a huge difference either way.

    ignoring the avr-hal-generic crate, which i think will be there regardless of which strategy is chosen, it feels to me like the amount of shared code is faily insignificant compared to the amount of unique code specific to a given crate. looking at the attiny crate in the next branch, it looks like the only code not covered under the chip feature flags is a few imports (though i may be reading it wrong).

    it allows writing "addon" crates that work with any of the arduino-hal supported boards without needing even more feature hell

    shouldnt any addon crates use embedded-hal rather than arduino-hal? i feel like it would be bad practice for an addon crate to depend on any arduino-specific features, though i can certainly see it being more convenient

    it eases maintenance a lot because we do not duplicate the HAL for each supported device, but keep a single version for all.

    i guess this is the most important difference. if separating the crates is significantly more difficult to maintain than combining them, then its probably not even worth thinking about splitting them unless some catastrophic issue comes up

    And because of that, we also don't run into the risk that individual HALs start to diverge

    why is it so bad if they start to diverge? sure, its better for them to all be the same, but if implementing a feature for some particular chip is somehow more difficult or time consuming than for other chips, wouldnt it be nice to be able to diverge them for more efficient releases? especially if the problematic chip is not commonly used

    ultimately, i havent done that much work for this crate, especially compared to you, but i just felt like i should correct my previous opinion since it has changed since i last expressed it. im sure regardless of which strategy you decide to take, itll still be just as good of a crate either way.

    rahix
    @rahix:matrix.org
    [m]

    im thinking about it less in terms of what each option is capable of and more about what is more intuitive to the user. imo, calling a chip or board a "feature" isnt really intuitive, but theres not a huge difference either way.

    true, and ultimately this is an abuse of cargo's feature system, for lack of a better option. Ideally, we'd get something like rust-lang/cargo#2980 to solve it properly.

    looking at the attiny crate in the next branch

    attiny-hal is a bad choice because it is so bare-bones. atmega-hal is much bigger already and you can see how multiple MCUs share certain items. With separate crates we'd have to duplicate all that.

    shouldnt any addon crates use embedded-hal rather than arduino-hal?

    It really depends. embedded-hal is for anything truly platform-agnostic, e.g. a plain sensor driver. Targeting arduino-hal makes sense for libraries which are specific to Arduino boards, but still work across the entire family. Think, for example, of a crate supporting a certain Arduino shield.

    why is it so bad if they start to diverge?

    it's hell when things work differently across different MCUs. The entire point of a HAL is to abstract away the details of each MCU so you get a common interface ontop. Also, you'll have to re-learn the API each time and always be cautious if you missed some non-obvious difference. By forcing a common API, we'll ensure this can never happen and that if an API is supported across multiple MCUs it is guaranteed to work the same. If one MCU is harder to support, we can still cfg() out the relevant stuff until it's implemented.

    On a different note, I recently created https://github.com/Rahix/avr-hal-template as an easier starting ground for new projects. It is already based on the next branch of avr-hal.
    rahix
    @rahix:matrix.org
    [m]
    enaut
    @enaut:matrix.org
    [m]
    hey all, I'm just starting with arduino etc. I wanted to use ravedude to flash the arduino. however I'm stuck with: avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
    rahix
    @rahix:matrix.org
    [m]
    hi enaut
    what board are you using?
    enaut
    @enaut:matrix.org
    [m]
    using avrdude it works with: avrdude -C/etc/avrdude/avrdude.conf -v -patmega168 -carduino -P/dev/ttyUSB0 -b19200 -D -Uflash:w:/home/dietrich/Projekte/Source/rust-arduino-blink/target/avr-atmega168/release/rust-arduino-blink.elf:e
    so its arduino nano but with atmega168
    rahix
    @rahix:matrix.org
    [m]
    hm, and I suppose you tried ravedude nano ....?