Scott Worley [Tue, 10 Oct 2023 07:50:42 +0000 (00:50 -0700)]
client: Hold presses in queues, one queue per send_count
This lets us efficiently hold many more presses with pending resends
and eliminates the failure mode in which young presses could be dropped
because the sleeps_heap was full of old presses.
Instead of storing each press in the sleeps_heap, we now only store up
to config_resend_count entries in the sleeps_heap.
Old presses now only compete with similarly-old presses for retention
space.
Scott Worley [Mon, 9 Oct 2023 21:53:25 +0000 (14:53 -0700)]
client: Stop sleeping separately for each re-send
Instead, determine when the next send, in the whole pile of sends,
needs to happen and sleep until then.
This is the first functionality in this project that is more than simple
glue code. This is the first non-trivial functionality that has some
internal logic to it.
I'd really like to write a test for it.
This environment (C, CMake, pico-sdk) makes testing hard! :(
I'd like to build the test as a host/native executable and run it on the
build machine at build time, even though the primary/production use of
the code under test would be on the pico, cross-compiled.
I know testing this way is imperfect: It would fail to catch the entire
class of bugs that are caused by the code under test making architecture
assumptions that are valid on the build host but invalid on the cross
target. But it would still be very useful for all other classes of bugs!
This usage is very much not supported:
1. CMake doesn't support it at all: One toolchain per language:
https://discourse.cmake.org/t/compile-unit-test-natively-and-cross-compile-code-for-embedded-target/3607
https://discourse.cmake.org/t/using-multiple-toolchains-in-the-same-project/1505
2. Even if I'm confident in my ability to write portable C that runs
correctly on both build-host and cross-target architectures, I can't
rely on pico-sdk's pheap library to be portable in this way. It is
super-not-portable-at-all; it will never run on the build host.
3. If I use a different, portable heap library, I'm duplicating code
already in the pico-sdk standard library. The pico is small enough
already. I'd rather not deploy two heap libraries.
4. I could define an interface to a heap library & use the pico's heap
library when deploying to the pico & some other heap library when testing
on the native machine, but
a. My interface-to-pico's-heap-library code goes untested.
b. The interface-to-a-heap-library code would likely add overhead.
c. That's a bunch of extra code to write. :(
5. Even if I worked through the interfacing-with-pico's-heap library issue
and made this a separate, independent, portable library, I'd still
be left with the problem of composing the two pieces. Do I build
a library .so separately, spinning up a separate Debian VM for that?
Does pico-sdk even support building libraries? Or do I copy the source
of the library into the executable's source tree & make building the
library part of the executable's build process? Ick. :(
6. Other option: Build a test intended to run on the pico. It's nuts
that this is the least-nuts option. :(
I am very discouraged. :(
I don't even bother to keep this functionality separate with a clean
interface for the test harness. :(
Scott Worley [Sun, 8 Oct 2023 04:34:50 +0000 (21:34 -0700)]
client: net: Fix port byte order
Docs ( https://www.nongnu.org/lwip/2_0_x/group__udp__raw.html ) say
"ipaddr & port are expected to be in the same byte order as in the pcb,"
which apparently means _don't_ run it through htons().
Scott Worley [Fri, 29 Sep 2023 19:37:21 +0000 (12:37 -0700)]
client: Build in a Debian VM
This finally makes it work. Hurray!
Other things I tried that didn't help:
* Other versions of cross gcc (8, 9, 10, 11 12)
* Other versions of host gcc (10)
* Other versions of pico-sdk (1.3.1, 1.4.0)
arm-none-eabi-gcc as packaged in Debian works.
arm-none-eabi-gcc as packaged in Nix doesn't.
I haven't yet looked further into why.