Firmware: Emit CAN “State Change Notification” Frames#

Requirements Specification#

  • Use Hardware: CAN Controller JF0815

  • 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

    • ⟶ 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#

Fear And Uncertainty Ahead#

Pending Queue

  • “Pending queue” is hammered on by multiple ISRs in parallel

  • std::list is not atomic

  • ⟶ 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

  • ⟶ Lost/delayed notification

  • ⟶ Fortunately we are using a spinlock