コード例 #1
0
 def testStopAfterStart(self):
     a = ResettableTimer(0.4)
     a.start()
     self.assertEqual(True, a.isRunning())
     self.assertEqual(False, a.isExpired())
     a.stop()
     self.assertEqual(False, a.isRunning())
     self.assertEqual(False, a.isExpired())
コード例 #2
0
 def testStateAfterExpiredThenRestart(self):
     a = ResettableTimer(0.4)
     a.start()
     sleep(0.45)
     self.assertEqual(False, a.isRunning())
     self.assertEqual(True, a.isExpired())
     a.restart()
     self.assertEqual(True, a.isRunning())
     self.assertEqual(False, a.isExpired())
コード例 #3
0
 def testTimerAccuracy(self):
     testTimes = [1, 0.3, 0.2, 0.1, 0.01, 0.01]
     for i in testTimes:
         a = ResettableTimer(i)
         startTime = perf_counter()
         a.start()
         while (a.isRunning()):
             pass
         endTime = perf_counter()
         delta = endTime - startTime
         self.assertAlmostEqual(delta, i, delta=0.001)
コード例 #4
0
    def recv(self, timeout_s):
        #return self.__connection.recv(... can pass timeout from here if required ...)  # .... implemented in the LIN bus impl, so the rest of function replaced by this
        timeoutTimer = ResettableTimer(timeout_s)

        payload = []
        payloadPtr = 0
        payloadLength = None

        sequenceNumberExpected = 1

        endOfMessage_flag = False

        state = LinTpState.IDLE

        timeoutTimer.start()
        while endOfMessage_flag is False:

            rxPdu = self.getNextBufferedMessage()

            if rxPdu is not None:
                N_PCI = (rxPdu[N_PCI_INDEX] & 0xF0) >> 4
                if state == LinTpState.IDLE:
                    if N_PCI == LinTpMessageType.SINGLE_FRAME:
                        payloadLength = rxPdu[N_PCI_INDEX & 0x0F]
                        payload = rxPdu[SINGLE_FRAME_DATA_START_INDEX: SINGLE_FRAME_DATA_START_INDEX + payloadLength]
                        endOfMessage_flag = True
                    elif N_PCI == LinTpMessageType.FIRST_FRAME:
                        payload = rxPdu[FIRST_FRAME_DATA_START_INDEX:]
                        payloadLength = ((rxPdu[FIRST_FRAME_DL_INDEX_HIGH] & 0x0F) << 8) + rxPdu[
                            FIRST_FRAME_DL_INDEX_LOW]
                        payloadPtr = self.__maxPduLength - 1
                        state = LinTpState.RECEIVING_CONSECUTIVE_FRAME
                        timeoutTimer.restart()
                elif state == LinTpState.RECEIVING_CONSECUTIVE_FRAME:
                    if N_PCI == LinTpMessageType.CONSECUTIVE_FRAME:
                        sequenceNumber = rxPdu[CONSECUTIVE_FRAME_SEQUENCE_NUMBER_INDEX] & 0x0F
                        if sequenceNumber != sequenceNumberExpected:
                            raise Exception("Consecutive frame sequence out of order")
                        else:
                            sequenceNumberExpected = (sequenceNumberExpected + 1) % 16
                        payload += rxPdu[CONSECUTIVE_FRAME_SEQUENCE_DATA_START_INDEX:]
                        payloadPtr += (self.__maxPduLength)
                        timeoutTimer.restart()
                    else:
                        raise Exception("Unexpected PDU received")

            if payloadLength is not None:
                if payloadPtr >= payloadLength:
                    endOfMessage_flag = True

            if timeoutTimer.isExpired():
                raise Exception("Timeout in waiting for message")

        return list(payload[:payloadLength])
