This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F280025:LIN 从器件响应

Guru**** 2609955 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1580072/tms320f280025-lin-slave-response

器件型号:TMS320F280025


C2k 团队、

我试图对一些设备进行 LIN MITM 攻击、并尝试为 LIN 外设编写一些驱动程序。  似乎没有任何文件或示例说明如何推动奴隶的响应。  我唯一能找到的是:

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1114621/tms320f280049c-lin-module-in-slave-mode---how-to-initiate-response-transmission

在此处发布的示例中、用户只能响应单个 ID。  该示例还告诉我、底层状态机希望在允许从器件响应之前看到 TX ID 匹配吗?  这是真的吗?

我正在尝试编写一个基于中断的驱动程序、在该驱动程序中、我管理与处理器的所有通信、不使用任何滤波/屏蔽。  我能够全天接收消息。  当我获得用于从器件响应消息的 ID 中断时、我将数据复制到 TX 缓冲区、但始终不会被发送出去、并且首次运行后、isTxReady 检查失败。

这是我的 ISR:

__interrupt void
LIN_linAHandler(void)
{
    uint16_t interruptCause;

    //
    // Read the high priority interrupt vector
    //
    interruptCause = LIN_getInterruptLine0Offset(LINA_BASE);
    switch(interruptCause)
    {
    case LIN_VECT_ID:
    {
        linMessageObject_t *message;
        volatile uint16_t messageId;
        messageId = LIN_getRxIdentifier(LINA_BASE);
        message = LIN_linGetMessageObjectById(messageId);

        if(message != 0)
        {
            //Set frame length so it may be received correctly
            LIN_setFrameLength(LINA_BASE, message->len);

            //Calculate period
//            message->period = timer0getCount() - message->lastRxTime;
//            message->lastRxTime = timer0getCount();

            //If the message is TX its showtime baybee!
            if((message->direction == LINMESSAGE_TO_MASTER) && injectionActive)
            {
//                LIN_linTx(LINA_BASE, message);
                if(LIN_isTxReady(LINA_BASE))
                {
                    //
                    // Write data to Tx Buffer of LINA
                    //
                    LIN_sendData(LINA_BASE, message->originalData);
                }
            }

            //If the message is RX we are done
        }


        //Clear Interrupt Status
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_ID);
        break;
    }

    case LIN_VECT_RX:
    {
        linMessageObject_t *message;
        volatile uint16_t dumpBuffer[8];
        message = LIN_linGetMessageObjectById(LIN_getRxIdentifier(LINA_BASE));



        if(message != 0)
        {
            if((message->direction == LINMESSAGE_TO_SLAVE) )//|| !injectionActive)
            {
                LIN_getData(LINA_BASE, message->originalData);

            }else
            {
                //We gots a problem
                //Data in the rx buffer we don't know what to do with.
//                ESTOP0;
                LIN_getData(LINA_BASE, dumpBuffer);
            }
        }else
        {
            LIN_getData(LINA_BASE, dumpBuffer);
        }

        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_RX);
        break;
    }
    case LIN_VECT_TX:
    {
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_TX);
        break;
    }
    case LIN_VECT_CE:
    {
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_CE);
//        ESTOP0;
        break;
    }
    case LIN_VECT_FE:
    {
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_FE);
//        ESTOP0;
        break;
    }
    case LIN_VECT_OE:
    {
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_OE);
//        ESTOP0;
        break;
    }
    case LIN_VECT_BE:
    {
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_BE);
//        ESTOP0;
        break;
    }
    case LIN_VECT_NRE:
    {
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_NRE);
//        ESTOP0;
        break;
    }
    case LIN_VECT_PBE:
    {
        LIN_clearInterruptStatus(LINA_BASE, LIN_INT_PBE);
//        ESTOP0;
        break;
    }
    default:
        ESTOP0;
    }


    LIN_clearGlobalInterruptStatus(LINA_BASE, LIN_INTERRUPT_LINE0);

    //
    // Acknowledge this interrupt located in group 8
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
}

