slowly pulling together the methodology and API for the roadster real-time code.
current project source onstruction. needs rundown of what's in the library (IPC*, power, eeprom, logging).
this was the workign note from roadster hood ornament logger spy.
/* ROADSTER STANDARD MODULE INTERFACE DEFINITE-METHOD REALTIME SCHEME this main source file in typical Arduino Wiring arrangement contains the main loop() and setup() as always, but also the global environment all of the user code relies on. what follows, from this point in the source down to setup and loop, set up and define the standard interface ("operating systems api") that the other modules assume. Arduino IDE and C++ puts demands and limitations on what is possible. Arduino IDE by default concatenates all .ino files into one large (hidden, temporary) .c file to compile. in order to evade many of the implied side effects the following scheme is used. it works with the IDE and would be easy to do in a makefile. A) DEFINITIONS REQUIRED BEFORE CODE: #include Arduino libraries. #include SR libraries. #include SRMessage message codes and related enums ("roadster_codes.h") #include Roadster/project specific definitions (engine, pins, common flash text, etc) B) DATA REQUIRED BEFORE CODE: generally tables and debug. the badly-named resend list -- table of messages that this box originates. EEPROM save list -- table of messages that should be saved/restored in EEPROM. Any other global read-only data tables. (this is a C++ limitation). C) IPC PROTOTYPES. IPC and it's arguments depend on typedefs and enums defined in section A. // prototypes of the global IPC functions defined in ipc.h. messageV IPCSendMessage (loopV, loopV, messageV, unsigned); unsigned IPCFetchDatum (loopV, messageV); void log Message (const __FlashStringHelper *h, messageV code, unsigned nnn); void IPCMessageStatistics (void); // honeypot to catch references to global "fetchDatum"... // float fetchDatum (int, int, int, int, int, int, int); D) THE API. these are simply global instantiations of SRLOG, SRPRNG, etc. none of these have side effects. NOTE: one danger is when the main section needs an instance of SRTimer; that instance will be global, and source errors in other modules (eg. forgetting to define) could inadvertantly reference it instead of a local copy. no fix here except if global needs a timer, to not use the 'T' name convention. E) DEBUGGER SECTION. global but without side effects (or none of any significance). F) MODULE SECTION. see special footnote on IPC code arrangement. #includes of all task loop objects. each task loop source should define AND INSTANTIATE one object. objects here are to create local scopes, not for class reusability. it's bad that the object names are contained in the source file but in practice it never seems to matter. it is critical to note that the IPC module is loaded LAST (and initialized FIRST). the global IPCSendMesssage dispatcher references each of the objects, which must be defined before IPC code is included. (careful prototypes would resolve this if necessary). see special footnote on IPC code arrangement. G) MAIN SETUP. setup() initializes all of the objects and functions loaded in D) and local hardware, especially power-handling, quickly. the setup() method of all task loop objects are called. it is critical to note that IPC is initialized FIRST (and loaded, above, first). task loop setup() may call IPC during it's initialization. note that many objects use malloc to initialize themselves ONE TIME; memory allocated is NEVER released, hence, no fragmentation problems nor susceptibility to malloc bugs. H) MAIN LOOP. loop() then simply calls each task loop object's loop() method. IPC CODE ARRANGEMENT: the IPC object/code is loaded by including the IPC.h tab, described in D) above. however portions of the IPC are local/specific to the project and some parts are commonm and stored in the library. refer to the IPC.h tab. */
notes for new IPC scheme. jan 2019 uplink, downlink messages are SRMessages; uint16 payload and postfix message type (single ASCII letter). see SRMessage docs for details. there are no exceptions. only SR Message basic messages (A..Za..z) and IPCR_ messages may pass through the inter-box IPC. IPCL_ messages are intra-box only. messages have no addressing of any kind. each box has a list (badly named "resend" list) that is the list of which messages that box originates. sending boxes (usually) send all messages on both uplink and downlink ports. the main or only exception is MSGCOLDBOOT. sending boxes have no knowledge of which box "wants" any particular message. messages may be received at any time from uplink or downlink. receiving boxes may act on, drop, or forward incoming messages. when a message is received (from uplink or downlink) and is to be forwarded, it is forwarded to the opposite link (downlink or uplink). messages that are generated within a given box, but received on any link, are generally dropped. STARTUP/RESET RECOVERY there is only one startup sequence that handles normal power on and unexpected reset recovery. the end result is, at power-on time, when all boxes power up and are ready "at the same time" (see below) then starup proceeds as an odinary cold boot. if however any (one or more) box resets "substantially after" at least one other box, that "up" box restores current operating state to all other boxes. "at the same time": each box has a typical millisecond clock that resets at reset. boxes with uptime greater than ENGINE_BOOTDEADTIME are assumed to have complete operating state and will respond to MSGCOLDBOOT messages with a state broadcast. boxes with uptimes short of that remain silent (and receiev updates). when reset: * each box issues MSGCOLDBOOT to both uplink and downlink, 3 times; delayed (more or less 100 mS) from reset or previous MSGCOLDBOOT. * any MSGCOLDBOOT received from uplink is acted upon and forwarded downlink. * any MSGCOLDBOOT received from downlink is acted upon and not forwarded. upon receipt of MSGCOLDBOOT (from up or down) the receiving controller schedules a "fast resend" of the entire message cache iff the receiving box has been itself up for at least ENGINE_BOOTDEADTIME. EXCEPTION TO THE ABOVE MSGACTION HANDLING occurs between the panel and chassis controllers, and regarding lighting state changes. LEFT, RIGHT and HAZARDS are not simple on/off states; the physical actions on the panel send triggering ICPR_BLINK* events to the chassis controller, which counts out the defined number (and width, etc) blinks. each blink sub-event is returned to the panel as an ICPR_BLINK* event. (headlights and brakelights are simple states, and hence can be restored by cold boot. blinking is lost at reset.) forked from v4, runs on new ANALOG and POWER boards. cooling functions split off into separate cooling computer.