コード例 #5
0
    def send(self, payload, functionalReq=False):  # TODO: functionalReq not used???
        #self.__connection.send(payload)  # .... implemented in the LIN bus impl, so the rest of function replaced by this
        payloadLength = len(payload)

        if payloadLength > LINTP_MAX_PAYLOAD_LENGTH:
            raise Exception("Payload too large for CAN Transport Protocol")

        if payloadLength <= self.__maxPduLength:
            state = LinTpState.SEND_SINGLE_FRAME
        else:
            # we might need a check for functional request as we may not be able to service functional requests for
            # multi frame requests
            state = LinTpState.SEND_FIRST_FRAME
            firstFrameData = payload[0:self.__maxPduLength-1]
            cfBlocks = self.create_blockList(payload[5:])
            sequenceNumber = 1

        txPdu = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

        endOfMessage_flag = False

        ## this needs fixing to get the timing from the config
        timeoutTimer = ResettableTimer(1)
        stMinTimer = ResettableTimer(self.__STMin)

        self.clearBufferedMessages()

        timeoutTimer.start()
        while endOfMessage_flag is False:

            rxPdu = self.getNextBufferedMessage()

            if rxPdu is not None:
                raise Exception("Unexpected receive frame")

            if state == LinTpState.SEND_SINGLE_FRAME:
                txPdu[N_PCI_INDEX] += (LinTpMessageType.SINGLE_FRAME << 4)
                txPdu[SINGLE_FRAME_DL_INDEX] += payloadLength
                txPdu[SINGLE_FRAME_DATA_START_INDEX:] = fillArray(payload, self.__maxPduLength)
                self.transmit(txPdu)
                endOfMessage_flag = True
            elif state == LinTpState.SEND_FIRST_FRAME:
                payloadLength_highNibble = (payloadLength & 0xF00) >> 8
                payloadLength_lowNibble  = (payloadLength & 0x0FF)
                txPdu[N_PCI_INDEX] += (LinTpMessageType.FIRST_FRAME << 4)
                txPdu[FIRST_FRAME_DL_INDEX_HIGH] += payloadLength_highNibble
                txPdu[FIRST_FRAME_DL_INDEX_LOW] += payloadLength_lowNibble
                txPdu[FIRST_FRAME_DATA_START_INDEX:] = firstFrameData
                self.transmit(txPdu)
                state = LinTpState.SEND_CONSECUTIVE_FRAME
                stMinTimer.start()
                timeoutTimer.restart()
            elif state == LinTpState.SEND_CONSECUTIVE_FRAME:
                if(
                        stMinTimer.isExpired() and
                        (self.__transmitBuffer is None)
                ):
                    txPdu[N_PCI_INDEX] += (LinTpMessageType.CONSECUTIVE_FRAME << 4)
                    txPdu[CONSECUTIVE_FRAME_SEQUENCE_NUMBER_INDEX] += sequenceNumber
                    txPdu[CONSECUTIVE_FRAME_SEQUENCE_DATA_START_INDEX:] = cfBlocks.pop(0)
                    self.transmit(txPdu)
                    sequenceNumber = (sequenceNumber + 1) % 16
                    stMinTimer.restart()
                    timeoutTimer.restart()

                    if len(cfBlocks) == 0:
                        endOfMessage_flag = True

            txPdu = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

            sleep(0.001)

            if timeoutTimer.isExpired(): raise Exception("Timeout")
