Guest7282 has left #rust-embedded [Error from remote client]
IlPalazzo-ojiisa has quit [Quit: Leaving.]
notgull has joined #rust-embedded
onkoe[m] has joined #rust-embedded
<onkoe[m]>
hey there! does anyone know if there's an on-going effort to get `avr-hal` working with `embedded-hal@1.0.0-r3`? i have a small library crate that i just ported to the new `embedded-hal` (since it's releasing soon), but i'd really like to test with my Arduino before i even commit + push the branch.
<onkoe[m]>
as-is, the stable version of `avr-hal` uses the old `spi` implementation. however, with the new `embedded-hal`, i need an `SpiDevice` implementation instead!
<onkoe[m]>
i have `embedded-hal-mock@0.10.0-rc.4` working just fine. however, i'd like to make sure it's all still good by testing it with real hardware :)
starblue has quit [Ping timeout: 245 seconds]
starblue has joined #rust-embedded
dreamcat4 has joined #rust-embedded
notgull has quit [Ping timeout: 260 seconds]
crabbedhaloablut has joined #rust-embedded
Guest7282 has joined #rust-embedded
lehmrob has joined #rust-embedded
samkent has joined #rust-embedded
samkent has quit [Quit: Leaving]
IlPalazzo-ojiisa has joined #rust-embedded
notgull has joined #rust-embedded
lehmrob has quit [Remote host closed the connection]
notgull has quit [Ping timeout: 260 seconds]
cr1901 has quit [Quit: Leaving]
cr1901 has joined #rust-embedded
samkent has joined #rust-embedded
samkent has quit [Ping timeout: 260 seconds]
samkent has joined #rust-embedded
samkent has quit [Ping timeout: 245 seconds]
samkent has joined #rust-embedded
samkent has quit [Remote host closed the connection]
samkent has joined #rust-embedded
IlPalazzo-ojiisa has quit [Quit: Leaving.]
samkent has quit [Quit: Leaving]
ryan-summers[m] has quit [Quit: Idle timeout reached: 172800s]
sourcebox[m] has quit [Quit: Idle timeout reached: 172800s]
crabbedhaloablut has quit [Read error: Connection reset by peer]
crabbedhaloablut has joined #rust-embedded
kenny has joined #rust-embedded
crabbedhaloablut has quit []
crabbedhaloablut has joined #rust-embedded
IlPalazzo-ojiisa has joined #rust-embedded
crabbedhaloablut has quit []
kenny has quit [Quit: WeeChat 4.1.2]
crabbedhaloablut has joined #rust-embedded
kenny has joined #rust-embedded
notgull has joined #rust-embedded
crabbedhaloablut has quit []
crabbedhaloablut has joined #rust-embedded
IlPalazzo-ojiisa has quit [Quit: Leaving.]
barnabyw[m] has joined #rust-embedded
<barnabyw[m]>
any opinions about exposing the chip feature list in embassy-stm32 as a collapsed <details> list in the docs? it’s slightly more work as (afaik) it’s not automatically generated and would be the longest such list, but prevents people from having to dig into a library Cargo.toml to find out if their chip is supported
Guest7282 has left #rust-embedded [Error from remote client]
notgull has quit [Ping timeout: 276 seconds]
crabbedhaloablut has quit [Read error: Connection reset by peer]
crabbedhaloablut has joined #rust-embedded
crabbedhaloablut has quit [Read error: Connection reset by peer]
crabbedhaloablut has joined #rust-embedded
<Noah[m]1>
is anyone here using qemu on M1? I cannot even get it to boot a simple image :/
crabbedhaloablut has quit [Ping timeout: 252 seconds]
crabbedhaloablut has joined #rust-embedded
<thejpster[m]>
M1 as in Apple Silicon?
<thejpster[m]>
I use RISC-V QEMU and x86-64 QEMU on MacBook Pro quite a bit.
crabbedhaloablut has quit [Read error: Connection reset by peer]
crabbedhaloablut has joined #rust-embedded
<JamesMunns[m]>
you could do drop-panic bombs, at least for things that are not recoverable, however: a cancellation is no different than a cold-power off, right? Other than attempting to do more things later.
<JamesMunns[m]>
Another option to force a recovery/consistency fix instead of panicking, basically blow an "aborted" flag, and don't clear it until you know you are in a consistent state
<JamesMunns[m]>
(and definitely document "you should never cancel these futures, e.g. using select/etc")
<JamesMunns[m]>
I mean a panic is just a very strong hint, that you hope people will find in dev :D
<diondokter[m]>
Haha yeah
<diondokter[m]>
Will be annoying though to wrap all futures in a panic-on-drop-future
<JamesMunns[m]>
an alternative would be to design the format in a way that it was always deterministic to recover from a power loss, and blow the "unknown state" fuse on a cancellation
<JamesMunns[m]>
yep
<JamesMunns[m]>
diondokter[m]: yep
<JamesMunns[m]>
JamesMunns[m]: I assume you would need to partially skip OR erase some segment, if you notice on cold-boot or after-cancellation that the state is inconsistent
<dirbaio[m]>
A write cancel is kinda the same as an unclean poweroff during a write
<dirbaio[m]>
So you might be already handling that fine?
<JamesMunns[m]>
yeah, the issue is you EXPECT potential incomplete actions at boot, and (currently) do not expect it at "steady state"
<dirbaio[m]>
Yeah! In ekv I solved this with a "dirty" flag
<JamesMunns[m]>
so if you maintain any state between writes/erases/whatever, it may be inconsistent depending on how you do async/carry state
<diondokter[m]>
Currently it tries its best, but at some point it will tell you that it's corrupted
<dirbaio[m]>
When starting an op, set dirty=true. When finish, set dirty=false. If when doing an op you see dorty=true, do the same "cleanup/recover" you'd do on boot
<PeterHansen[m]>
diondokter: I have fairly sophisticated flash "logging" filesystem code which is robust in the face of cancellations, crashes, or power failures. It mainly works by always writing a sector/page/record header with at least one "magic" bit still set, then other data, then goes back and clears the magic bit(s) to finalize the sector/page/record. Not sure if you're already doing something similar, but it's possible to make it
<PeterHansen[m]>
completely bomb-proof if you take an approach like that.
<JamesMunns[m]>
diondokter[m]: you should never lose EVERYTHING on a power loss, right? unless you just erased everything? like you might lose the current segment, but does it not recover from that?
<JamesMunns[m]>
PeterHansen[m]: I'm interested to know how reliable you've found multiple writes to the same bytes across flash hardware
<dirbaio[m]>
Yeah I'd expect an unclean poweroff to maybe write or maybe not, but not trash the whole thing
<JamesMunns[m]>
In theory it seems possible, I've always been to chicken to do it in fear of not being portable
<JamesMunns[m]>
s/to/too/
<diondokter[m]>
If an item header is fully written, things should be generally ok
<diondokter[m]>
Hmmm, I'd have to test all invariants though. And those quickly multiply when any write or erase can be partial
<PeterHansen[m]>
I've never found any of these sorts of flash (either the fancy external serial flash like QSPI stuff, or the flash inside embedded chips) to have a problem with writing repeatedly to one byte, provided of course you're only ever clearing bits. I never assume that any write will be atomic, however, just that bits will only ever go from 1 to 0 except during an erase. I do also implicitly assume that during an erase I will not
<PeterHansen[m]>
likely ever encounter a partial erase state where only random bits are turned back into 1 while others are left as 0. I could imagine that happening, but since erase is on a sector by sector basis at a minimum, I just pretend I never thought of that... and don't ever expect to see it.
<PeterHansen[m]>
I know some of the parts explicitly document you can write repeatedly, provided you don't expect to turn 0s into 1s.
<diondokter[m]>
Thanks to lulf the project now has fuzzing, so I could add a random partial-write chance to the mock flash. The fuzzer should be able to find faults...
<JamesMunns[m]>
PeterHansen[m]: most manuals I've seen (for external flash) don't mention it, and nrf's internal flash specifically says something like "N writes per page per erase" or something fear inducing like that
<diondokter[m]>
STML4 has a check in hardware where on the second write, all bits have to be 0
<PeterHansen[m]>
For appending records within a sector, for example, my header will include a record type value and a record length, and an "open" bit that is left 1. Then the data can be written separately, and then when it's fully written I go back to clear the "open" bit, so a 0 means "closed" or "final". On reboot, I have to scan all open sectors to find possibly unclosed records (skipping past all closed records), then possibly recover,
<PeterHansen[m]>
or invalidate (e.g. write type field to 0), or possibly leave it invalid but go back to "close" the sector so no more appending is possible, then open a new one.
<JamesMunns[m]>
diondokter[m]: fwiw: you could probably make this exhaustive for all tests: make one pass that counts how many steps there are, add a "fuel bar" to your simulator, and iterate from 1..N and see if you can recover at that point.
<PeterHansen[m]>
James Munns: I know they may have a limit, but generally I'm only ever writing twice per byte.
<JamesMunns[m]>
likely a single functional test is doing less than a few hundred writes per test, so you could just clone + check the whole flash from a cold boot to see what it says
<diondokter[m]>
PeterHansen[m]: I do have CRC protection of the length and the data, so it may work pretty well already
<diondokter[m]>
JamesMunns[m]: In my crate, every call is as if it cold-boots
<JamesMunns[m]>
Also diondokter something that was handy for me recently was using `insta` with my mocked flash code, and writing a little "flash to hexdump" that skips all never-touched bytes
<JamesMunns[m]>
tho if you have more detailed tests, insta/snapshot testing may be less valuable and more noisy
<diondokter[m]>
JamesMunns[m]: Cool, I'll check it out!
<JamesMunns[m]>
it's useful for telling if you accidentally made some format/determinism change tho :D
<JamesMunns[m]>
(originally I WASN'T skipping untouched parts, and realized very quickly I was committing multi-megabyte text files because my mocked flash was 1M... whoops)
<PeterHansen[m]>
So yeah, that explicitly allows doing what I'm doing, provided you are never trying to append less than basically one word at a time.
<PeterHansen[m]>
Except I don't use internal flash as data, so far, for nRF...
<JamesMunns[m]>
PeterHansen[m]: yeah, on most chips, internal flash is so painful to use at runtime, it's not worth it
<JamesMunns[m]>
for like rare calibration/config data where you're fine with rebooting afterwards and/or basically stalling the whole system, it's okay.
<JamesMunns[m]>
tho nordic does have the funny "stall for N milliseconds at a time" flash peripheral helper lol
<JamesMunns[m]>
so you can choose how long you want your system to be unresponsive for when erasing/writing on-chip flash data
<PeterHansen[m]>
Yeah, the most we've done is allowed the old C SDK to use 3 sectors for writing BLE encryption keys, but that's all Nordic's code so I just let it do whatever it did. With Rust we're doing that in external flash with the rest of the data. Also used UICR for factory settings but we'll move away from that now with the new APPROTECT junk getting in the way of doing that.
<PeterHansen[m]>
James Munns: I would take Nordic's "two writes max per word between erases" to be explicit permission to do that rather than something meant to instill fear of doing even 2. I don't know what technical reason would make them not allow more, but I would guess they know that this sort of "dirty" bit thing is such a strong use case that they knew they had to support more than 1.
<JamesMunns[m]>
Yeah, that's fair, the snippet you posted was more concise/clear than I remembered. I do appreciate them specifying it, the fear is more "oh god are all the other datasheets just incomplete on this topic?"
<PeterHansen[m]>
true
<diondokter[m]>
PeterHansen[m]: We've been doing 2 writes on the nrf91 and it's never gone wrong so far
<diondokter[m]>
STM also explicitly allows it as long as the second write is all 0
<PeterHansen[m]>
I can only say I haven't had a problem with this across tens of thousands of consumer devices doing this all day long for small bits of data (appending 4-100 bytes at a time, many times a day).
<PeterHansen[m]>
but not in the nRF flash... definitely external
<PeterHansen[m]>
diondokter: Ew, yuck... that would be so annoying.
<JamesMunns[m]>
it's like when a food has a label that's like "contains no X!", and you're like, "wait, is that marketing, or does all other food like that contain X?"
<diondokter[m]>
PeterHansen[m]: Yeah, it reports it as an error if it's not. But at least it's hardware-checked
<PeterHansen[m]>
I guess it would just force me to reserve an entire word as the "dirty" flag. :(
<diondokter[m]>
JamesMunns[m]: In Dutch supermarkets, the vegan label now gets put on everything. Like ok, thanks for letting me know this bag of vegetables is vegan...
<PeterHansen[m]>
Which I guess is always an option too, of course... as long as you can spare the wasted space, I guess that's guaranteed safe.
<JamesMunns[m]>
diondokter[m]: I was gunna make the same comment about "gluten free", because sometimes I see that on silly stuff that definitely never contains gluten.
<JamesMunns[m]>
But hey, mcdonalds fries used beef tallow for a long time, which made some religious + vegetarian/vegan people fairly mad when they found out
<JamesMunns[m]>
so, yes its a silly label, but also I wouldn't put it past a company to put whatever filler on things. Maybe a bag of broccoli is simple enough for that :D
M9names[m] has joined #rust-embedded
<M9names[m]>
diondokter[m]: You do want advance warning when your veg gets a taste for meat 😋
<PeterHansen[m]>
As someone with a celiac daughter, I appreciate anything that explicitly says "no wheat". After all, it turns out even some spices and herbs toss in some wheat, apparently to absorb moisture.
<JamesMunns[m]>
yeah, exactly. I have friends/family with allergies, and it's no joke. like "cooked on the same pan that was used to cook with shellfish" was enough to send my mom to the hospital, so I totally do appreciate those notices.
IlPalazzo-ojiisa has joined #rust-embedded
kpcyrd[m] has joined #rust-embedded
<kpcyrd[m]>
In case somebody is going to be at 37c3, I'm going to be looking for somebody to implement embedded_hal::blocking::i2c::{Read, Write, WriteRead} with for an attiny85 :) I'm going to bring digisparks to develop with. I think one of the c3's was when I first ran into Rust for embedded, but only picked it up a few years later.