tock / tockloader

Tool for programming Tock onto hardware boards.
MIT License
42 stars 47 forks source link

Mixing fixed position and PIC apps #82

Open dcz-self opened 2 years ago

dcz-self commented 2 years ago

Tockloader currently has 2 separate paths for flashing: one for when all apps are PIC and can go anywhere in the flash, and one for when all have fixed positions in the flash (possibly multiple fixed positions).

This separation fundamentally doesn't have to exist, because (presumably) Tock kernel can make sense out of applications and where to put them if it gets a mix of both.

With libtock-c producing PIC binaries, and libtock-rs producing only fixed ones, until this issue is solved, programs using them cannot coexist.

I'm creating this issue as a place to discuss solving this.

dcz-self commented 2 years ago

The timing is not accidental, because I'm halfway through implementing a solution. To make the process as smooth as possible (rather than sending a deluge of patches), I'd like to educate myself on some opinions first.

  1. The change needs some refactoring of the tbf handling and App classes (so far, generalizing some methods to handle the case of multiple-applications-in-one). Does it make sense to send them as separate patches, or include them in one big update where they are actually put to use?

  2. Is adding a dependency OK? I've rolled out the big guns, and instead of finding the specific solution, I went for a SAT solver. This way seems more testable, too.

  3. Regarding unit tests, is there any preferred framework I should use for the above?

dcz-self commented 2 years ago

I made it work, a fixed libtock-rs app together with a PIC libtock-c app:

│ App 0                                            |
  Name:                  
  Enabled:               True
  Sticky:                False
  Total Size in Flash:   1024 bytes
  Address in Flash:      0x30000
[...]
    TLV: Fixed Addresses (5)
      fixed_address_ram   :  536911888   0x2000a010
      fixed_address_flash :     196680      0x30048

│ App 1                                            |
  Name:                  blink
  Enabled:               True
  Sticky:                False
  Total Size in Flash:   2048 bytes
  Address in Flash:      0x30800

Output shows both:

Initialization complete. Entering main loop
NRF52 HW INFO: Variant: AAC0, Part: N52840, Package: QI, Ram: K256, Flash: K1024
tock$ FER FULL ***
[1] cmd(0x2, 2, 0x1, 0x0) = Success

*** DEBUG BUFFER FULL ***
[1] cmd(0x0, 2, 0x0, 0x0) = SuccessU3
*** DEBUG BUFFER FULL ***
[1] cmd(0x0, 6, 0x12feb, 0x1f40) = Su
*** DEBUG BUFFER FULL ***
[0] memop(0, 0x2000c010) = Success
[
*** DEBUG BUFFER FULL ***
[0] cmd(0x2, 1, 0x0, 0x0) = Success

If anyone's interested in the "kill it with fire" quality prototype, I keep it in here: https://github.com/dcz-self/tockloader/tree/master . The actual SAT part is rather readable though, and lives in https://github.com/dcz-self/tockloader/blob/master/tockloader/allocate.py

Now I'd like to find out how best to proceed with this, because the practical flashing also received some changes.

bradjc commented 2 years ago

I think combining the changes into a PR is fine, as is handling the internal API changes separately.

As for adding z3, I'm not sure we want to go that direction. Because it pulls in host code, I'm worried it could make tockloader hard to install to support a narrow use case.

What about what we talked about before: placing all of the fixed apps and then appending the PIC apps?

dcz-self commented 2 years ago

That could work, although I'm not especially eager to code the algorithm by hand when optimizers come to better solutions with less effort.

In either case, the first step would be to separate the act of positioning from the act of flashing, as they are intertwined currently. Then the position solver could be self-contained and pluggable. I'll try to submit something to that effect when I have the time.