I'm trying learn rust and native coding and bare-metal and raspberry pi all at once. I'm targeting aarch64 rpi3 (https://github.com/JasonKleban/rust-rasp) and trying to figure out the rustiest way to make its onboard ACT led blink. Actually, I haven't gotten it to blink at all yet - I think my build may be right but I wouldn't be able to tell yet because there's of course no outward indication until I can expect to see that light blinking, which I don't yet have the right code for.
I found some information about how to do this but the examples/tutorials are in c (https://github.com/vanvught/rpidmx512/blob/master/lib-bcm2835/src/bcm2837_gpio_virt.c) or asm (https://adamransom.github.io/posts/raspberry-pi-bare-metal-part-1.html). There's a particular way we need to ask the GPU to control the ACT led for us - with a mailbox protocol. The mailbox is mapped to a particular address and we write arbitrarily-sized, word-aligned, and word-padded data to send messages. The sizes of the data are included in the data.
I'm **aware** of rust's `#[repr(align(4))]` and dynamically-sized-types, but I don't know how we might even represent the padding at the end (as documented) to reserve exactly the space needed. There's also an "end of tags" symbol, 0x0, expected after the last tag in the arbitrary-sized sequence of tags in a buffer but in rust such a dynamically-sized-type can only be last in the struct.
By my reading, I think the buffer full of tags is to be allocated on the heap (aligned(4) so that bits needed for other purposes can be assumed to be 0) and that only the address gets placed on the mailbox. I don't understand what happens after that. So we're writing a single word being the memory address of the buffer? I think is an atomic operation but I don't know how atomic works in shared memory on independent processors.
And then how do we know that the item has been processed and that we can deallocate the buffer? If the answer is that the GPU is writing back to our mailbox to say "DONE" then how does IT know that we've seen its message so that it can deallocate that "DONE" message?
Also, perhaps the GPU on an RPI3 has access to all the memory, but I don't think it is always the case. So how can rust hint to the allocator that the memory must be allocated in a particular range?
How can protocols like this be modeled nicely as rust types? Or does it have to be modeled in rust as `&mut [u8]` with very unsafe function fiddling all the bytes to make up the buffer?
I don't care to write in c, I'm drawn to rust. I don't care to learn rust on x86_64, I'm drawn to arm/embedded. I don't care to write for an OS - I don't want long boot times, system maintenance, user accounts, or startup scripts. I definitely don't want to write python. Other than the OS and the python-emphasis, I like the rpi3 because it seems like I should be able to hook up ready-made peripherals to it and figure out how to control motors and sensors on it from bare metal once I understand the basics - I AM interest if there's a better, cheap, modern, rust-compatible, bare-metal platform for robotics than rpi though - I want to write bare-metal rust (ideally for 64-bit ARMv8+ because it seems clean and power-efficient but also very capable) mostly to control gpio pins (I think) connected to motor controllers and simple sensors. I'm really bad at electronics, so I don't know how to make my own peripherals.