Wednesday, August 2, 2017

Keeping It Simple. Stoopid.


Notes from yesterday / today:

I need a running TODO list. Some items are marked  '// TODO' in code comments, but some are related to real-world builds or tweaks. Right now it's in a small notebook I keep with me, but 'out of sight, out of mind' and all that... The list will be at the bottom of every post. Still beats a project plan, but only just.

Looks like the boot procedure needs some work / documentation so I can get a working memory management library done; here is the current setup:

setup()
  • At startup, pull a byte from internal EEPROM with pointers to the rest of config.
    • This is bit-packed, 2 bits per state, 4 states, pointing each SEQ[0..3] to a memory type (flash, internal EEPROM, external EEPROM, FRAM/SD/...)
  • Perform config work by reading in register init-values as needed (bytes 0 to 31) of config.
  • Read in the operating-config to a register array (currently byte 32 to ~96).
  • Addresses for the four prime state sequences (they can be in different memories) are in the MAP structure in that memory. MAP always starts at byte 256, and is 128 bytes long, and each entry is 4 bytes.
  • Validate that SEQ0 memory is reachable, readable, parseable.
  • Prep for loop() with state = POTC (ie, SEQ0) & instruction pointer = 0.
  • Log the end of startup.
loop()
  • Process hardware & flags for state changes (we might go to state = ERROR, for example).
  • Look at the state elements (at boot state = SEQ0); one will have an 'execute now' schedule; 
  • Read-in the opcode and parameter at IP, and dispatch to the interpreter.
  • If the opcode returns zero, then increment the IP (if not, the routine needs more time/loop cycles*; do nothing more.
  • Loop.
*Most opcodes will call functions that complete and return quickly, and are 'blocking'. An obvious exception is rotating the table to a new position, which is non-blocking.

The reason for this extra complexity is to allow different sequences and configurations to be stored in different memories. For example, a skinny version of the daily schedule (SEQ1) is in FLASH, so everything *should* work even if EEPROM gets wiped out. But we might want a much longer sequence for a given day, or if this is used with different hardware (for example, the rover).

// TODO:
  • get the TODO list into the blog
  • organize the reg[ ] array into config and run entries. Those entries that are only used during setup() don't have to be copied in memory. I should be able to save about 32 bytes of SRAM this way.
  • document the current boot sequence (and update the memory map in the spreadsheet)
  • copy the position schedule currently in a FLASH_ARRAY into some of the unused low bytes of internal EEPROM. I think it fits between the reg[] and MAP.
  • document blocking vs non-blocking calls
  • sift thru the current spreadsheet of opcodes and stuff all the blocking calls into one group so we can flag those in the sequence generator - in case we need to run those as 'exclusive'.
  • I had an idea to wrap the stock LCD library so we can include references to a string_table for option-list type fields. Currently it's all numeric. Smells like scope creep.
  • UPDATE: Forgot the August 31 deadline for autonomous operations. Dang.


No comments:

Post a Comment