コード例 #6
0
    def recv(self, timeout_s):

        timeoutTimer = ResettableTimer(timeout_s)

        payload = []
        payloadPtr = 0
        payloadLength = None

        sequenceNumberExpected = 1

        txPdu = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

        endOfMessage_flag = False

        state = CanTpState.IDLE

        timeoutTimer.start()
        while endOfMessage_flag is False:

            rxPdu = self.getNextBufferedMessage()

            if rxPdu is not None:
                N_PCI = (rxPdu[N_PCI_INDEX] & 0xF0) >> 4
                if state == CanTpState.IDLE:
                    if N_PCI == CanTpMessageType.SINGLE_FRAME:
                        payloadLength = rxPdu[N_PCI_INDEX & 0x0F]
                        payload = rxPdu[SINGLE_FRAME_DATA_START_INDEX:
                                        SINGLE_FRAME_DATA_START_INDEX +
                                        payloadLength]
                        endOfMessage_flag = True
                    elif N_PCI == CanTpMessageType.FIRST_FRAME:
                        payload = rxPdu[FIRST_FRAME_DATA_START_INDEX:]
                        payloadLength = (
                            (rxPdu[FIRST_FRAME_DL_INDEX_HIGH] & 0x0F) <<
                            8) + rxPdu[FIRST_FRAME_DL_INDEX_LOW]
                        payloadPtr = self.__maxPduLength - 1
                        state = CanTpState.SEND_FLOW_CONTROL
                elif state == CanTpState.RECEIVING_CONSECUTIVE_FRAME:
                    if N_PCI == CanTpMessageType.CONSECUTIVE_FRAME:
                        sequenceNumber = rxPdu[
                            CONSECUTIVE_FRAME_SEQUENCE_NUMBER_INDEX] & 0x0F
                        if sequenceNumber != sequenceNumberExpected:
                            raise Exception(
                                "Consecutive frame sequence out of order")
                        else:
                            sequenceNumberExpected = (sequenceNumberExpected +
                                                      1) % 16
                        payload += rxPdu[
                            CONSECUTIVE_FRAME_SEQUENCE_DATA_START_INDEX:]
                        payloadPtr += (self.__maxPduLength)
                        timeoutTimer.restart()
                    else:
                        raise Exception("Unexpected PDU received")

            if state == CanTpState.SEND_FLOW_CONTROL:
                txPdu[N_PCI_INDEX] = 0x30
                txPdu[FLOW_CONTROL_BS_INDEX] = 0
                txPdu[FLOW_CONTROL_STMIN_INDEX] = 0x1E
                self.transmit(txPdu)
                state = CanTpState.RECEIVING_CONSECUTIVE_FRAME

            if payloadLength is not None:
                if payloadPtr >= payloadLength:
                    endOfMessage_flag = True

            if timeoutTimer.isExpired():
                raise Exception("Timeout in waiting for message")

        return list(payload[:payloadLength])
