creich_ has quit [Quit: Leaving]
creich has joined #rust-embedded
starblue1 has joined #rust-embedded
starblue has quit [Ping timeout: 244 seconds]
emerent has quit [Ping timeout: 244 seconds]
emerent has joined #rust-embedded
tokomak has joined #rust-embedded
fabic has quit [Ping timeout: 265 seconds]
<re_irc_> <@w​illeml:m​> How would I read memory mapped external (qspi) flash?
<re_irc_> <@w​illeml:m​> or actually, how would I read internal flash?
<re_irc_> <@w​illeml:m​> I know how to write internal, but I do not know how to read it...
<re_irc_> <@d​irbaio:m​> internal flash is simply memory-mapped
<re_irc_> <@d​irbaio:m​> in stm32s at 0x0800_0000
<re_irc_> <@w​illeml:m​> I mean, how do I read memory?
<re_irc_> <@w​illeml:m​> I know how to do it in z80 asm, but not rust lol
<re_irc_> <@d​irbaio:m​> cast the int memory address to a pointer
<re_irc_> <@d​irbaio:m​> 0x0800_0000 as *const u8
<re_irc_> <@w​illeml:m​> ah, and that reads a single byte I guess?
<re_irc_> <@w​illeml:m​> if I wanted to read say the next 4096 bytes how would I do that easily?
<re_irc_> <@d​irbaio:m​> that gives you a raw pointer, you can then use it to read with .read() or similar
<re_irc_> <@d​irbaio:m​> you can also construct slices from it
<re_irc_> <@d​irbaio:m​> `let s = slice::from_raw_parts(0x0800_0000 as *const u8, 256*1024)`
<re_irc_> <@d​irbaio:m​> that'll give you a `&[u8]` of the entire flash (assuming it's 256kb)
<re_irc_> <@d​irbaio:m​> that slice really points to flash, creating it is "free", it's not copying the data! :D
<re_irc_> <@w​illeml:m​> Awesome!
<re_irc_> <@d​irbaio:m​> note that the compiler is allowed to assume the data doesn't change while the slice exists (since it's a &)
<re_irc_> <@d​irbaio:m​> so if you write to flash you need to make sure to *not* hold on to such slices
<re_irc_> <@w​illeml:m​> so `let s = slice::from_raw_parts(0x0800_0000 as *const u8, 4*1024)` would create a pointer to the first 4k of flash
<re_irc_> <@d​irbaio:m​> yup
<re_irc_> <@d​irbaio:m​> for example if you write, do *not* keep the slice around
<re_irc_> <@w​illeml:m​> dirbaio: so if I write flash, drop the slice and recreate the pointer
<re_irc_> <@d​irbaio:m​> create the slice to read, then write, then create the slice again
<re_irc_> <@d​irbaio:m​> yeah
<re_irc_> <@w​illeml:m​> Awesome, thank you
<re_irc_> <@d​irbaio:m​> and for external memory-mapped qspi it works the same
<re_irc_> <@d​irbaio:m​> you need to do whatever black magic the qspi peripheral needs to configure memory mapping, then you can create slices like that too :D
<re_irc_> <@w​illeml:m​> just `0x0900_000`
<re_irc_> <@d​irbaio:m​> yea
<re_irc_> <@w​illeml:m​> I am pretty sure that I have already done the memory mapping code, just need to test it lol
<re_irc_> <@w​illeml:m​> porting c++ code is not fun
<re_irc_> <@w​illeml:m​> Also, makes me realize how stupid some parts of C++ are...
<re_irc_> <@d​irbaio:m​> hahaha :D
<re_irc_> <@w​illeml:m​> Is there an easy way of formatting a slice of u8 to a binary file?
<re_irc_> <@w​illeml:m​> (and then sending that over rtt)
<re_irc_> <@9​names:m​> you could encode it as ascii hex (2 base 16 numbers, 00 to FF) and use a tool like XXD to convert it back to binary on your PC
<re_irc_> <@9​names:m​> not very efficient, but simple.
<re_irc_> <@d​irbaio:m​> you can read memory contents from pc with `probe-rs-cli dump 08000000 4096`
<re_irc_> <@w​illeml:m​> oh, thats awesome, thanks
<re_irc_> <@w​illeml:m​> exactly what I have been looking for
<re_irc_> <@w​illeml:m​> Would you happen to know if I can write to memory mapped addresses?
<re_irc_> <@9​names:m​> the memory mapping is usually read-only, since flash needs to be erased to be written to
<re_irc_> <@w​illeml:m​> ah
<re_irc_> <@d​isasm-ewg:m​> Oops, I forgot to move RISC-V team repos to GHA and Travis already stopped working. I wonder how we can do this technically and administratively now. adamgreig maybe you have an idea?
dkm has quit [*.net *.split]
dkm has joined #rust-embedded
Lumpio- has quit [*.net *.split]
Lumpio_ has joined #rust-embedded
<re_irc_> <@a​damgreig:m​> disasm: It shouldn't cause any issues, a new pr can change bors.toml to require gha instead of Travis and at the same time remove travis.yaml and add a gha workflow
<re_irc_> <@a​damgreig:m​> But some repos might have GitHub set to require both Travis and bors, in which case you might be able to change that from the protected branch settings
<re_irc_> <@a​damgreig:m​> But if you can't, I certainly can, so just let me know which repos have Travis set to required and I'll remove it
<re_irc_> <@j​amesmunns:m​> As a note (CC adamgreig), we might want to mark the `r0` crate as deprecated, and link to as explanation why.
<re_irc_> <@j​amesmunns:m​> It caused confusion on twitter today: (see above/below context)
<re_irc_> <@a​damgreig:m​> thanks
fabic has joined #rust-embedded
<re_irc_> <@d​isasm-ewg:m​> adamgreig: Hmm, interesting. I'll go this way then.
<re_irc_> <@t​halesfragoso:m​> thalesfragoso: Is this what really happens in cortex-m-rt ? Ping adamgreig
<re_irc_> <@a​damgreig:m​> more or less, yea, why?
<re_irc_> <@a​damgreig:m​> i.e. anything that's declared at the top of the method as `static mut` is replaced by a `&mut`
<re_irc_> <@a​damgreig:m​> in the end I don't know how widely used this feature is, and it's quite surprising to a lot of people
<re_irc_> <@t​halesfragoso:m​> Because that example is unsound...
<re_irc_> <@a​damgreig:m​> it possibly made more sense in the early days
<re_irc_> <@a​damgreig:m​> what's the nature of the unsoundness?
<re_irc_> <@a​damgreig:m​> you can't call the interrupt handler, you can't spell its eventual name
<re_irc_> <@t​halesfragoso:m​> On the second "call" to interrupt you have two &mut alive at the same time
<re_irc_> <@t​halesfragoso:m​> Yeah, but you can trigger it anyway
<re_irc_> <@a​damgreig:m​> mm
<re_irc_> <@t​halesfragoso:m​> The call there is just an example
<re_irc_> <@a​damgreig:m​> and the `unsafe` on L18 would go away if STORAGE was a Mutex?
<re_irc_> <@t​halesfragoso:m​> Yep
<re_irc_> <@t​halesfragoso:m​> So, UB in safe code
<re_irc_> <@t​halesfragoso:m​> I mean, that's what I think, I would wish someone would prove me wrong
<re_irc_> <@t​halesfragoso:m​> Because now I'm really wondering if that's also the case in RTIC...
<re_irc_> <@j​amesmunns:m​> I feel like we've had this discussion before and decided it was okay
<re_irc_> <@j​amesmunns:m​> but don't take that as fact
<re_irc_> <@j​amesmunns:m​> with rtic, I believe your access to resources is bounded on the lifetime of cotext
<re_irc_> <@j​amesmunns:m​> which means you can't hold the reference more than the lifetime of the task function
<re_irc_> <@t​halesfragoso:m​> Oh, that would solve it them
<re_irc_> <@j​amesmunns:m​> could be wrong tho
<re_irc_> <@t​halesfragoso:m​> I will do some checks later and ask around
<re_irc_> <@j​amesmunns:m​> and interrupts are specifically not re-entrant in cortex-m-rt and rtic
<re_irc_> <@t​halesfragoso:m​> Yeah, but it doesn't need to be re-entrant
<re_irc_> <@j​amesmunns:m​> like, you can pend the interrupt anywhere, but it will never be called recursively
<re_irc_> <@t​halesfragoso:m​> If you got a &'static mut you can storage it anywhere
<re_irc_> <@j​amesmunns:m​> yeah
<re_irc_> <@j​amesmunns:m​> I understand the potential problem, but I feel like this is something we identified and resolved previously
<re_irc_> <@j​amesmunns:m​> its an echo of a memory though.
<re_irc_> <@t​halesfragoso:m​> I should try it on real cortex-m code, but it feels like it's the same thing
<re_irc_> <@j​amesmunns:m​> how do I make a critical section again?
<re_irc_> <@t​halesfragoso:m​> cortex_m:: interrupt::free
<re_irc_> <@a​damgreig:m​> `cortex_m::interrupt::free(|_| {...})`
<re_irc_> <@a​damgreig:m​> aw, too slow
<re_irc_> <@t​halesfragoso:m​> yours was more complete, heh
<re_irc_> <@a​damgreig:m​> thalesfragoso: I think the &mut you get from cortex-m-rt _isnt'_ `'static`?
<re_irc_> <@j​amesmunns:m​> ```rust
<re_irc_> <@j​amesmunns:m​> static STORAGE: Mutex<Option<&'static mut u32>> = ::cortex_m::interrupt::Mutex::new(None);
<re_irc_> <@j​amesmunns:m​> use cortex_m::interrupt::{Mutex, free};
<re_irc_> <@j​amesmunns:m​> #[interrupt]
<re_irc_> <@j​amesmunns:m​> borrow also only gives you an &
<re_irc_> <@j​amesmunns:m​> lemme add inner mut
<re_irc_> <@t​halesfragoso:m​> That fails to compile ?
<re_irc_> <@a​damgreig:m​> borrow gives you an & to an &mut
<re_irc_> <@a​damgreig:m​> so you do get the mut, that's ok
<re_irc_> <@a​damgreig:m​> but you can't then store RESOURCE into it
<re_irc_> <@a​damgreig:m​> error[E0621]: explicit lifetime required in the type of `RESOURCE`
<re_irc_> <@a​damgreig:m​> --> src/
<re_irc_> <@a​damgreig:m​> 150 | #[interrupt]
<re_irc_> <@a​damgreig:m​> |
<re_irc_> <@a​damgreig:m​> I mean, it gives you `&Option<&'static mut u32>>`, so when you `*STORAGE.borrow(cs)` you get the Option, which contains the &mut
<re_irc_> <@t​halesfragoso:m​> Dont you need RefCell anyway ?
<re_irc_> <@j​amesmunns:m​> use cortex_m::interrupt::{Mutex, free};
<re_irc_> <@j​amesmunns:m​> ```rust
<re_irc_> <@j​amesmunns:m​> static STORAGE: Mutex<RefCell<Option<&'static mut u32>>> = ::cortex_m::interrupt::Mutex::new(RefCell::new(None));
<re_irc_> <@j​amesmunns:m​> use core::cell::RefCell;
<re_irc_> <@j​amesmunns:m​> yeah, the created static refs aren't static
<re_irc_> <@j​amesmunns:m​> err, created mut refs aren't static
<re_irc_> <@a​damgreig:m​> what I don't understand is why they were in thalesfragoso's original non-cortex-m example
<re_irc_> <@j​amesmunns:m​> he was using unsafe
<re_irc_> <@j​amesmunns:m​> to simulate what cortex-m does
<re_irc_> <@a​damgreig:m​> so? unsafe doesn't let you ignore lifetimes?
<re_irc_> <@t​halesfragoso:m​> Cortex-M also uses unsafe
<re_irc_> <@j​amesmunns:m​> no, but static muts are also a footgun
<re_irc_> <@j​amesmunns:m​> and you can easily get multiple live &'static mut refs from them
<re_irc_> <@a​damgreig:m​> c-m-rt does:
<re_irc_> <@j​amesmunns:m​> I am suggesting that his simulation was not accurate enough to demonstrate what c-m[-rt] actually does
<re_irc_> <@j​amesmunns:m​> hold on, cargo-expanding
<re_irc_> <@a​damgreig:m​> hah, yea, same
<re_irc_> <@t​halesfragoso:m​> How does the ref survive the { } if isn't 'static, hmm
<re_irc_> <@t​halesfragoso:m​> I mean, it could survive and then get shrink, but why
<re_irc_> <@a​damgreig:m​> ah
<re_irc_> <@a​damgreig:m​> yes that's it
<re_irc_> <@a​damgreig:m​> you're missing a level of indirection
<re_irc_> <@j​amesmunns:m​> ```rust
<re_irc_> <@j​amesmunns:m​> use cortex_m::interrupt::{free, Mutex};
<re_irc_> <@j​amesmunns:m​> use core::cell::RefCell;
<re_irc_> <@j​amesmunns:m​> static STORAGE: Mutex<RefCell<Option<&'static mut u32>>> =
<re_irc_> <@a​damgreig:m​> c-m-rt creates a trampoline for the ISR which has the static mut and creates the &mut
<re_irc_> <@a​damgreig:m​> then it passes those to the actual ISR function, which takes &mut (not 'static')
<re_irc_> <@t​halesfragoso:m​> Oh, yeah, the trampoline
<re_irc_> <@a​damgreig:m​> so by the time the user's code gets the &mut, it's not 'static, so can't be stashed away
<re_irc_> <@t​halesfragoso:m​> How about entry ?
<re_irc_> <@a​damgreig:m​> same deal
<re_irc_> <@t​halesfragoso:m​> But entry is fine either eay
<re_irc_> <@t​halesfragoso:m​> Well played, thanks
<re_irc_> <@t​halesfragoso:m​> Glad to be wrong on this one
<re_irc_> <@a​damgreig:m​> yea...
<re_irc_> <@a​damgreig:m​> I mean I still think we should get rid of this feature
<re_irc_> <@a​damgreig:m​> it seems like a tactical nuke aimed at your feet for the purposes of warming them up a bit, and maybe you could just wear socks
<re_irc_> <@a​damgreig:m​> but so far it does seem resistant to suggestions that it's unsound
<re_irc_> <@j​amesmunns:m​> or rather, we've iterated a lot of the unsoundness away over time :D
<re_irc_> <@j​amesmunns:m​> I don't think it was always so resilient
<re_irc_> <@a​damgreig:m​> heh
<re_irc_> <@j​amesmunns:m​> (and the current code points out the easily-footgunnable-nature of `static mut`)
<re_irc_> <@t​halesfragoso:m​> Does the second function get the same attributes from the first ?
<re_irc_> <@t​halesfragoso:m​> Otherwise it would be bad if you want to place them in RAM
<re_irc_> <@a​damgreig:m​> I wonder if this was an accident, even, because we used to generate randomised idents and then swapped to trampolines to remove the need for random generation in build (due to cargo feature unification)
<re_irc_> <@a​damgreig:m​> yea, it copies permitted attributes over
<re_irc_> <@t​halesfragoso:m​> Nice
<re_irc_> <@t​halesfragoso:m​> adamgreig: Yeah, now I remember it
<re_irc_> <@a​damgreig:m​> lol, yea, looking at the commit that changed it
<re_irc_> <@a​damgreig:m​> it sure looks like you would have been able to do your unsoundness before that
<re_irc_> <@a​damgreig:m​> and I don't think that was a reason for the change at the time
<re_irc_> <@j​amesmunns:m​> hmm
<re_irc_> <@j​amesmunns:m​> like I said, I vaguely remember talking about this problem before
<re_irc_> <@j​amesmunns:m​> but I have no proof of that
<re_irc_> <@j​amesmunns:m​> might have been after the switch already
<re_irc_> <@a​damgreig:m​> previously it emitted `let #ident: &mut #ty = unsafe { static mut #ident: #ty = #expr; &mut #ident};`
<re_irc_> <@j​amesmunns:m​> (and my memory is admittedly bad)
<re_irc_> <@a​damgreig:m​> but perhaps that's OK, because the top type annotation is non-'static
<re_irc_> <@a​damgreig:m​> no, looks like it would have had an implicit 'static in that case
<re_irc_> <@a​damgreig:m​> so it would have been bad
<re_irc_> <@a​damgreig:m​> switch was back in nov 2019, so, dunno
<re_irc_> <@a​damgreig:m​> jonas did it, might be the person to ask
<re_irc_> <@a​damgreig:m​> jamesmunns: if I just want to push single bits of data at a time, in this case a command (u8) from the IR decoder interrupt into the main loop, is bbqueue still sensible (given i don't care for contiguous blocks of memory or anything)?
<re_irc_> <@a​damgreig:m​> could practically just use an AtomicU8 and keep 0 as a sentinal value but in theory you could drop commands that way
<re_irc_> <@t​halesfragoso:m​> Is it a stream or a block ?
<re_irc_> <@j​amesmunns:m​> If you have an explicit push of a single item, heapless is probably better
<re_irc_> <@j​amesmunns:m​> if you have dma filling a block, probably bbqueue
<re_irc_> <@a​damgreig:m​> ah of course, I forgot heapless had a queue
<re_irc_> <@a​damgreig:m​> thanks
<re_irc_> <@a​damgreig:m​> now to get the producer half into the interrupt, lol
<re_irc_> <@j​amesmunns:m​> Honestly, RTIC?
<re_irc_> <@a​damgreig:m​> yea, probably should
<re_irc_> <@j​amesmunns:m​> I mean irq and cmim are great
<re_irc_> <@j​amesmunns:m​> but rtic is such a no brainer
<re_irc_> <@h​enrik_alser:m​> Yeah it’s all built in
<re_irc_> <@j​amesmunns:m​> as soon as I add an interrupt instead of just a main loop, I've already moved over to rtic
<re_irc_> <@j​amesmunns:m​> just because I never remember the "option refcell dance", as you saw above :D
<re_irc_> <@a​damgreig:m​> (I do use rtic on other projects, just yea, this started last night and this is the first interrupt)
<re_irc_> <@j​amesmunns:m​> I literally don't even remember how to use `free` lol
<re_irc_> <@j​amesmunns:m​> (for reference, I DO think it's important the ecosystem works outside of RTIC, because who knows if there will be something better in the future, or different options like Embassy, but for now, I do use rtic in roughly 100% of my personal and professional projects)
<re_irc_> <@j​amesmunns:m​> Ferrous really needs an `app-template-rtic`
<re_irc_> <@j​amesmunns:m​> because knurling's `app-template` is also 100% how I start every new embedded project these days.
<re_irc_> <@j​amesmunns:m​> cargo generate \
<re_irc_> <@j​amesmunns:m​> --git \
<re_irc_> <@j​amesmunns:m​> --branch main \
<re_irc_> <@j​amesmunns:m​> --name WHATEVER
<re_irc_> <@j​amesmunns:m​> Is in my `ctrl-r` history forever
<re_irc_> <@a​damgreig:m​> shame the template can't specify the --branch (?)
<re_irc_> <@a​damgreig:m​> or is that just for cargo-generate to know what to fetch?
<re_irc_> <@d​irbaio:m​> Can you put non-Send things in the CMRT resources?
<re_irc_> <@d​irbaio:m​> If so you can abuse the resources to send non-Send things to different priority levels
<re_irc_> <@a​damgreig:m​> how?
<re_irc_> <@d​irbaio:m​> By changing the irq prio level
<re_irc_> <@a​damgreig:m​> but how do they get in/out?
<re_irc_> <@d​irbaio:m​> Set prio 1, trigger the irq
<re_irc_> <@d​irbaio:m​> Irq creates a non-Send thing and puts it in an option resource
<re_irc_> <@d​irbaio:m​> Set prio 2, trigger it again
<re_irc_> <@d​irbaio:m​> Irq uses the thing it stored before, now from a different prio level
<re_irc_> <@a​damgreig:m​> couldn't you already do that using a Mutex and CriticalSection?
<re_irc_> <@d​irbaio:m​> No because the mutex requires contents to be send
<re_irc_> <@t​halesfragoso:m​> But can you create problems with that ?
<re_irc_> <@t​halesfragoso:m​> You can re-enter the interrupt
<re_irc_> <@t​halesfragoso:m​> Can't*
<re_irc_> <@a​damgreig:m​> hm, or at least the mutex is only Sync if T is Send
<re_irc_> <@t​halesfragoso:m​> You can only place Sync stuff in static, so yes, Mutex kinda requires Send
<re_irc_> <@a​damgreig:m​> yea
<re_irc_> <@t​halesfragoso:m​> Now the question, can you place anything on a static Mut ?
<re_irc_> <@t​halesfragoso:m​> Or just Sync stuff ?
<re_irc_> <@a​damgreig:m​> oh, inside the interrupt? yea
<re_irc_> <@t​halesfragoso:m​> Or anywhere
<re_irc_> <@a​damgreig:m​> doesn't matter if it's global because then you'd still need unsafe to access it
<re_irc_> <@t​halesfragoso:m​> someone that's not in a phone, put a UnsafeCell on a static mut
<re_irc_> <@t​halesfragoso:m​> Wait, we place non-Send futures in statics, right ?
<re_irc_> <@t​halesfragoso:m​> Or we wrapped them ?
<re_irc_> <@d​irbaio:m​> Embassy puts non-Send futures on statics yeah
<re_irc_> <@d​irbaio:m​> Task has unsafe impl Send+Sync
<re_irc_> <@t​halesfragoso:m​> Ah, knew it
<re_irc_> <@d​irbaio:m​> But then the executor ensures the future is only ever polled from the same prio level
<re_irc_> <@d​irbaio:m​> Once you spawn a task it gets "locked" to the current prio level
<re_irc_> <@d​irbaio:m​> So it should be OK
<re_irc_> <@d​irbaio:m​> It's not sending non-Send things
<re_irc_> <@t​halesfragoso:m​> Yeah, how about UnsafeCell on static mut ?
<re_irc_> <@a​damgreig:m​> isn't UnsafeCell Send?
<re_irc_> <@a​damgreig:m​> struct NotSend(u8);
<re_irc_> <@a​damgreig:m​> ```rust
<re_irc_> <@a​damgreig:m​> #[interrupt]
<re_irc_> <@a​damgreig:m​> impl !Send for NotSend {}
<re_irc_> <@a​damgreig:m​> like that?
<re_irc_> <@d​irbaio:m​> Yeah
<re_irc_> <@a​damgreig:m​> so yea, I can't put that NotSend into a Mutex because it's not Send and so the Mutex isn't Sync and so won't live in a `static mut`
<re_irc_> <@a​damgreig:m​> but I _can_ put it into the `static mut` inside the interrupt handler
<re_irc_> <@t​halesfragoso:m​> I meant not Sync, sorry, yeah UnsafeCell is send
<re_irc_> <@t​halesfragoso:m​> But not sync
<re_irc_> <@a​damgreig:m​> however if I `impl !Sync for NotSend {}`, I'm _still_ allowed to use it inside the interrupt handler, huh?
<re_irc_> <@a​damgreig:m​> I can also just have a global `static mut X: NotSend = NotSend(0)` despite an `impl !Sync for NotSend` :/
<re_irc_> <@t​halesfragoso:m​> The theoretical problem is that changing the interrupt priority is kinda the same of sending stuff across threads
<re_irc_> <@a​damgreig:m​> is it?
<re_irc_> <@t​halesfragoso:m​> But I'm not sure if it can cause a practical problem in our case, maybe
<re_irc_> <@a​damgreig:m​> I guess in a sense each priority level plus the main thread counts as a thread of execution since they can pre-empt each other
<re_irc_> <@a​damgreig:m​> so it's not only "interrupt context" and "thread context"
<re_irc_> <@a​damgreig:m​> but since it's inside the same ISR, it can't ever pre-empt itself
<re_irc_> <@t​halesfragoso:m​> But maybe you can clone and move it out
<re_irc_> <@t​halesfragoso:m​> Like an Arc
<re_irc_> <@t​halesfragoso:m​> Of better, a Rc somehow
<re_irc_> <@a​damgreig:m​> because the &mut to it is Send?
<re_irc_> <@t​halesfragoso:m​> If you somehow have 2 !Send stuff at the same priority level, you might think that's okay, like two Rcs to be same data
<re_irc_> <@t​halesfragoso:m​> But then if you change the priority level then is not okay anymore
<re_irc_> <@a​damgreig:m​> if you can get it out so that two interrupt handlers at two priority levels both have access to the same !Send thing, I can see the problem
<re_irc_> <@a​damgreig:m​> and I can see how you can end up using the same !Send thing from one interrupt handler at two consecutively different priorities
<re_irc_> <@a​damgreig:m​> but I don't know how you get the !Send thing into two different interrupt handlers to begin with
<re_irc_> <@a​damgreig:m​> (irregardless of their priority level)
<re_irc_> <@a​damgreig:m​> except by using something that synchronises them, I guess?
<re_irc_> <@t​halesfragoso:m​> Unsafe, probably
<re_irc_> <@a​damgreig:m​> right, in which case it's not a problem
<re_irc_> <@t​halesfragoso:m​> But it would be a okay unsafe
<re_irc_> <@a​damgreig:m​> clearly not :P
<re_irc_> <@a​damgreig:m​> but perhaps a very surprisingly not-ok unsafe
<re_irc_> <@t​halesfragoso:m​> Hmmm, dirbaio might have some more ideas on how that could happen
<re_irc_> <@a​damgreig:m​> yea, I think a concrete example would be easier here, i'm getting lost in all the arcs and so on
<re_irc_> <@d​irbaio:m​> Yeah I think for it to be unsound it needs to be combined more things
<re_irc_> <@d​irbaio:m​> For example a "PrioMutex" that let's you access the contents only if current prio level = X
<re_irc_> <@a​damgreig:m​> yea, those sorts of platform-level assumptions about behaviour are where this all gets super tricky
<re_irc_> <@a​damgreig:m​> cortex-m's Mutex is basically the same
<re_irc_> <@a​damgreig:m​> "if we're in a critical section, we are OK"
<re_irc_> <@a​damgreig:m​> (but therefore, it must be unsafe everywhere to enable interrupts, unmask interrupts, and don't think too hard about hardfault and nmi)
<re_irc_> <@d​irbaio:m​> Well within the model of "1 prio level = 1 thread" these are all ok
<re_irc_> <@d​irbaio:m​> What's unsound is the CMRT resources
<re_irc_> <@a​damgreig:m​> only in that same model, which c-m-rt doesn't promise to subscribe to
<re_irc_> <@a​damgreig:m​> the same way I could release a crate that safely exposes "enable interrupts", and it be OK because it's not the law that enabling interrupts is unsafe, it's just convenient for cortex-m's life that doing so means mutex can work
<re_irc_> <@a​damgreig:m​> but if you use my hypothetical crate alongside cortex-m, and enable interrupts inside a CS, you get unsoundness
<re_irc_> <@d​irbaio:m​> Uuuuh, what other model would there be?
<re_irc_> <@a​damgreig:m​> my point is that the soundness depends on the preconditions each crate has for the safe abstractions it provides
<re_irc_> <@a​damgreig:m​> like how cortex-m's are broken on multi-core
<re_irc_> <@a​damgreig:m​> c-m-rt doesn't know about priority levels at all iirc
<re_irc_> <@a​damgreig:m​> if your PriorityMux provides a safe API but requires that you can't Send things between priority levels, that's a precondition it makes (and perhaps therefore makes it unsuitable for use alongside c-m-rt?)
<re_irc_> <@a​damgreig:m​> but I'm not sure it would be fair to say c-m-rt was unsound in that case
<re_irc_> <@d​irbaio:m​> Hmm
<re_irc_> <@a​damgreig:m​> (not saying that such a precondition isn't reasonable or perhaps even desirable, but it's not written down anywhere)
<re_irc_> <@d​irbaio:m​> Aiui The One True Model is "1 prio level = 1 thread"
<re_irc_> <@d​irbaio:m​> Therefore "you shall not send non-Send things across prio levels"
<re_irc_> <@d​irbaio:m​> And crates hace these preconditions where they only uphold the model if they are met
<re_irc_> <@d​irbaio:m​> Eg the multicore stuff
<re_irc_> <@a​damgreig:m​> not saying that's unreasonable but also I don't think I've seen anyone state it like that before and I don't think it's written anywhere in e.g. c-m or c-m-rt
<re_irc_> <@a​damgreig:m​> so you see what I mean that it's well and good for that to be your model, but it doesn't mean c-m-rt is unsound just because your other crate has assumptions that c-m-rt doesn't share
<re_irc_> <@a​damgreig:m​> (obviously this is a larger scale problem; on hosted platforms the OS provides these assumptions and so everyone's platform assumptions can match; on bare metal platforms it's trickier?)
<re_irc_> <@a​damgreig:m​> (I don't know if Arm have a meaningful spec or definition we could use... but probably not since the interaction with Send and Sync will be the main things)
<re_irc_> <@a​damgreig:m​> (certainly "what do Send and Sync mean in an embedded context" has been a topic of rigorous debate for years)
<re_irc_> <@d​irbaio:m​> Hm, I see it as a logical conclusion of
<re_irc_> <@d​irbaio:m​> 1. The assumptions rust code does about send etc
<re_irc_> <@d​irbaio:m​> 2. How the arm architecture works
Lumpio_ is now known as Lumpio-
<re_irc_> <@t​hejpster:m​> Hmm. Trying rtic for the first time today. It's going .... OK?
<re_irc_> <@t​hejpster:m​> I made a thing that compiles, but drops into the Default Handler.
<re_irc_> <@a​damgreig:m​> is your code up anywhere?
<re_irc_> <@a​damgreig:m​> what value are you getting when it panics in the defaulthandler?
<re_irc_> <@t​hejpster:m​> -16
<re_irc_> <@t​hejpster:m​> And I can't find anything that says that that is, as the exceptions only seems to go up to 16
<re_irc_> <@t​hejpster:m​> Finished release [optimized + debuginfo] target(s) in 1.47s
<re_irc_> <@t​hejpster:m​> Running `probe-run --chip STM32F031K6Tx target/thumbv6m-none-eabi/release/neotron-bmc`
<re_irc_> <@t​hejpster:m​> (HOST) INFO flashing program (6.89 KiB)
<re_irc_> <@t​hejpster:m​> (HOST) INFO success!
<re_irc_> <@t​hejpster:m​> I've previously eyed rtic with suspicion as a big ball of magic. But I thought it was time to be brave and poke it a bit.
<re_irc_> <@a​damgreig:m​> it looks like you're hitting a hardfault here
<re_irc_> <@t​hejpster:m​> I immediately ballsed it up and fell into a big ball of magic.
<re_irc_> <@a​damgreig:m​> hah
<re_irc_> <@t​hejpster:m​> THe hardfault is the UDF in the panic handler.
<re_irc_> <@a​damgreig:m​> ah
<re_irc_> <@t​hejpster:m​> It seems that as soon as it calls `c_m::interrupt::enable` it jumps into DefaultHandler.
<re_irc_> <@a​damgreig:m​> that's very weird. -16 means it wasn't executing an interrupt/exception at that time.
<re_irc_> <@a​damgreig:m​> (i.e. that it read 0 from VECTACTIVE, so was in thread mode)
<re_irc_> <@t​hejpster:m​> Do I need a feature or something to use it on an M0.
<re_irc_> <@a​damgreig:m​> shouldn't do, no...
<re_irc_> <@d​irbaio:m​> I think vectactive doesn't work on m0?
<re_irc_> <@a​damgreig:m​> huh, CM0 manual describes it as normal
<re_irc_> <@d​irbaio:m​> uh
<re_irc_> <@d​irbaio:m​> `DefaultHandler(-16)` doesn't make sense
<re_irc_> <@d​irbaio:m​> DefaultHandler can't run in thread mode, can it?
<re_irc_> <@a​damgreig:m​> indeed
<re_irc_> <@t​hejpster:m​> thalesfragoso figured it out. No "rt" feature on the HAL crate.
<re_irc_> <@t​hejpster:m​> I feel like maybe we could detect that?
<re_irc_> <@a​damgreig:m​> I wonder how not having rt turned into DefaultHandler getting run in thread mode, lol
<re_irc_> <@a​damgreig:m​> I guess it means the USB interrupt that RTIC wants to use wasn't loaded into the vector table, instead DefaultHandler was
<re_irc_> <@a​damgreig:m​> but RTIC pending USB should give you the USB IRQ number in the panic I would have thought
<re_irc_> <@t​hejpster:m​> Hmm. More weirdness. I get into the blinker task (now `led_status_blink`) exactly once. Scheduling it to be called again does nothing. Does the `monotonic` counter need to set interrupts or does RTIC deal with that?
<re_irc_> <@t​halesfragoso:m​> M0 doesn't have the default monotic, no ?
<re_irc_> <@t​halesfragoso:m​> oh, you have one
<re_irc_> <@t​hejpster:m​> correct, I stole one from the STM32L0 example, which uses Timer 6.
<re_irc_> <@t​halesfragoso:m​> you probably need to trigger an update event to use the new prescaler
<re_irc_> <@a​damgreig:m​> yea, `timer.egr.write(|w|;` after settign prescaler
<re_irc_> <@a​damgreig:m​> though it should just be running super faster otherwise, hm
<re_irc_> <@t​hejpster:m​> Adding that egr didn't help
<re_irc_> <@t​hejpster:m​> Ah, my timer isn't ticking
<re_irc_> <@t​hejpster:m​> fn idle(_: idle::Context) -> ! {
<re_irc_> <@t​hejpster:m​> defmt::info!("Idle is running...")
<re_irc_> <@t​hejpster:m​> cortex_m::asm::wfi();
<re_irc_> <@t​hejpster:m​> loop {
<re_irc_> <@t​hejpster:m​> 27 INFO It is now 0
<re_irc_> <@t​hejpster:m​> 28 INFO It is now 0
<re_irc_> <@t​hejpster:m​> └─ neotron_bmc::idle @ src/
<re_irc_> <@t​hejpster:m​> └─ neotron_bmc::idle @ src/
<re_irc_> <@t​halesfragoso:m​> maybe set ARR too ?
<re_irc_> <@a​damgreig:m​> what's waking it from each wfi() sleep?
<re_irc_> <@t​halesfragoso:m​> to u16::MAX
<re_irc_> <@a​damgreig:m​> if you're upcounting you want ARR to be 0, right?
<re_irc_> <@a​damgreig:m​> hmmmm
<re_irc_> <@t​halesfragoso:m​> I think max
<re_irc_> <@t​halesfragoso:m​> set it before triggering the update though
<re_irc_> <@a​damgreig:m​> yea
<re_irc_> <@a​damgreig:m​> "The counter is blocked while the auto-reload value is null."
<re_irc_> <@t​halesfragoso:m​> it was counting from 0 to 0, heh
<re_irc_> <@t​hejpster:m​> Uhhh. I don't think my F031K6T has a TIM6?
<re_irc_> <@t​halesfragoso:m​> shouldn't the pac know that ?
<re_irc_> <@t​hejpster:m​> Well that's what I'd have thought
<re_irc_> <@t​hejpster:m​> I've switched to TIM3 and it's fine
<re_irc_> <@t​halesfragoso:m​> TIM6 is basic timer, so maybe it has it
<re_irc_> <@t​halesfragoso:m​> hmm, okay
<re_irc_> <@t​hejpster:m​> The HAL timer source ( says it's behind a feature gate
<re_irc_> <@a​damgreig:m​> TIM6/TIM7 are only F05x, F07x, F09x
<re_irc_> <@a​damgreig:m​> hmm
<re_irc_> <@t​hejpster:m​> But I was using the PAC
<re_irc_> <@a​damgreig:m​> ah, but the PAC granularity is F0x0, F0x1, F0x2, F0x8
<re_irc_> <@a​damgreig:m​> so an F031 uses the same feature as an F051, and the F051 does have the TIM6
<re_irc_> <@a​damgreig:m​> thanks ST
<re_irc_> <@t​hejpster:m​> TIM6 is not behind a gate in the PAC
<re_irc_> <@t​hejpster:m​> Ah
<re_irc_> <@a​damgreig:m​> I don't fully understand the ARR thing: I'm also using (on an F4) a timer from 0 to max and haven't programmed ARR and it works fine, despite the RM saying "timer blocked when ARR is null"
<re_irc_> <@t​hejpster:m​> ffs
<re_irc_> <@t​hejpster:m​> These chips are almost, but not quite, entirely unlike each other.
<re_irc_> <@a​damgreig:m​> works fine if I program ARR to all-1s too though, so that's odd. maybe it does something special when upcounting and arr is 0 :/
<re_irc_> <@t​hejpster:m​> thanks all
<re_irc_> <@a​damgreig:m​> hm, I see, the ARR register has a reset value of 0xFFFF (or 0xFFFF_FFFF for 32-bit)
<re_irc_> <@a​damgreig:m​> but the RM documents it as being 0
<re_irc_> <@a​damgreig:m​> that's sneaky
<re_irc_> <@t​halesfragoso:m​> adamgreig: maybe default is 0xFFFF ?
<re_irc_> <@a​damgreig:m​> the SVD agrees with the RM in thinking that its reset value is 0
<re_irc_> <@a​damgreig:m​> hmmm
<re_irc_> <@a​damgreig:m​> yea, even if I write some random value to ARR, pulsing APB1RSTR brings it back to FFFF
<re_irc_> <@a​damgreig:m​> so it really is FFFF as a reset value, and all the RMs are lying, cool
<re_irc_> <@t​halesfragoso:m​> F407 isn't, at least
<re_irc_> <@t​halesfragoso:m​> nor F030...
<re_irc_> <@a​damgreig:m​> isn't what?
<re_irc_> <@a​damgreig:m​> guess I should test on more things but now searching the internet for it, a lot of people seem to also be relying on/assuming that ARR will reset to FFFF, including a comment in an ST document
<re_irc_> <@a​damgreig:m​> it certainly does on the F411 in any event
<re_irc_> <@t​halesfragoso:m​> adamgreig: The RM isn't lying on the reset value here
<re_irc_> <@t​halesfragoso:m​> checked just two of them though
<re_irc_> <@a​damgreig:m​> ah, interesting! yep, RM0090 says FFFF
<re_irc_> <@a​damgreig:m​> and RM0091 for the F0 too
<re_irc_> <@a​damgreig:m​> but RM0383 for the F411 says 0 and the SVDs agree with it, weird
<re_irc_> <@a​damgreig:m​> time to download a new version of RM0383...
<re_irc_> <@t​halesfragoso:m​> RM0383 here for TIM1 says 0xFF
<re_irc_> <@t​halesfragoso:m​> 0xFFFF*
<re_irc_> <@a​damgreig:m​> yep, looks like it was just a mistake in this old version of RM0383
<re_irc_> <@a​damgreig:m​> well, mystery solved, lol
<re_irc_> <@a​damgreig:m​> well, that will teach me to check if there's a new version of the RM! thanks for checking
<re_irc_> <@f​irefrommoonlight:m​> Sneaky
fabic has quit [Remote host closed the connection]
<re_irc_> <@j​amesmunns:m​> dirbaio: I'm still catching up on chat history, but this is what the `cmim` crate does
<re_irc_> <@j​amesmunns:m​> Like, literally, it only checks your expected vectactive is correct
<re_irc_> <@j​amesmunns:m​>
<re_irc_> <@f​irefrommoonlight:m​> To any cortex-m HAL maintainers: It's worth looking at cortex-m's stick Delay implementation, and deciding if you want to remove the HAL's delay in favor of it. I just did this
<re_irc_> <@j​amesmunns:m​> And the data is initialized, I guess
<re_irc_> <@f​irefrommoonlight:m​> The main justification is reduced cross-lib DRY
<re_irc_> <@f​irefrommoonlight:m​> It should be a drop-in replacement
<re_irc_> <@f​irefrommoonlight:m​> (depending on how you're passing in the systick speed(
<re_irc_> <@a​damgreig:m​> jamesmunns: That's not the same as checking priority though right?
<re_irc_> <@j​amesmunns:m​> That's true
<re_irc_> <@j​amesmunns:m​> It only cares about the specific vector, not level
<re_irc_> <@j​amesmunns:m​> But that's even more strict imo
<re_irc_> <@d​irbaio:m​> it'd have the same problemas as CMRT resources
<re_irc_> <@d​irbaio:m​> except it requires T: Send
<re_irc_> <@a​damgreig:m​> i thought the issue would just let you move things that were Send between priority levels, not between interrupt handlers, though?
<re_irc_> <@a​damgreig:m​> oh, you mean that cmim would also have this issue
<re_irc_> <@a​damgreig:m​> but if it requires T:Send then no problem right?
<re_irc_> <@d​irbaio:m​> the issue is sending non-Send things to a different priority level
<re_irc_> <@d​irbaio:m​> it requires Send so yeah that's OK
<re_irc_> <@d​irbaio:m​> CMRT isn't
<re_irc_> <@a​damgreig:m​> do you think there's any use cases for putting non-Send things into an interrupt handler's resources?
<re_irc_> <@a​damgreig:m​> wonder how to even bound that in the macro. I guess you could call a dummy function that requires T:Send or something.
<re_irc_> <@d​irbaio:m​> there are usecases yeah
<re_irc_> <@d​irbaio:m​> a "dummy async executor" that polls a future on irq fire
<re_irc_> <@d​irbaio:m​> and "owns" the future, so the future can be non-Send
<re_irc_> <@j​amesmunns:m​> I'll reread the full history when I'm back at my pc
<re_irc_> <@j​amesmunns:m​> But yeah, cassette also requires Send iirc for that reason
<re_irc_> <@d​irbaio:m​> why not just remove the resources in CMRT?
<re_irc_> <@d​irbaio:m​> it's not RTIC
<re_irc_> <@d​irbaio:m​> if you want resources, go and use RTIC which is much more powerful
<re_irc_> <@d​irbaio:m​> btw RTIC is also unsound if you manually change irq prio levels right?
<re_irc_> <@a​damgreig:m​> hmmm
<re_irc_> <@a​damgreig:m​> can you actually change priority level in safe code?
<re_irc_> <@a​damgreig:m​> cortex-m's NVIC::set_priority is unsafe "Changing priority levels can break priority-based critical sections (see register::basepri) and compromise memory safety."
<re_irc_> <@d​irbaio:m​> ahhhh
<re_irc_> <@d​irbaio:m​> then maybe we can say CMRT resources are OK because you need unsafe to break them? 🤣
<re_irc_> <@a​damgreig:m​> yea, I think that ends up being reasonable
<re_irc_> <@a​damgreig:m​> I mean like I said we could also remove them entirely and users can just put their one unsafe line in if they want them without rtic or whatever
<re_irc_> <@d​irbaio:m​> yeah
<re_irc_> <@d​irbaio:m​> the "porcelain vs plumbing" thing
<re_irc_> <@a​damgreig:m​> I'm a little hesitant to do so without--- yea
<re_irc_> <@a​damgreig:m​> it would seem a bit shit to just cut them out of c-m-rt for its own sake, unless we do actually find an unsoundness issue
<re_irc_> <@a​damgreig:m​> but definitely as part of that larger effort it would make sense to relocate such a thing
<re_irc_> <@d​irbaio:m​> wasn't there some talk about removing it already?
<re_irc_> <@a​damgreig:m​> I thought that might have been part of jonas' big changes to those macros but I guess it wasn't
<re_irc_> <@d​irbaio:m​>
<re_irc_> <@a​damgreig:m​> (amusingly you commented on that pr back in feb, lol)
<re_irc_> <@d​irbaio:m​> yeah it's all I can find
<re_irc_> <@d​irbaio:m​> oooh yeah 🤣
<re_irc_> <@d​irbaio:m​> actually resources on DefaultHandler are actually unsound
<re_irc_> <@d​irbaio:m​> unless all irqs without a defined handler are ALL at the same prio
<re_irc_> <@a​damgreig:m​> hmmmmm
<re_irc_> <@d​irbaio:m​> maybe teeeeechnically you could say it's not becaues on boot they're all at the same prio and you'd need to call set_priority which is unsafe to break that
<re_irc_> <@a​damgreig:m​> I mean they will be unless the user unsafely sets the priority
<re_irc_> <@a​damgreig:m​> yea
<re_irc_> <@d​irbaio:m​> 🤣
<re_irc_> <@d​irbaio:m​> but then
<re_irc_> <@d​irbaio:m​> what are the safety invariants of set_priority? they're super complex
<re_irc_> <@d​irbaio:m​> also is it really CM's job to outline these invariants if it's an entirely unrelated crate (CMRT) that requires them?
<re_irc_> <@a​damgreig:m​> meh, more or less the same deal as enabling or unmasking interrupts though, right?
<re_irc_> <@d​irbaio:m​> dunno
<re_irc_> <@a​damgreig:m​> unmasking an interrupt is fine... unless some other crate is relying on you not doing that for its own safety
<re_irc_> <@d​irbaio:m​> to me CM saying "you may not set_priority safely because OTHER crates out there may be doing assumptions" is weird
<re_irc_> <@d​irbaio:m​> it should be the other crate that has unsafe telling you "don't manually enable/disable the irq!"
<re_irc_> <@a​damgreig:m​> pretty tough set of operating conditions if other crates have to assume any irq might change priority at any time and without it knowing about it
<re_irc_> <@f​irefrommoonlight:m​> RTIC seems is very popular in Rust embedded. It seems there's a C framework called RTFM (lol) that is a similar concept. From what I gather, it's used by a small portion of C embedded code. Why do y'all think this approach is comparatively popular with Rust?
<re_irc_> <@a​damgreig:m​> RTFM is the old name for RTIC
<re_irc_> <@a​damgreig:m​> and it started as a C++ project and later ported to Rust
<re_irc_> <@a​damgreig:m​> people are used to RTOSs in C and there aren't any really in Rust, is probably why the comparative popularity
<re_irc_> <@d​irbaio:m​> rtic is more attractive to Rust users than C users because in C loooooots of stuff is unsafe, so who cares if one more thing is
<re_irc_> <@f​irefrommoonlight:m​> That explanation makes perfect sense. I do read a lot about RTOS on C/++
<re_irc_> <@f​irefrommoonlight:m​> Re unsafe: I agree that it's not obvious how to share info between interrupts safely, and the naive implementations are verbose. But there are workflows that are safe and concise
<re_irc_> <@f​irefrommoonlight:m​> Still a point for RTIC though
<re_irc_> <@g​rantm11235:m​> Would this (or something like it) solve our async dma problems?
<re_irc_> <@t​halesfragoso:m​> GrantM11235: what would happen if someone mem::forget a run to complete future ?
<re_irc_> <@d​khayes117:m​> I'm curious, what are the instuctions in the probe-rs flash algorithms?
<re_irc_> <@w​illeml:m​> Anyone here got experience with memory mapped QSPI storage? (enabling memory mapped mode)
<re_irc_> <@w​illeml:m​> Because attempting to read from where it should be mapped to (0x09000000) causes a crash
<re_irc_> <@a​damgreig:m​> dkhayes117: They're mostly prebuilt assembly snippets from the device manufacturers, which implement a standard Arm API so a debugger knows "load this code into ram, then load arguments into these registers, then execute it" to do "program this page" or whatever
<re_irc_> <@a​damgreig:m​> Totally possible to make them yourself and people have for specific chips where the manufacturer ones are missing or bad
<re_irc_> <@w​illeml:m​> willeml: actually, pretty sure I just missed the mpu init step for this
<re_irc_> <@d​khayes117:m​> adamgreig: It doesn't look like assembly, is it hashed or something?
<re_irc_> <@a​damgreig:m​> It's the compiled machine code, so binary, and then base64 encoded to a string to store in yaml
<re_irc_> <@a​damgreig:m​> (going off memory for that base64 bit but I believe it is...)
<re_irc_> <@a​damgreig:m​> You could base64 -d to decode them into a .bin file and open it with a disassembler to see the actual instructions
<re_irc_> <@d​khayes117:m​> adamgreig: Neat. Thanks!
<re_irc_> <@a​damgreig:m​> I should say it's "assembled" rather than "compiled" though I bet a lot of them are written in C anyway
<re_irc_> <@a​damgreig:m​> (people have also written them in Rust!)
<re_irc_> <@j​amesmunns:m​> adamgreig: This process seems bizarre, but I can also understand why the did it this way
<re_irc_> <@a​damgreig:m​> adamgreig:
<re_irc_> <@j​amesmunns:m​> Like, "this seems like a bin file with more steps"
<re_irc_> <@a​damgreig:m​> Gotta store the bin files in a text file though
<re_irc_> <@j​amesmunns:m​> But I also don't know how much other metadata is in that yaml
<re_irc_> <@a​damgreig:m​> There's a load of them for every chip and loads of chips per yaml file
<re_irc_> <@j​amesmunns:m​> That's just a tar file with more steps!
<re_irc_> <@a​damgreig:m​> (well they're usually shared between lots of chips)
<re_irc_> <@a​damgreig:m​> Hah I guess so
<re_irc_> <@a​damgreig:m​> It's not like anyone's loading them from bin files though
<re_irc_> <@j​amesmunns:m​> *sigh*
<re_irc_> <@j​amesmunns:m​> "we have two very related tools and storage processes, but we will write them without any concern for composing the common parts"
<re_irc_> <@j​amesmunns:m​> Ahhhh
<re_irc_> <@j​amesmunns:m​> Nevermind, I didn't realize it was like 100 chips to 3 algos
<re_irc_> <@j​amesmunns:m​> Am uninformed, please disregard :/
<re_irc_> <@j​amesmunns:m​> I also was imagining much larger binary content :p, how compact are those in bytes? They seem tiny!
<re_irc_> <@f​irefrommoonlight:m​> willeml: I'm going to tackle that over the next few days
<re_irc_> <@f​irefrommoonlight:m​> But haven't tried yet
<re_irc_> <@w​illeml:m​> firefrommoonlight: I just started on mpu init, I am pretty sure its the only thing missing, my next problem will be writing to the flash chip without interrupting program execution...
<re_irc_> <@a​damgreig:m​> jamesmunns: Yep they're super tiny! Just little loops writing the flash control registers and stuff really
tokomak has quit [Ping timeout: 250 seconds]
<re_irc_> <@y​atekii:m​> jamesmunns: tbh, initially I chose to put everything in the yaml per family because it was so much easier to get paths etc right. it would be tricky to get both right: dynamic loading and compiled in targets.
<re_irc_> <@j​amesmunns:m​> Yeah, after seeing the metadata:binary ratio, it makes way more sense
<re_irc_> <@y​atekii:m​> nowadays I am way smarter (TM) and I would try and go for a multiple file solution. I am not 100% positive tho that would be so much nicer to use :)
<re_irc_> <@j​amesmunns:m​> "thumb assembly in base64 in yaml" seems absurd out of context, but in context it's a totally reasonable solution.
<re_irc_> <@y​atekii:m​> would be an experiment. and tbh, with sequences coming up we might *have* to look for a multi file solution
<re_irc_> <@y​atekii:m​> because I am quite sure you don't want to put any script in yaml lol
<re_irc_> <@j​amesmunns:m​> :D
<re_irc_> <@j​amesmunns:m​> "github actions for your flash sequence"
<re_irc_> <@y​atekii:m​> then we end up with a similarly stupid DSL ARM based on XML :/
<re_irc_> <@y​atekii:m​> jamesmunns: kinda :D
<re_irc_> <@g​rantm11235:m​> thalesfragoso: That would violate the contract of the unsafe poll function, so it could cause undefined behavior
<re_irc_> <@y​atekii:m​> but we need to allow for way more stuff. we need to be actually turing complete etc
<re_irc_> <@j​amesmunns:m​> oof
<re_irc_> <@y​atekii:m​> but we'll do rust only extensions for starters and then look for a suitable language
<re_irc_> <@y​atekii:m​> because Python & JS bring a huge interpreter and are kinda bad on bitfiddling, lua could work but has no native uint32/64 as well. rhai would be awesome but is not really known ...
<re_irc_> <@y​atekii:m​> the list goes on :D
<re_irc_> <@j​amesmunns:m​> Yeah, I've thought the same for writing a hardware in the loop testing language
<re_irc_> <@j​amesmunns:m​> like, it feels like JUST in the middle between "I should have this all as config", and "I need a full language for this"
<re_irc_> <@j​amesmunns:m​> You might also consider something like starlark
<re_irc_> <@j​amesmunns:m​> which is a much more limited version of python, basically
<re_irc_> <@j​amesmunns:m​> I think there's a rust interpreter written by facebook or google or something?
<re_irc_> <@j​amesmunns:m​> I've also considered making a fork of rhai that can work without a heap alloc, and to be able to pre-interpret parts of it and encode it in a bitcode format which is basically postcard
<re_irc_> <@j​amesmunns:m​> or rather, heap alloc optional, but also dynamic parts of the language optional
<re_irc_> <@t​hejpster:m​> Yeah, I nearly did this too
<re_irc_> <@j​amesmunns:m​> yeah, I think I talked to you a bit about this
<re_irc_> <@t​hejpster:m​> Neotronian ended up being a bit more BASIC, a bit Lua.
<re_irc_> <@t​hejpster:m​> Simple procedural stuff is fairly easy
<re_irc_> <@t​hejpster:m​> It's structures that get complicated
<re_irc_> <@t​hejpster:m​> Or just making it all dictionaries, like Python.
<re_irc_> <@t​hejpster:m​> Then ref vs copy args. Explicit, like Rust and C? Or implicit like Python?
<re_irc_> <@t​hejpster:m​> Then I gave up.
<re_irc_> <@y​atekii:m​> jamesmunns: yes!
<re_irc_> <@y​atekii:m​> hmm I came across starlark when reading about bazel
<re_irc_> <@y​atekii:m​> and I kinda abandonned it like "why would I want an even lesser version of the abomination called python". but maye that's exactly what one wants!
<re_irc_> <@t​halesfragoso:m​> GrantM11235: I guess it's hard to me to imagine how to build a safe interface over it, the executor doing the unsafe polls can't really control if the user calls mem::forget inside an async task, but I mean, not saying there isn't a way out
<re_irc_> <@t​halesfragoso:m​> Just saying right now I can't see it
<re_irc_> <@f​irefrommoonlight:m​> thejpster: You'll be pleasantly surprised by Python's `dataclass` and `enum`
<re_irc_> <@y​atekii:m​> hmm jamesmunns starlark actually sounds like a nice fit now I think about it. known syntax, no oddities of python, rather simple. sadly the rust impl is quite limited: and requires nightly apparently
<re_irc_> <@w​illeml:m​> MPU.RNR()->setREGION(sector++);
<re_irc_> <@w​illeml:m​> int sector = 0;
<re_irc_> <@w​illeml:m​> does `sector++` equal 0 or one there (does it increment before or after passing the arg, I am pretty sure its before, but...)
<re_irc_> <@t​halesfragoso:m​> Should be 0, ++sector would be 1
<re_irc_> <@w​illeml:m​> Ohh, neat that makes sense, thank you!
<re_irc_> <@y​atekii:m​> thejpster: I rather have something more modern than BASIC related :) also, structures can be done in the simplest way possible as we do not have any perfromance needs I guess
aquijoule_ has quit [Remote host closed the connection]
<re_irc_> <@g​rantm11235:m​> thalesfragoso: BTW, I found that proposal while reading this blog post, which includes some more ideas about how must-run-to-completion futures might work
<re_irc_> <@t​halesfragoso:m​> Thanks, will take a look
richbridger has joined #rust-embedded
richbridger has quit [Remote host closed the connection]
richbridger has joined #rust-embedded
<re_irc_> <@w​illeml:m​> firefrommoonlight: let me know when you do, because I am having serious troubles getting memory mapped qspi flash to work