ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to and logged at, code of conduct at
xnor has joined #rust-embedded
SArpnt[m] has joined #rust-embedded
<SArpnt[m]> is the rust target.json something specific to cargo? i'd like to use a target.json file with a linker invoked on the command line like lld
AtleoS has joined #rust-embedded
_whitelogger has quit [Ping timeout: 260 seconds]
_whitelogger has joined #rust-embedded
seds has joined #rust-embedded
timokrgr[m] has quit [Quit: Idle timeout reached: 172800s]
Lumpio_ is now known as Lumpio-
b34r_dev has joined #rust-embedded
b34r_dev has quit [Quit: Client closed]
<JamesMunns[m]1> <SArpnt[m]> "is the rust target.json somethin..." <- target jsons are specific to `rustc`, not necessarily cargo, but cargo knows how to pass it to rustc. It's not something a linker understands directly, it's used by rustc to pass to the linker where relevant
mali[m] has quit [Quit: Idle timeout reached: 172800s]
<BenPh[m]> <firefrommoonligh> "So, I could make a custom..." <- in general, my approach when I see a primitive type, is to wrap it. Even for a simple toy project, I'll wrap a `u32` and use `Seconds(u32)` (probably pub it as well). It does a few things:... (full message at <>)
<BenPh[m]> ZST, const only, word-size configurable, scale encapsulating. It's a work of art IMHO.
<Lumpio-> Not all that different from std::chrono::duration from C++11 :)
<Lumpio-> Maybe they took some inspiration
<BenPh[m]> <dirbaio[m]> "the goal of embedded-hal is..." <- I would like to add this as a quote near the top of the RFC document. Would it be appropriate to attribute it to you, or would you prefer something else?
<BenPh[m]> <Lumpio-> "Not all that different from std:..." <- yeah, in fact.....
<BenPh[m]> shoutout to korken89
<BenPh[m]> > This library is a heavily inspired of std::chrono's Duration from C++ which does all it can at compile time.
<korken89[m]> The whole idea of fugit is that I missed std::chrono:)
xypron has left #rust-embedded [ - Chat comfortably. Anywhere.]
<BenPh[m]> Only came across fugit "in anger" so to speak recently. Was looking for an embeded-friendly way to write a portable driver that needs time-readings. by way of seeing how esp-rs is doingtheir time, started looking into it in detail. Quickly becaume a fan.
<BenPh[m]> * Only came across fugit "in anger" so to speak recently. Was looking for an embeded-friendly way to write a portable driver that needs time-readings. by way of seeing how esp-rs is doingtheir time, started looking into it in detail. I can see why you would want to replicate it if it's a RRIR of std::chrono
<Lumpio-> hehe
<Lumpio-> I just wish fugit was named in a way that makes it more obvious what it does
<Lumpio-> I mean I know, tempus fugit, but I sure couldn't figure out what it means when I first saw it...
<BenPh[m]> Lumpio-: Oh god, please write a quick README PR that adds a footnote. It's been eating at me, and it seems like you're in the know.
<Lumpio-> No I mean when I first saw it in a dependency list I was like "what is this now then", a readme isn't going to solve that...
<Lumpio-> I mean the first thing that came to mind was "fug it :DDD" like some Finnish meme (but please don't change it _just_ to appease corporate suit and tie people like they did with RTFM and Riot...)
<BenPh[m]> <Lumpio-> "No I mean when I first saw it in..." <- oh yeah, won't help at that level.
<BenPh[m]> ...but I'm still wondering: what's the meaning behind "fugit"?
<Lumpio-> Didn't I just say "tempus fugit" :)
<JamesMunns[m]1> <Lumpio-> "I mean the first thing that came..." <- I think I nagged korken about fugit like I did RTFM :p
<Lumpio-> Corporate is the death of enthusiasm
<Lumpio-> "we are a respectable company with a big building and a board of directors where all male members are required to wear a suit *and* a tie, you must make everything IT related bland and boring in order for us to use your product"
<BenPh[m]> Lumpio-: Sometimes I wonder about myself...
<BenPh[m]> Lumpio-: ...then you have the other end of the extreme: being forced into a bad deal because your CEO made a 420 joke on twitter.
M9names[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]1> <Lumpio-> ""we are a respectable company..." <- there's also just being edgy for edgy's sake, I don't think it's quite so binary :D
<JamesMunns[m]1> But for sure nobody is obligated to listen to naming opinions if they aren't being paid for it (or want to be paid for it).
<Lumpio-> fwiw "rtic" is a better name, I like how it almost says "tick" like a scheduler tick you know, I just don't like the reasoning behind the change!
<firefrommoonligh> I'd forgotten about Fugit
<firefrommoonligh> Fugotten?
<firefrommoonligh> * Fugottin?
<firefrommoonligh> From a skim of the docs page: : I like the flexibility and avoiding unnecessarily large integers, but the syntax is kind of verbose
<firefrommoonligh> And puts more work onto the firmware lib to think about the internal type, NOM, and DENOM
<firefrommoonligh> I guess you could wrap it in a type definition
<firefrommoonligh> I guess it's nice we have two options already! (core::Duration is the other)
<firefrommoonligh> s/lib//
<firefrommoonligh> Instant here is... orthogonal to how I've been using it on embedded (Custom type) and PC (time::Instant): The main functionality I am looking for is getting timestamp in various real time amounts, like ms, us etc
<firefrommoonligh> [Instant]( here is... missing the main functionality I use Instants for, which is getting a time value in real units. For example, on `std::time::Instant`, you call `Elapsed`, which gets a Duration, that has `as_millis()` etc methods.
<firefrommoonligh> The one I hacked together has `elapsed()` on the Timer struct, which returns an instant. The instant has `as_us()` etc methods. I need to think through that one; if it makes sense to deviate from std::time
<firefrommoonligh> s/Elapsed/elapsed()/
<firefrommoonligh> * [Instant]( here is... missing the main functionality I use Instants for, which is getting a time value in real units. For example, on `std::time::Instant`, you call `elapsed()`, which gets a Duration, that has `as_millis()` etc methods.
<firefrommoonligh> The one I hacked together has `elapsed()` on the Timer struct, which returns an instant. The instant has `as_us()` etc methods. And you get Duration from subtracting Instants. I need to think through that one; if it makes sense to deviate from std::time
<firefrommoonligh> *Ah. I think I know what's going on. Fugit is not making the assumption it's coupling with a practical clock
<Lumpio-> I guess the idea with "Instant" being the way it is was that they didn't want to decide on a publicly visible "epoch"
<Lumpio-> Like what is that number of practical units since
<BenPh[m]> firefrommoonligh: yeah. My take is that fugit is nothing more than saying "wish you could have an integer, and just _know_ if it's a certain number of milliseconds, seconds, or a count of any fraction of a second? fugit to the rescue"
<Lumpio-> This is why you always need two Instants if you want a Duration
<BenPh[m]> Instant on its own implies a duration since a reference point (typically referred to as "epoch", and in posix, is that date in the 70s, and in embedded, is typically understood to be the zero-th instant)
<Lumpio-> It doesn't though
<Lumpio-> Instant is completely opaque - there might be an "epoch" in the implementation but it sure isn't visible though
<BenPh[m]> A `Duration` is saying "this is an instant, but the reference point has been changed"
<BenPh[m]> I.e. "duration since epoch" and "instant" are two ways of expressing the same thing.
<vollbrecht[m]> I think an easy overlooked practical problem is when you are writing drivers, that all this solutions are somewhat nice by providing nice abstractions, but they have non zero runtimecost, and if i am using this things its often in a time critical manner. Using an abstraction to make it play nice with many targets is only a secondary goal. The first one is always get the driver running "up to speck".
<Lumpio-> Yes but the Rust stdlib chose to hide the epoch from the user, it might as well not exist
<BenPh[m]> Lumpio-: agreed. Instant is a measure of a duration since an opaque epoch. Duration is analagous to an instant where the the epoch has been explicitly chosen.
<BenPh[m]> Lumpio-: This is consistent with my understanding.
<BenPh[m]> vollbrecht[m]: zero-cost abstractions are impotant. fugit seems to be able to accomplish this. everything is const (with some edge-case exceptions), so theoretically, is zero cost.
<JamesMunns[m]1> Zero cost is not zero cost
<JamesMunns[m]1> It means no extra cost over what hand implementing it would be
<JamesMunns[m]1> All implementations have some cost, it's important not to forget that.
<BenPh[m]> it could be the case that the peppering of generics can bloat the binary size, but my gut is along the lines of "what these generics are doing, e.g. specifying the mapping between a time-count and the duration it represents in terms of SI time units by way of specifying the frequency of the time-counter, they must be done anyway. Saying a clock is running at 80MHz requires an integer explicitly for this purpose somewhere in the
<BenPh[m]> code. with fugit, this constant still exists, but it is logically coupled to the compile-time type-definition"
<JamesMunns[m]1> If you use wall clock times, yes, but that's not always required (tho most useful in the general case).
<BenPh[m]> JamesMunns[m]1: agreed. worth highlighting.
<firefrommoonligh> <Lumpio-> "I guess the idea with "Instant..." <- Yea; I think that is the main thing I was missing
<JamesMunns[m]1> Also, complexity to the user is a complexity not measured in CPU cycles. This applies to complex types and awkward or hard to use APIs
<BenPh[m]> JamesMunns[m]1: Could you help me see an example where, in the context of time-tracking, it's not necisary to be aware of the tick rate?
<firefrommoonligh> My intent here is when writing firmware, I want an easy and tough-to-screw-up way to store, transmit, and compare timestamps. I think what I hacked together does it, but it's tied to a target-specific timer struct. And, ideally its API is similar to std::time::Instant. It's the same concept for me, so similar syntax is easier on my brain
<firefrommoonligh> I've got the ISR trimmed down not to need a CS etc as such:... (full message at <>)
<firefrommoonligh> Where TICK_OVERFLOW_COUNT is defined in the HAL module, so the timer struct can acceess it
<firefrommoonligh> And I think it's likely my intent and Ben's intent line up
<JamesMunns[m]1> my groundhog crate does give you the ticks per second, but you can calculate this once, then work solely on ticks locally
<BenPh[m]> You might be interested in the contributing to the RFC I put up about this.... (full message at <>)
<firefrommoonligh> Here's the hardware-side impl I have. AN important part is calculating `ns_per_tick` based on timer properties (like auto reload and prescaler for STM)... (full message at <>)
<firefrommoonligh> * Here's the hardware-side impl I have. AN important part is calculating `ns_per_tick` based on timer properties (like auto reload and prescaler for STM)... (full message at <>)
<BenPh[m]> JamesMunns[m]1: So that would be equivilent to `type TickMeasure = fugit::Duration<Self::RawData, 1, {crate::timer::systimer::TICKS_PER_SECOND}>;` that I've put in for my esp-hal implementation of the time-count trait I'm working on.
<JamesMunns[m]1> if your proposed API (instant, etc.) exposes ticks, yes
badyjoke[m] has quit [Quit: Idle timeout reached: 172800s]
<BenPh[m]> I chose that one, because the original esp-hal that im working on used fugit, but in your case, the assosciated type would be a u32, and an implementation would be the hz value
<JamesMunns[m]1> particularly if you can get an Instant without calculating SI time
<BenPh[m]> JamesMunns[m]1: yeah. I feel this is important.
<SArpnt[m]> <JamesMunns[m]1> "target jsons are specific to `..." <- is there any command i can run that will just pass a taeget json to a linker that i can otherwise use normally?
<sourcebox[m]> My approach would be: use ticks internally and convert from/to real units only when absolutely necessary, ideally at compile time.
<SArpnt[m]> i want to just so the linking step by itself as both a test and a demonstration if it works
<BenPh[m]> JamesMunns[m]1: with fugit, this moves the cost of mapping tick-count to SI time to the compiler, and run-time cost would be a slight growth in binary size, i think. It works by setting up constants, and const functions, such that if you do "Duration<...>::from_ticks(...)" it's essentially changes nothing, just gives you a new type-wrapping. the cost is when you explicitly ask for the math to calculate hours.
<SArpnt[m]> s/taeget/target/
<BenPh[m]> sourcebox[m]: this is essentially what fugit is doing, if I understand it correctly.
<vollbrecht[m]> SArpnt[m]: you may first specify what you are linking together, two rust elfs? A rust and some other C lib? And second what linker are you talking about. the target.json file is a specific rust description such the compiler knows how to compile stuff.
<firefrommoonligh> Interesting re Instant exposing Ticks. The one I'm using exposes time in ns. Upon creation, this value is generated (see above) from ticks, wraps, and a pre-calculated mapping of ticks to time.
<JamesMunns[m]1> BenPh[m]: yes, but there is runtime cost to that, particularly if you don't have hardware division.
<firefrommoonligh> s/exposes/stores/, s/time/_time/, s/ns./ns_./
<JamesMunns[m]1> but not saying that's a deal breaker!
<JamesMunns[m]1> Just saying: "zero cost abstractions (the lowest possible cost) is still not **zero cost**".
<SArpnt[m]> vollbrecht[m]: i'm linking multiple static libraries into an executable with a custom linker script in a makefile for armv4t-none-eabi and armv5te-none-eabi
<firefrommoonligh> Yea... I mean, if you have an instant, and use it in a few places, if you stores time in it, you are only running ticks -to-time calcs (see above) once.
<SArpnt[m]> i'm trying to take apart a build system that currently relies on a custom linker that isn't very good
<firefrommoonligh> But if you store ticks, you run that calc every time you get a timestamp
<firefrommoonligh> s/timestamp/time/
<BenPh[m]> BenPh[m]: at least, that's how I interprete the stated goal, and my look through the code base hasn't raised anything to the contrary (yet)
<firefrommoonligh> Does anyone nave any examples of how Fugit works in practice?
<BenPh[m]> firefrommoonligh: No, you get ticks, with assosciated generics that describe the frequency. you don't need to do run-time calculations until you explicitly ask for operations that cannot be inherently done at compile time.
<BenPh[m]> firefrommoonligh: esp-rs uses it a lot under the hood.
<firefrommoonligh> Ah got it
<JamesMunns[m]1> > operations that cannot be inherently done at compile time
<JamesMunns[m]1> How would you calculate runtime known values (e.g. timestamp in ticks) at compile time?
<JamesMunns[m]1> you could calculate the scalar factor at compile time, but you still have to do math to go from ticks to secs/millis/micros.
<sourcebox[m]> When using ticks, getting an Instant is dead cheap by typically just reading a timer register or variable. No calculation required.
<JamesMunns[m]1> like, you will have a constant mult/div factor - but you wont know the ticks (8001, 15564, 76543, etc.) until runtime, which you will have to turn into SI time.
<BenPh[m]> JamesMunns[m]1: > <> > operations that cannot be inherently done at compile time... (full message at <>)
<JamesMunns[m]1> BenPh[m]: yeah, so I have ticks of 76543, how many seconds is that?
<BenPh[m]> if you want "Give me a count of how many hours", it would give you a `Duration<u32, 3600, 1>`
<JamesMunns[m]1> sure, and what if I want the duration based on a user given value, e.g. a packet over the radio?
<firefrommoonligh> JamesMunns[m]1: This is where the stored `ns_per_ticks` var is important.
<JamesMunns[m]1> firefrommoonligh: yep! but I'm saying: *you have to do math on the ticks and the scalar value at runtime to compute the ns*!
<firefrommoonligh> Yea def
<BenPh[m]> JamesMunns[m]1: then that is a non-compile-time defined scale. I would have to think of the appropriate solution. I suspect that `fugit` wouldn't be an appropriate tool in such a case, but I don't suspect too strongly.
<firefrommoonligh> Not sure how to avoid that, but sounds lke you have a way?
<JamesMunns[m]1> anyway, I'm looking forward to review the actual code, rather than a sort of amorphous idea of what the code could be. There are MANY ways to solve this with different costs! But the HAL team will have to review a specific proposal and/or implementation, rather than vibes!
<JamesMunns[m]1> firefrommoonligh: tbh, I just use embassy-time 99.9% of the time, which *does* have costs, but it doesn't sell itself as zero cost - it sells itself as "a reasonable cost for the value/convenience you get in return".
<JamesMunns[m]1> and, the costs are not substantial about to care about in any project (incl. customer projects) I've done so far!
<ryan-summers[m]> FWIW I don't think I've ever seen or needed zero-cost time conversion stuff
<JamesMunns[m]1> I'll take making my life easier 99.9% of the time, for 0.1% more CPU usage, and 10x less hassle, and if I'm doing something in a tight loop, I'll do something different or fancy instead.
<firefrommoonligh> Yea we aer on the same page
<firefrommoonligh> I don't see how this is possible
<BenPh[m]> The question in my mind is "if it's encapsulating something that canot be expressed at compile time, should that be supported by a portable hal-trait?"
<JamesMunns[m]1> ¯\_(ツ)_/¯ have fun y'all :)
<firefrommoonligh> I mean, the $2 (on JLC) MCU that has become my favorite general-purpose tool has an FPU, 170Mhz CPU etc...
<JamesMunns[m]1> firefrommoonligh: oh, G4?
<firefrommoonligh> So I just want concise, working, maintainable code.
<JamesMunns[m]1> the G0 and G4 are both goodies, I use those and RP2040s a lot these days.
<JamesMunns[m]1> (actually haven't used G4 myself, but heard good things)
<firefrommoonligh> Yea - ther's a G4 variant (431) that has low flash and ram, but is cheap and available in high quantities
<firefrommoonligh> Nailed it
<firefrommoonligh> The higher-flash G4s get pricey to the point where there isn't much point in them IMO
<sourcebox[m]> In our initial discussion 2 years ago, there was a concern about u64 being to expensive on some platforms.
<vollbrecht[m]> sourcebox[m]: for avr-hal its a dealbreaker ;D
<JamesMunns[m]1> yeah, G0 is great fun for something you'd use specific ICs for, if you want it done custom, and can deal with low pin count and flash/ram (CM0+, 8K RAM, 16-64KiB flash, but you can get it TSSOP20 and it literally only requires a single ext component, a decoupling cap)
<BenPh[m]> My motivation is to see progress be made towards rust-embedded being a first class citizen of embedded development. Both convenient, and "no-compromise" zero-cost abstractions should be available. I see it not as a question of "what people will mostly use" but "what's missing from the ecosystem that prevents rust from being a true, first-class option, when considering tools to use"?
<JamesMunns[m]1> BenPh[m]: man, you keep repeating this mission statement - but I really don't think the situation is as dire as that communicates.
<ryan-summers[m]> Yeah I've been doing embedded dev in rust for years and not really needed this
<JamesMunns[m]1> there are time abstractions out there, it's not as widespread as the rest of e-hal, and I do think we need something, but this is a huge rallying cry.
<ryan-summers[m]> Nor have I needed it in C/C++
<JamesMunns[m]1> like, I'm glad you're having the conversation! But it's also not a 5 alarm emergency situation.
<ryan-summers[m]> But also don't listen to me right now, my brain is so severely jetlagged I can barely pay attention to anything
<firefrommoonligh> What drove me into this rabbit hole is I've been doing a lot of PC-embedded interop (over USB), and I notice that some of the code is similar between the two, and some isn't. I was thinking "I use abstract timers on both; why is it so different", so I wrote some embedded code to make it work more like on PC, then I saw Ben's post, and it seemed of similar intent.
<JamesMunns[m]1> firefrommoonligh: oh btw if you are doing this and haven't seen postcard-rpc, if you're ready to get on the serde train, I'm building some nice tooling around the PC/MCU-over-USB interop
<BenPh[m]> I just mean to communicate my personal motivation. I don't wish to claim that it is applicable in the general case: It's is very opinionated.
<BenPh[m]> I read you on your point. I should make more of an effort to be aware of the context I share this.
<sourcebox[m]> Honestly, I don't need to have all that fancy conversions at all. But a way to share time information between HAL, drivers and application would make life easier.
<firefrommoonligh> Excellent. I think some of the use cases I have are suitable for postcard
<JamesMunns[m]1> JamesMunns[m]1: My talk at RustNL, if you want the 30m talk version of both postcard and postcard-rpc:
<firefrommoonligh> Great; will take a look!
<JamesMunns[m]1> BenPh[m]: > <> I just mean to communicate my personal motivation. I don't wish to claim that it is applicable in the general case: It's is very opinionated.... (full message at <>)
<BenPh[m]> JamesMunns[m]1: > <> Like I said - you do you! But definitely keep an eye on the big picture, and it's much easier for folks to discuss concrete impl details and existing code than amorphous idea - it's very easy to talk in circles for hours on fuzzy ideas, vs direct feedback on actual code.... (full message at <>)
<ryan-summers[m]> sourcebox[m]: I 100% second this. The true need is interop between drivers/hals etc that all do things differently. Right now, the only real approach is "Send me ms in u32" or similiar. You can use fugit, but this imposes versioning issues as well (heapless in an external API has the same issue)
<ryan-summers[m]> What gets a bit more complicated and a good example use case is when a sensor driver may require some delay or timekeeping to know when the next sample is available. How does a driver know when this time has lapsed or when the sample should be ready?
<ryan-summers[m]> This is originally why I really liked embedded-time for its Clock trait. It unfortunately got abandoned by the maintainer pretty quickly. I used it a lot in an MQTT client and allowed the user to provide an arbitrary time keeping mechanism to handle keep-alive indications etc.
<sourcebox[m]> Yes, this is exactly what my motivation was when I started this whole discussion long ago.
<BenPh[m]> ryan-summers[m]: I originally thought `embedded-time` was part of rust embedded when I first saw it come up. wasn't until i scratched surface that I saw its state. I'm leaning into `embedded-time` quite heavily in my RFC and work on this.
<ryan-summers[m]> I suppose the previous Instant::elapsed() could solve the driver "know when next sample is ready" case, but I suspect the Instant would need a reference to the internal clock
<ryan-summers[m]> And then sharing said clock across multiple instances might cause lots of lifetime issues
<ryan-summers[m]> std avoids this because you can just always ask the OS to manage the clock for you
<ryan-summers[m]> * std avoids this because you can just use the system time, which is outside of the rust domain
<BenPh[m]> ryan-summers[m]: I'm trying to keep things minimal by limiting it just to the concept of reading a count, and interpreting that as a duration, pretty much the way the `Clock` trait does.
<BenPh[m]> Your comment about sharing an impl of a `Clock` has been raised, and it's a technical question that must be addressed at some point.
<ryan-summers[m]> I think it would need to be addressed before I'd ever consider an approach. Lifetimes in rust can be super burdensome for things like this
<ryan-summers[m]> And I wouldn't just write that off as a "technical detail". In rust, those kind of details can entirely break ideas, where they'd normally be fine in something like C, because it can make the program so much more complex or not possible in certain frameworks
<ryan-summers[m]> I've entirely scrapped ideas I've worked days on precisely for these reasons more than once
<ryan-summers[m]> Just saying that my gut reaction here is that "Thar be dragons" and this is likely pretty hard
<BenPh[m]> in a simplified context, a shared, imutable `Clock` is fine. it's a read-only thing, except when tracking overflows, but I think I already have a solution for that.
<BenPh[m]> The issue is if anything has been missed about reasonable expectations of what implementing a time-counter should imply, and does that include anything that precludes shared **im**mutable state?
<ryan-summers[m]> BenPh[m]: > <> in a simplified context, a shared, imutable `Clock` is fine. it's a read-only thing, except when tracking overflows, but I think I already have a solution for that.... (full message at <>)
<ryan-summers[m]> It's only really useful if the Clock is then 'static, which could be a really hard ask
<ryan-summers[m]> Otherwise, you can never store an `Instant<'a>` as i.e. an RTIC resource or similiar because it doesn't have a known type at compile time
<BenPh[m]> I don't think Instant needs to be coupled to the lifetime of a clock. It's a reading of a value. It's only connection to a clock is its method of creation, not what is being created.
<ryan-summers[m]> Yes, but then how can you ever make an Instant::elapsed() function without reference to the original timepiece used to make the instant to see the current time?
<BenPh[m]> by analogy, someone can ask you for the time in the street, then steal the watch you read the time from. That reading never changed.
<firefrommoonligh> I guess you can assume; it's what I"m doing
<ryan-summers[m]> I.e. an instant is then only a specific point in time. It could be used to compare with other points, but that doesn't feel super useful to me. Someone could just use fugit and wouldn't need some e-h trait
<BenPh[m]> ryan-summers[m]: elapsed() would be equivilent to `duration_since_epoch`, no?
<firefrommoonligh> I'm comparing Instants. But if you do something like stop the timer or w/e, it will break things. So, I keep the timer running! (And if you are using low power modes, that will break it; at that point it's probably RTC time)
<ryan-summers[m]> No, elapsed is the amount of time elapsed since that instant was created
<BenPh[m]> ryan-summers[m]: then you would do clock.duration_since(instant).
<ryan-summers[m]> Yeah but now you have to own the clock and the instant
<ryan-summers[m]> What if multiple drivers want the clock?
<BenPh[m]> ryan-summers[m]: > <> I.e.... (full message at <>)
<BenPh[m]> std environment is different.
<ryan-summers[m]> My point was I don't think the naming is misleading if it's a generally accepted, std-based approach
<ryan-summers[m]> ANyways gotta get back to work. As James said, I'd be happy to look at a concrete implementation - this stuff is hard to get working in practice
<ryan-summers[m]> * get working (and useful) in practice
<BenPh[m]> <ryan-summers[m]> "What if multiple drivers want..." <- This is a thinker! but setting something up so that the _source_ of a time-count is a vague *thing* that exists *gestitulates randomly* somewhere as a global is not the solution, inmho.
<sourcebox[m]> I personally would vote for having embassy-time as "official" solution. The only thing I don't like is the enormous amount of tick feature flags.
<BenPh[m]> and an `Instant` being a time-source, it must either be coupled to a specific clock in-memory (e.g. by holding a reference), or there must be a globally accesable source that it knows how to access.
<BenPh[m]> the `std` model takes the second approach, is my guess. that's fine in a context where you are running on a defined, universally accepted platform, but that is very much not the case in embedded.
pronvis has joined #rust-embedded
<pronvis> Hey guys!
<pronvis> am working on some kind of robot that have 4 stepper motors. To control them I have tmc2209 drivers. It is possible to speak with those drivers via half-duplex UART
<pronvis> There is no SoftwareSerial library for Rust which supports half-duplex, so I wrote my own. And when I tested that code I found some weird behavior, which I cant describe. It looks like some compiler optimisation, but I may wrong
<pronvis> Describing my code and it behavior is too much for IRC chat, so I wrote a post about it on Reddit, looking for embedded guru help:
newam[m] has quit [Quit: Idle timeout reached: 172800s]
<JamesMunns[m]1> There is, though it's out of date these days it appears
<pronvis> @JamesMunnel thank you, but it requires TX: OutputPin and RX: InputPin, but I have only one: TXRX: DynamicPin
<JamesMunns[m]1> ahh, gotcha, sometimes half duplex means "send OR receive only", sometimes it means "take turns", good point!
pronvis has quit [Read error: Connection reset by peer]
pronvis has joined #rust-embedded
<vollbrecht[m]> in esp land we call it half3wire 😺
<vollbrecht[m]> * in esp land we call the dynamic case half3wire 😺
stephe has quit [Quit: Connection closed for inactivity]
<firefrommoonligh> So... Here is where I am at with the timestamp thing:... (full message at <>)
<firefrommoonligh> s/timeInstant/time:Instant/, s/`>/`\>/
<firefrommoonligh> * So... Here is where I am at with the timestamp thing:... (full message at <>)
<firefrommoonligh> Maye have the Timer have a get_instant method, and remove the .as_millis() on it directly?
<firefrommoonligh> s/get_instant/`now()`/, s/./`./, s//`/
<dirbaio[m]> if you want "time since boot" i'd just copy the std api exactly
<dirbaio[m]> this is what embassy-time does
<firefrommoonligh> (A goal here is consistency)
<firefrommoonligh> Yea I am thinking same
<firefrommoonligh> It's technically time since whenever you started the timer, but same idea
<BenPh[m]> In my mind, it should be up to the implementors to define what the types are when you read a time-counter, and interprate it as a measure of time. I would advocate some sort of type representation within embedded-hal, but that's out of scope of designing a portable interface.
<BenPh[m]> at the moment, those trying to make a portable time driver seem to have to choose between embassy-time primitives, u64, or fugit. Part of the meeting outcomes this week discussed fugit maintenance.
rmsyn[m] has quit [Quit: Idle timeout reached: 172800s]
<BenPh[m]> As soon as the interface starts setting opinionated restrictions on what the types are, it becomes less portable.
<JamesMunns[m]1> BenPh[m]: disagree
<whitequark[cis]> fugit?
<dirbaio[m]> 🍿
<JamesMunns[m]1> as in, "Tempus Fugit" (this is also why I dislike names like this - you spend more time explaining the name than discussing the actual crate itself)
<whitequark[cis]> wow that's a lot of types
<whitequark[cis]> JamesMunns[m]1: what the hell does that mean
<BenPh[m]> whitequark[cis]: most of those are type aliases.
<JamesMunns[m]1> latin
<whitequark[cis]> wow that's a lot of type aliases
<JamesMunns[m]1> (I hadn't heard the saying until after I saw the crate)
<BenPh[m]> MilliDuration<T> is just Duration<T, 1, 1000>
<BenPh[m]> MicroDuration<T> is just Duration<T, 1, 1_000_000>
<firefrommoonligh> After thought, I like what I just posted, and am trying it. Timer::now() -> Instant. Instant::elapsed() -> Duration. Get integer values for ms etc from Duration. So... just like std. Working at first glance.
<firefrommoonligh> No more as_millis() etc on Instant, and no elapsed on Timer. Those would be confusing compared to std::Time
<whitequark[cis]> JamesMunns[m]1: this is supposed to be an image right? element fails to show it
<BenPh[m]> whitequark[cis]: there are a whole lot of different names we give to different aliases for time. Every time you're saying a time-frame that isn't seconds, you're using an alias. "10 hours" is just 3.6 * 10^3 seconds" :P
<JamesMunns[m]1> whitequark[cis]: Ah yes, screenshot of the google info page:
<JamesMunns[m]1> > time flies (used to draw attention to the rapid passage of time).
<JamesMunns[m]1> > "Tempus fugit! It seems no time since we were cursing the long, dark winter evenings—now here we are in flaming June"
<whitequark[cis]> personally i prefer space wasps but that's just my fave arthropod
<BenPh[m]> firefrommoonligh: Instant::elapsed() is just `duration_since_epock()`, or am I missing something?
<firefrommoonligh> I think so
<firefrommoonligh> *Sorry, I confused things. What I meant was, I generally use an_instant.elapsed() to get a duration since that Instant. That's what I'm going for.
<firefrommoonligh> I guess it would have to be `Timer::elapsed(instant) -> Duration
<firefrommoonligh> Or vice versa
<JamesMunns[m]1> At some point, I might suggest it would make sense to move all of the "plans for time planning" to another room - this has been like 90% of the traffic of the whole room for like two days now
<BenPh[m]> firefrommoonligh: that works in a std environment, but it doesn't fit in with making things portable. This way, you either a) have to couple a source of an instant to an instant, which makes the lifetime of the instant and the source tightly coupled, or you have to use only one common global time-source, which forces a (arguably bad) design scheme onto anyone that chooses to implement the trait.
<JamesMunns[m]1> it's... challenging to have other discussions around this one, and it might be more useful to have a single room where the whole history is "on topic"
<dirbaio[m]> that's why zulip's "topics" are great
<firefrommoonligh> Yea - this isn't portable. It's practical
<firefrommoonligh> I'm not coupling; i'm just calling in a situation where I have both.
<BenPh[m]> so then it would have to be `instant.duration_since(&clock_source)`?
<JamesMunns[m]1> We have a zulip channel if folks would like to use that instead:
<JamesMunns[m]1> (normally, here is the best place for visibility, but this discussion is eclipsing normal operation)
<JamesMunns[m]1> so - perhaps better to have the conversation elsewhere, and check back in here if there are things to share, or get feedback on.
AtleoS has quit [Ping timeout: 268 seconds]
AdamHott[m] has quit [Quit: Idle timeout reached: 172800s]
bartmassey[m] has quit [Quit: Idle timeout reached: 172800s]
cbjamo[m] has quit [Quit: Idle timeout reached: 172800s]
sirhcel[m] has quit [Quit: Idle timeout reached: 172800s]
pronvis_ has joined #rust-embedded
pronvis has quit [Read error: Connection reset by peer]
pronvis_ has quit [Remote host closed the connection]
pronvis has joined #rust-embedded
pronvis has quit [Ping timeout: 268 seconds]
pronvis has joined #rust-embedded
pronvis has quit [Ping timeout: 264 seconds]
pronvis has joined #rust-embedded
pronvis has quit [Ping timeout: 252 seconds]
pronvis has joined #rust-embedded
pronvis has quit [Ping timeout: 260 seconds]
pronvis has joined #rust-embedded
pronvis has quit [Ping timeout: 252 seconds]
M9names[m] has joined #rust-embedded
<M9names[m]> <JamesMunns[m]1> "as in, "Tempus Fugit" (this is..." <- Could you more explicitly define "names like this"? Like, what makes this name bad, and crate names like "grounded", "bbqueue" good?
<M9names[m]> Are tokio, crossbeam, mnemos and embassy good names, or do we just tolerate how bad they are?
pronvis has joined #rust-embedded
pronvis has quit [Ping timeout: 268 seconds]
pronvis has joined #rust-embedded
pronvis has quit [Ping timeout: 264 seconds]
pronvis has joined #rust-embedded
adamgreig[m] has quit [Quit: Idle timeout reached: 172800s]
NickStevens[m] has quit [Quit: Idle timeout reached: 172800s]