- Date: 2020-04-27
- Time: 22:30
- Link to this stream
- Link to Office Hours Channel
- Worked on the bbqueue esb PR
- Didn't get the the RFC
- Playing with Nordic Radios and Enhanced ShockBurst - office-hours#2
- Write an RFC for Embedded WG MSRV - office-hours#8
So what are we doing here?
Two contexts:
- Interrupt Context
- App context
Additionally, we are going to be doing DMA, which means we need to have packets:
- In RAM (nrf52 specific)
- Data must be contiguous (because DMA)
- Comms between contexts must be thread safe (because interrupts)
- Data must have
'static
lifetime (mostly)
heapless::Queue<[0u8; 32], U10>
| 32 bytes | 32 bytes | ..... | 32 bytes |
BUT if you have variable packet
bbqueue
- really great for variable size chunks of u8 (bytes).
| ONE BIG POOL OF BYTES | | | | | | | | | ] | ][ ]
APP SIDE IRQ SIDE
======== ========
Some handle Some Handle
- send packet - get outgoing packet
- receive a packet - shove incoming packet
====================> OUTGOING
PRODUCER CONSUMER
<==================== INCOMING
CONSUMER PRODUCER
We need two BBQueues!
// Buffer for ESB, incoming queue is 1024 bytes, outgoing queue is 512 bytes
static BUFFER: EsbBuffer<U1024, U512> = EsbBuffer::new();
fn main() {
let (mut app_esb, irq_esb) = EsbInterface::new(&BUFFER).unwrap();
// somehow send `irq_esb` to the interrupt
something(irq_esb);
// Enable ESB or something?
app_esb.init(...).unwrap();
// TODO: What is a better interface?
if auto_send { // DO this one
// start the reception process
let mut msg = app_esb.start_send().unwrap();
// Fill the outgoing message
msg[..8].copy_from_slice(&[10u8; 8]);
// NOTE: This pends the RADIO interrupt too!
msg.complete_send();
} else {
// start the reception process
let mut msg = app_esb.start_push().unwrap();
// Fill the outgoing message
msg[..8].copy_from_slice(&[10u8; 8]);
msg.finish_push();
// Trigger send
app_esb.start_tx();
}
// OR: Do we want
// Wait for an incoming message
while !app_esb.msg_ready() {
continue;
}
// now we're not waiting
let incoming = app_esb.get_incoming().unwrap();
assert_eq!(&incoming[..8], &[11u8; 8]);
}
#[interrupt]
fn RADIO() {
static mut STATE = ...;
let esb_handle = something_get().unwrap();
// Something with the radio?
match STATE {
State::Idle => {
// check for outgoing?
}
State::WaitingForAck => {
// check for incoming?
// Maybe also a new outgoing?
if got_ack() {
push_into_queue()
check_for_next()
}
}
}
}