-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Loading two programs that take too much space result in an endless loop
embassy/embassy-rp/src/pio/mod.rs
Lines 1108 to 1113 in 8a20a57
| while origin < 32 { | |
| match self.try_load_program_at(prog, origin as _) { | |
| Ok(r) => return Ok(r), | |
| Err(a) => origin = a + 1, | |
| } | |
| } |
This loops tries to naively search for a space until the origin is reached, but the problem is the Err(a) => origin = a + 1, line, because the downstream function doesn't guarantee exclusively incremental a.
embassy/embassy-rp/src/pio/mod.rs
Lines 1142 to 1153 in 8a20a57
| for (i, instr) in instrs.enumerate() { | |
| // wrapping around the end of program memory is valid, let's make use of that. | |
| let addr = (i + start) % 32; | |
| let mask = 1 << addr; | |
| if (self.instructions_used | used_mask) & mask != 0 { | |
| return Err(addr); | |
| } | |
| PIO::PIO.instr_mem(addr).write(|w| { | |
| w.set_instr_mem(instr); | |
| }); | |
| used_mask |= mask; | |
| } |
Let's say we try to load 2 programs: 11 intructions and 27 (anything 32 < 11 + second_program). Once we finally find the end of the program in the try_load_program while loop, the try_write_instr starts loading the second program.
Issue: when second program is loaded in try_write_instr and it reaches the first's origin (which is 0) it returns a = 0 in the Err to the line Err(a) => origin = a + 1, and resents the origin counter causing an infinite loop.
P.S. I apologies in case the issue is formatted incorrectly. I wasn't able to find guidance at a quick glance. Also I would be happy to fix this and raise a PR if that helps