ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to #rust-embedded:matrix.org and logged at https://libera.irclog.whitequark.org/rust-embedded, code of conduct at https://www.rust-lang.org/conduct.html
<re_irc> <ian_rees> jamesmunns I really like the timing discussion in that "Better Embedded System Software" book that IIRC you recommended a while back - safe to assume your approach is in line with it?
<re_irc> <James Munns> as far as I remember, yes!
radens has joined #rust-embedded
<re_irc> <James Munns> firefrommoonlight here's a simple example, with two main tasks (I call high and low priority): https://docs.google.com/spreadsheets/d/1rrGZ0NnGumaqc3w2ThWdF0v0CTztLt5JmYl5unFwLMw/edit?usp=sharing
<re_irc> <James Munns> This shows "worst case", with blocking everything, using ~70% of the total budget. You can play around with the numbers (you'll need to copy the sheet) to see how things like upping the sample rate (or task rate) would affect budget.
<re_irc> <James Munns> You could also look at things like sending/receiving as being something that could be mostly eliminated with DMA, while things like serializing or filtering couldn't be.
<re_irc> <James Munns> but - usually I don't do that on a "first pass", I just take the notes and see how bad things are.
explore has joined #rust-embedded
<re_irc> <James Munns> hope thats helpful :)
<re_irc> <firefrommoonlight> Nice! An example of how to get organized
<re_irc> <firefrommoonlight> Also of note, even if you're not using all the CPU time bewteen updates, you can still get into trouble with latency if 2 things are fighting for the same time slot
<re_irc> <firefrommoonlight> (assuming latency-critical use case)
<re_irc> <James Munns> Yeah, I'd probably put anything latency critical in the highest prio
<re_irc> <James Munns> but certainly scheduling calculation is a whole thing, for sure.
<re_irc> <James Munns> (usually queues are my go-to for breaking this up, I don't actually like shared resources for ANYTHING, especially not anything timing critical)
<re_irc> <James Munns> but if you assume you don't have any shared resources - this will tell you basically "how much CPU do you use per second".
<re_irc> <James Munns> which is the same regardless of how you schedule it.
<re_irc> <James Munns> (this is more about CPU budgeting - vs "worst case execution time" or "worst case latency guarantees")
<re_irc> <firefrommoonlight> I trust in ST
<re_irc> <James Munns> but - if you don't have contention - and a high prio task runs EXACTLY once a millisecond, EVERY millisecond - that calculation is trivial: your worst case latency is 1ms.
<re_irc> <James Munns> Here, this also allows you to "roll down" your budget.
<re_irc> <James Munns> if your high prio task runs at 10x the nominal rate of your low prio task, and it takes 3.550ms out of every low prio window, you know your low prio task must execute in 10-3.550ms
<re_irc> <James Munns> (and still successfully achieve it's worst-case 10ms latency window)
<re_irc> <James Munns> this gets much more complicated when you have more complex scheduling
<re_irc> <James Munns> but if you can keep it segmented in "a couple of tasks that run at fixed intervals, and always fit into their fractional time slice", your life will be 100x easier.
<re_irc> <James Munns> especially if you can segment "latency critical" and "non latency critical" requirements.
<re_irc> <James Munns> (koopman's book goes much more into calculating WCET and latency/response time calculations, including some helpful formulas - this is the "good way to have confidence if you have the luxury of keeping everything stupid simple"
<re_irc> <James Munns> that being said: I find "stupid simple" maps to "stupid reliable" more often than not :)
<re_irc> <James Munns> this calculation basically assumes "worst case is the always case"
<re_irc> <James Munns> which makes a lot of scheduling and calculation trivial.
<re_irc> <James Munns> but, I've talked too much tonight anyway :). This is a good place to start, and it will work until it doesn't! Then you will need to bring in more complex math to make sure everything fits in the hardware you have.
<re_irc> <firefrommoonlight> I'm with stupid simple!
<re_irc> <firefrommoonlight> Thanks for all the info and ruminations; super useful
<re_irc> <firefrommoonlight> and relevant
<re_irc> <firefrommoonlight> In the vein of stupid simple: Here's the entirety of the setup code for the ADC, which thankfully doesn't need tight timing considerations:
<re_irc> let mut batt_curr_adc = Adc::new_adc2(dp.ADC2, AdcDevice::Two, adc_cfg, &clock_cfg);
<re_irc> batt_curr_adc.set_sample_time(setup::BATT_ADC_CH, adc::SampleTime::T601);
<re_irc> // With continuous reads, we can set a long sample time.
<re_irc> <firefrommoonlight> * Adc::new(dp.ADC2,
<re_irc> <firefrommoonlight> In the vein of stupid simple: Here's the entirety of the setup code for the ADC, which thankfully doesn't need tight timing considerations:
<re_irc> // We use the ADC to measure battery voltage and ESC current.
<re_irc> operation_mode: adc::OperationMode::Continuous,
<re_irc> let adc_cfg = AdcConfig {
<re_irc> <firefrommoonlight> So, a bit of setup code, but then skim readings A/R from the buffer in runtime, and never touch the ADC periph
<re_irc> <firefrommoonlight> In the vein of stupid simple: Here's the entirety of the setup code for the ADC, which thankfully doesn't need tight timing considerations:
<re_irc> // We use the ADC to measure battery voltage and ESC current.
<re_irc> let adc_cfg = AdcConfig {
<re_irc> operation_mode: adc::OperationMode::Continuous,
<re_irc> <firefrommoonlight> In the vein of stupid simple: Here's the entirety of the setup code for the ADC, which thankfully doesn't need tight timing considerations:
<re_irc> // We use the ADC to measure battery voltage and ESC current.
<re_irc> let adc_cfg = AdcConfig {
<re_irc> operation_mode: adc::OperationMode::Continuous,
<re_irc> <dirbaio> I wonder if you can read torn/corrupted values if you read right when DMA writes to it
<re_irc> <firefrommoonlight> I was having that though too
<re_irc> <firefrommoonlight> And am actually surprised it didn't come up in testing
<re_irc> <firefrommoonlight> Could workaround that with a longer buffer as a quick+dirty approach if it becomes a problem
<re_irc> <firefrommoonlight> There are some STM32 ADC settings related to overruns and underruns etc that might be relevant (?)
<re_irc> <dirbaio> to avoid UB you have to do volatile reads to the buffer
<re_irc> <dirbaio> but even with volatile you could read a torn value
<re_irc> <dirbaio> unless you do the same access witdth as DMA I think?
<re_irc> <dirbaio> like, if the DMA does 16bit writes and you do 16bit reads then you can't read torn values (?)
<re_irc> <firefrommoonlight> In this case, the DMA is doing 16-bit writes. Not sure if the ADC is doing 16 or 12
<re_irc> <firefrommoonlight> Again, I'm legit surprised it's working without any consideration for deconflicting read and write
<re_irc> <firefrommoonlight> *ADC is probalby doing 16, due to ADC_DR being 16 bits
<re_irc> <firefrommoonlight> * ADC_DR's RDATA field
starblue has quit [Ping timeout: 246 seconds]
starblue has joined #rust-embedded
bjc has left #rust-embedded [ERC 5.4 (IRC client for GNU Emacs 28.1)]
<re_irc> <Imran K> Yes
causal has quit [Quit: WeeChat 3.5]
explore has quit [Quit: Connection closed for inactivity]
emerent is now known as Guest8852
Guest8852 has quit [Killed (mercury.libera.chat (Nickname regained by services))]
emerent has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
Ekho has quit [Remote host closed the connection]
Ekho has joined #rust-embedded
genpaku has quit [Ping timeout: 272 seconds]
genpaku has joined #rust-embedded
explore has joined #rust-embedded
fooker has quit [Ping timeout: 258 seconds]
fooker has joined #rust-embedded
starblue has quit [Ping timeout: 258 seconds]
starblue has joined #rust-embedded
thomas25 has quit [Quit: fBNC - https://bnc4free.com]
thomas25 has joined #rust-embedded
radens has quit [Quit: Connection closed for inactivity]
explore has quit [Quit: Connection closed for inactivity]
explore has joined #rust-embedded
crabbedhaloablut has joined #rust-embedded
genpaku has quit [Remote host closed the connection]
genpaku has joined #rust-embedded
genpaku has quit [Quit: leaving]
genpaku has joined #rust-embedded
causal has joined #rust-embedded
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
iyedonhismed has joined #rust-embedded
iyedonhismed has quit [Client Quit]
genpaku has quit [Quit: leaving]