有什么想法我做错了?  当这样的关键功能没有记录下来并且没有示例时、这是非常令人沮丧的。 Cryμ s

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是我的初始化代码、如果调试很有帮助...

        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_LINA);
    
        GPIO_setPinConfig(DEVICE_GPIO_CFG_LINA_TX);
        GPIO_setDirectionMode(DEVICE_GPIO_PIN_LINA_TX, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_LINA_TX, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_LINA_TX, GPIO_QUAL_ASYNC);
    
        GPIO_setPinConfig(DEVICE_GPIO_CFG_LINA_RX);
        GPIO_setDirectionMode(DEVICE_GPIO_PIN_LINA_RX, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_LINA_RX, GPIO_PIN_TYPE_STD);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_LINA_RX, GPIO_QUAL_ASYNC);
    
        //
        // Interrupts that are used in this example are re-mapped to
        // ISR functions found within this file.
        // This registers the interrupt handler in PIE vector table.
        //
        Interrupt_register(INT_LINA_0, &LIN_linAHandler);
    
        //
        // Enable the LIN interrupt signals
        //
        Interrupt_enable(INT_LINA_0);
    
        //
        // Initialize the LIN module
        //
    
        EALLOW;
    
        //
        // Reset LIN module
        // Release from hard reset
        //
        LIN_disableModule(LINA_BASE);
        LIN_enableModule(LINA_BASE);
    
        //
        // Enter Software Reset State
        //
        LIN_enterSoftwareReset(LINA_BASE);
    
        //
        // Enable LIN Mode
        //
        LIN_disableSCIMode(LINA_BASE);
    
        //
        // Set LIN mode to Master
        //
        LIN_setLINMode(LINA_BASE, LIN_MODE_LIN_SLAVE);
    
        //
        // Enable Fixed baud rate mode
        //
        LIN_enableAutomaticBaudrate(LINA_BASE);
    
        //
        // Use the set frame length and not ID4/ID5 bits for length control
        //
        LIN_setCommMode(LINA_BASE, LIN_COMM_LIN_USELENGTHVAL);
    //    LIN_setCommMode(LINA_BASE, LIN_COMM_LIN_ID4ID5LENCTL);
    
        //
        // Setup to continue operating on emulation suspend
        //
        LIN_setDebugSuspendMode(LINA_BASE, LIN_DEBUG_COMPLETE);
    
        //
        // Use Enhanced Checksum
        //
        LIN_setChecksumType(LINA_BASE, LIN_CHECKSUM_ENHANCED);
    
        //DISABLE CHECKSUM
        HWREG_BP(LINA_BASE + LIN_O_SCIGCR2) &= ~LIN_SCIGCR2_CC;
    
        //
        // Message filtering uses slave task ID byte
        //
        LIN_setMessageFiltering(LINA_BASE, LIN_MSG_FILTER_IDSLAVE);
    
        //
        // Disable Internal loopback for external communication
        //
        LIN_disableIntLoopback(LINA_BASE);
    
        //
        // Enable multi-buffer mode
        //
        LIN_enableMultibufferMode(LINA_BASE);
    
        //
        // Enable parity check on received ID
        //
    //    LIN_enableParity(LINA_BASE);
    
        //
        // Enable transfer of data to and from the shift registers
        //
        LIN_enableDataTransmitter(LINA_BASE);
        LIN_enableDataReceiver(LINA_BASE);
    
        //
        // Enable the triggering of checksum compare on extended frames
        //
    //    LIN_triggerChecksumCompare(LINA_BASE);
    
        //
        // Set LIN interrupts to enabled
        //
        LIN_disableInterrupt(LINA_BASE, LIN_INT_ALL);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_RX);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_ID);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_CE);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_FE);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_OE);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_BE);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_NRE);
        LIN_enableInterrupt(LINA_BASE, LIN_INT_PBE);
    
        LIN_setInterruptLevel0(LINA_BASE, LIN_INT_ALL);
    
    
        LIN_enableGlobalInterrupt(LINA_BASE, LIN_INTERRUPT_LINE0);
        LIN_clearGlobalInterruptStatus(LINA_BASE, LIN_INTERRUPT_LINE0);
    
        //
        // Set Baud Rate Settings - 100MHz Device
        //
        LIN_setBaudRatePrescaler(LINA_BASE, 96U, 11U);
        LIN_setMaximumBaudRate(LINA_BASE, 100000000U);
    
        //
        // Set response field to 1 byte
        //
        LIN_setFrameLength(LINA_BASE, 1U);
    
        //
        // Configure sync field
        // Sync break (13 + 5 = 18 Tbits)
        // Sync delimiter (1 + 3 = 4 Tbits)
        //
        LIN_setSyncFields(LINA_BASE, 5U, 3U);
    
        //
        // Set Mask ID so TX/RX match will always happen
        //
        LIN_setTxMask(LINA_BASE, 0xFFU);
        LIN_setRxMask(LINA_BASE, 0xFFU);
    
        //
        // Disable IODFT testing and external loopback mode
        //
        LIN_disableExtLoopback(LINA_BASE);
    
        //
        // Finally exit SW reset and enter LIN ready state
        //
        LIN_exitSoftwareReset(LINA_BASE);
    
        EDIS;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在这方面取得了一些进展。  我使用的是一辆系统电压为 24V 的汽车。  因此、我用 24V 电压为电路板供电、因此我的 LIN 节点在该电平下运行。  我想我的注意力不够密切、因为我错过了车辆 LIN 总线的其余部分以 12V 运行。  将电路板交换到 12V 电源似乎已经导致电路板能够开始作为从器件回复消息。  仍然需要更多时间来完全验证、但我认为这是导致问题的根本原因。

    我仍然想问的是、TRM 中详细说明了这一功能、并提供了一些示例。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Trey:

    C2000 LIN 没有从设备示例肯定是一个缺口、我们将在后续软件版本中尝试修复此问题、感谢您提请我们注意、由此带来的挫折感令我深感歉意。 如果将来对 TRM 进行任何更新、我还可以确保在文档中对此进行了更新。  

    在进行更多验证后、如果您有任何其他问题、请告诉我。  

    此致、

    Delaney