.. include:: Firmware: Emit CAN "State Change Notification" Frames ===================================================== Requirements Specification -------------------------- * Use :doc:`../can-jf0815-hw/index` * On every state transition, send out the new state * CAN ID: 37 * Payload, in little endian: * ``RUNNING``: 1 * ``OVERTEMP``: 2 * ``SENSORBURNING``: 3 Plan ---- * FSM constructor: add "CAN id", and "CAN interface" (Linux SocketCAN) parameters * Add ``CAN_JF0815_HW_Wrapper`` member * ``CAN_JF0815_HW_Wrapper`` only has room for one in-flight frame * |longrightarrow| Need "pending" queue if still busy sending * Wrap state change into method * Create CAN frame like defined * If xmit busy, push to pending-queue * Else, xmit directly * Change state * Register ISR for "xmit-done" interrupt * Pop frame from pending queue if any, and xmit * **Question: locking?** Software Changes When Done -------------------------- .. toctree:: :maxdepth: 1 main fsm Fear And Uncertainty Ahead -------------------------- **Pending Queue** * "Pending queue" is hammered on by multiple ISRs **in parallel** * ``std::list`` is **not atomic** * |longrightarrow| **Fortunately we are using a spinlock** **If-then-else** * ``if (controller is busy)``, followed by action, **is not atomic** * Once we enter the *controller busy* branch (about to enqueue the frame for later), the CAN xmit-done ISR might have just interrupted us * |longrightarrow| **Lost/delayed notification** * |longrightarrow| **Fortunately we are using a spinlock**