コード例 #7
0
    def send(self, payload, functionalReq=False):

        payloadLength = len(payload)
        payloadPtr = 0

        state = CanTpState.IDLE

        if payloadLength > CANTP_MAX_PAYLOAD_LENGTH:
            raise Exception("Payload too large for CAN Transport Protocol")

        if payloadLength < self.__maxPduLength:
            state = CanTpState.SEND_SINGLE_FRAME
        else:
            # we might need a check for functional request as we may not be able to service functional requests for
            # multi frame requests
            state = CanTpState.SEND_FIRST_FRAME

        txPdu = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

        sequenceNumber = 1
        endOfMessage_flag = False

        blockList = []
        currBlock = []

        ## this needs fixing to get the timing from the config
        timeoutTimer = ResettableTimer(1)
        stMinTimer = ResettableTimer()

        self.clearBufferedMessages()

        while endOfMessage_flag is False:

            rxPdu = self.getNextBufferedMessage()

            if rxPdu is not None:
                N_PCI = (rxPdu[0] & 0xF0) >> 4
                if N_PCI == CanTpMessageType.FLOW_CONTROL:
                    fs = rxPdu[0] & 0x0F
                    if fs == CanTpFsTypes.WAIT:
                        raise Exception("Wait not currently supported")
                    elif fs == CanTpFsTypes.OVERFLOW:
                        raise Exception("Overflow received from ECU")
                    elif fs == CanTpFsTypes.CONTINUE_TO_SEND:
                        if state == CanTpState.WAIT_FLOW_CONTROL:
                            if fs == CanTpFsTypes.CONTINUE_TO_SEND:
                                bs = rxPdu[FC_BS_INDEX]
                                if (bs == 0):
                                    bs = 585
                                blockList = self.create_blockList(
                                    payload[payloadPtr:], bs)
                                stMin = self.decode_stMin(
                                    rxPdu[FC_STMIN_INDEX])
                                currBlock = blockList.pop(0)
                                state = CanTpState.SEND_CONSECUTIVE_FRAME
                                stMinTimer.timeoutTime = stMin
                                stMinTimer.start()
                                timeoutTimer.stop()
                        else:
                            raise Exception(
                                "Unexpected Flow Control Continue to Send request"
                            )
                    else:
                        raise Exception("Unexpected fs response from ECU")
                else:
                    raise Exception("Unexpected response from device")

            if state == CanTpState.SEND_SINGLE_FRAME:
                txPdu[N_PCI_INDEX] += (CanTpMessageType.SINGLE_FRAME << 4)
                txPdu[SINGLE_FRAME_DL_INDEX] += payloadLength
                txPdu[SINGLE_FRAME_DATA_START_INDEX:] = fillArray(
                    payload, self.__maxPduLength)
                self.transmit(txPdu, functionalReq)
                endOfMessage_flag = True
            elif state == CanTpState.SEND_FIRST_FRAME:
                payloadLength_highNibble = (payloadLength & 0xF00) >> 8
                payloadLength_lowNibble = (payloadLength & 0x0FF)
                txPdu[N_PCI_INDEX] += (CanTpMessageType.FIRST_FRAME << 4)
                txPdu[FIRST_FRAME_DL_INDEX_HIGH] += payloadLength_highNibble
                txPdu[FIRST_FRAME_DL_INDEX_LOW] += payloadLength_lowNibble
                txPdu[FIRST_FRAME_DATA_START_INDEX:] = payload[0:self.
                                                               __maxPduLength -
                                                               1]
                payloadPtr += self.__maxPduLength - 1
                self.transmit(txPdu, functionalReq)
                timeoutTimer.start()
                state = CanTpState.WAIT_FLOW_CONTROL
            elif state == CanTpState.SEND_CONSECUTIVE_FRAME:
                if (stMinTimer.isExpired()):
                    txPdu[N_PCI_INDEX] += (
                        CanTpMessageType.CONSECUTIVE_FRAME << 4)
                    txPdu[
                        CONSECUTIVE_FRAME_SEQUENCE_NUMBER_INDEX] += sequenceNumber
                    txPdu[
                        CONSECUTIVE_FRAME_SEQUENCE_DATA_START_INDEX:] = currBlock.pop(
                            0)
                    payloadPtr += self.__maxPduLength
                    self.transmit(txPdu, functionalReq)
                    sequenceNumber = (sequenceNumber + 1) % 16
                    stMinTimer.restart()
                    if (len(currBlock) == 0):
                        if (len(blockList) == 0):
                            endOfMessage_flag = True
                        else:
                            timeoutTimer.start()
                            state = CanTpState.WAIT_FLOW_CONTROL
                            #print("waiting for flow control")

            txPdu = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
            # timer / exit condition checks
            if (timeoutTimer.isExpired()):
                raise Exception("Timeout waiting for message")

            sleep(0.001)
コード例 #8
0
 def testIsExpiredWith0Time(self):
     a = ResettableTimer(0)
     a.start()
     self.assertEqual(False, a.isRunning())
     self.assertEqual(True, a.isExpired())
コード例 #9
0
 def testStateAfterTimeoutTime(self):
     a = ResettableTimer(0.2)
     a.start()
     sleep(0.25)
     self.assertEqual(False, a.isRunning())
     self.assertEqual(True, a.isExpired())
コード例 #10
0
 def testStateWhenInitialised(self):
     a = ResettableTimer(0.6)
     self.assertEqual(False, a.isRunning())
     self.assertEqual(False, a.isExpired())