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.

[参考译文] TMS320F2.8377万D:CAN_A在muxed到CPU2时不接收消息

Guru**** 2524460 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1094010/tms320f28377d-can_a-does-not-receive-messages-when-muxed-to-cpu2

部件号:TMS320F2.8377万D
主题中讨论的其他部件:C2000WARE

大家好,

与上一个帖子相关,我一直在尝试在CAN总线通过muxed发送到CPU2时使其正常工作。 我需要在CPU2而非CPU1中部署CAN消息。

我做了以下工作:

CPU1:

-设置mutxing和GPIOs

-将CAN_A分配给CPU2

CPU2:

—设置消息属性

—启用CAN中断

-启用Cana时钟

尽管如此,我仍然看不到收到的任何消息。 CPU1和CPU2都在运行,但当我通过CANbus发送消息时,在CPU2中看不到任何ISR触发器。 我可以看到,如果我只是在CPU1上启用相同的ISR,并仅使用该内核,这是最终用户软件规格所无法做到的。

我附加CPU1的代码(仅main(),因为我没有在此处触发ISR):

void main(void)
{
    InitSysCtrl();      // Initialize System Control (F2837xD_SysCtrl.c)

    EALLOW;
    // As GSxRAM is allocated to CPU2 below, GCB_cpu01 must be run before GCB_cpu02 can be loaded into target
    MemCfgRegs.GSxMSEL.bit.MSEL_GS5 = 1;            // allocate RAMGS5 to CPU02
    MemCfgRegs.GSxMSEL.bit.MSEL_GS6 = 1;            // allocate RAMGS6 to CPU02
    MemCfgRegs.GSxMSEL.bit.MSEL_GS7 = 1;            // allocate RAMGS7 to CPU02
    MemCfgRegs.GSxMSEL.bit.MSEL_GS8 = 1;            // allocate RAMGS8 to CPU02
    EDIS;

    // Init GPIOs
    InitGpio();

    // setting the GPIO for CPU2
    // Setup GPIO pin mux for CAN-A TX/RX and CAN-B TX/RX
    GPIO_SetupPinMux(36, GPIO_MUX_CPU2, 6); //GPIO36 -  CANRXA
    GPIO_SetupPinOptions(36, GPIO_INPUT, GPIO_ASYNC);
    GPIO_SetupPinMux(37, GPIO_MUX_CPU2, 6); //GPIO37 - CANTXA
    GPIO_SetupPinOptions(37, GPIO_OUTPUT, GPIO_PUSHPULL);

    //
    // Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    // Clear all interrupts and initialize PIE vector table
    DINT;
    InitPieCtrl();  // Clear all ENPIE bit and PIEIERx PIEIFRx registers
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable(); //

    // Wait here until CPU02 is ready
    while (IpcRegs.IPCSTS.bit.IPC17 == 0) ; // Wait for CPU02 to set IPC17
    IpcRegs.IPCACK.bit.IPC17 = 1;           // Acknowledge and clear IPC17

    // assign CAN_A to CPU2 (CPU2 is the owner)
    EALLOW;
    DevCfgRegs.CPUSEL8.bit.CAN_A = 1;
    EDIS;

    // dummy loop to check whether CPU1 is alive
    do{
        dummy_int++;
        DELAY_US(1000* 1000);
    }while(1);

}

对于CPU2 (main()加上ISR功能和CANbus设置功能):

void main(void)
{

    // Initialize System Control
   InitSysCtrl();

// Clear all interrupts and initialize PIE control registers
    DINT;
    InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags
    IER = 0x0000;
    IFR = 0x0000;

    // enable the clock for CANA
    EALLOW;
    CpuSysRegs.PCLKCR10.bit.CAN_A = 1;
    EDIS;

    SetCANbus(); // setup the CAN --- not messages specs yet (see beneath InitCANbus)

// Initialize the PIE vector table
    InitPieVectTable();

// Map ISR functions
    EALLOW;
    PieVectTable.CANA0_INT = &canaISR;        // mapping CANbus
    EDIS;

// Enable global interrupts and higher priority real-time debug events:
    IER |= M_INT9;          // Enable PIE group 9 interrupt (SCIB_RX, SCIB_TX, CANBUS)
    EINT;                   // Enable Global interrupt INTM
    ERTM;                   // Enable Global real-time interrupt DBGM

// Let CPU1 know that CPU2 is ready
    IpcRegs.IPCSET.bit.IPC17 = 1;       // Set IPC17 to release CPU1

// Enable the CAN-A interrupt on the processor (PIE).
    PieCtrlRegs.PIEIER9.bit.INTx5 = 1;      // first CANbus A interrupt

// init CANbus messages -- see function
    initCANbus();

    // dummy cycle for checking operation of CPU2
    for(;;){
            dummy_intCPU2++;
            DELAY_US(1000* 500);
        }

}


void SetCANbus(){

    // Initialize the CAN controllers
    CANInit(CANA_BASE);   // init CANA

    // Setup CAN to be clocked off the PLL output clock
    CANClkSourceSelect(CANA_BASE, 0);   // 500kHz CAN-Clock

    // 1Mbit/s
    CANBitRateSet(CANA_BASE, 200000000, 1000000);

    // Enable interrupts on the CAN A peripheral.
    CANIntEnable(CANA_BASE, CAN_INT_MASTER | CAN_INT_ERROR); // keep the error, NOT the status change for calling the ISR

}

void initCANbus(){
    //
    // Enable the CAN-B interrupt signal
    //
    CANGlobalIntEnable(CANA_BASE, CAN_GLB_INT_CANINT0);     // enable CANA

    // setting the CAN messages properties --------------------------------

    sRXCANMessage.ui32MsgID = 0x226;    // receive message from slave
    sRXCANMessage.ui32MsgIDMask = 0;
    sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;
    sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;
    sRXCANMessage.pucMsgData = rxMsgData;

    /* the following line is commented when only transmitting */
    CANMessageSet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, MSG_OBJ_TYPE_RX);

    //
    // Start CAN module A and B operations
    //
    CANEnable(CANA_BASE);
    // ---------------------------------------------------------------------------------
}

//
// CAN A ISR - The interrupt service routine called when a CAN interrupt is
//             triggered on CAN module A.
//
__interrupt void canaISR(void)
{

    trigger_receive++;

    // read CAN_A status
    status = CANIntStatus(CANA_BASE, CAN_INT_STS_CAUSE);

    //
    // If the cause is a controller status interrupt, then get the status
    //
    if(status == CAN_INT_INT0ID_STATUS)
    {
        // read CANA status and get it
        status_inner = CANStatusGet(CANA_BASE, CAN_STS_CONTROL);

        //
        // Check to see if an error occurred.
        //
        if(((status_inner  & ~(CAN_ES_RXOK)) != 7) &&
           ((status_inner  & ~(CAN_ES_RXOK)) != 0))
        {
            //
            // Set a flag to indicate some errors may have occurred.
            //
            errorFlag = 1;
        }
    }
    //
    // Check if the cause is the CAN-B receive message object 1
    //
    else if(status == RX_MSG_OBJ_ID)
    {
        //
        // Get the received message
        //
        CANMessageGet(CANA_BASE, RX_MSG_OBJ_ID, &sRXCANMessage, true);

        //
        // Getting to this point means that the RX interrupt occurred on
        // message object 1, and the message RX is complete.  Clear the
        // message object interrupt.
        //
        CANIntClear(CANA_BASE, RX_MSG_OBJ_ID);

        //
        // Increment a counter to keep track of how many messages have been
        // received. In a real application this could be used to set flags to
        // indicate when a message is received.
        //
        rxMsgCount++;

        //
        // Since the message was received, clear any error flags.
        //
        errorFlag = 0;

    }
    else
    {
        //
        // Spurious interrupt handling can go here.
        //
    }

    //
    // Clear the global interrupt flag for the CAN interrupt line
    //
    CANGlobalIntClear(CANA_BASE, CAN_GLB_INT_CANINT0);

    //
    // Acknowledge this interrupt located in group 9
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;

}

请您提供帮助,或建议我是否错过了什么?

谢谢!

尼古拉

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

    Nicola,

    我已将您的帖子分配给主题专家,但由于美国假期,请期待我们在星期一结束前回复您。

    最佳,

    Matthew

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

    Matthew,您好!

    非常感谢您的及时回复和更新。 我要等到星期一。

    最佳,

    尼古拉

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

    Nicola,

       CAN通信与CPU1正常工作表明没有硬件问题,这很好。 验证节点的传输操作比接收操作更容易。 您能否检查是否能够从CPU2进行传输? 请勿涉及任何中断。 只需传输(使用 C:\ti\c2000\c2000Ware_4_00_00\driverlib\f2837xd\examples\CPU1中2000中的2837的can_ex4_simple_transmit.c作为参考)。 成功完成此操作后,我们已验证CPU2是否正确拥有CAN模块。 如果传输正常,则没有理由不能接收。  

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

    Hareesh,您好!

    谢谢。 我使用的是位字段。 但是我只是尝试了变速器。 它在CPU2中不起作用,但在CPU1中起作用, 这是我无法理解的,因为强制GPIO多工显然没有任何效果,即我是否将GPIO _MUX_CPU2或GPIO _MUX_CPU1指定为GPIO _SetupPinMux的第二个输入,它实际上没有任何效果,所有权似乎始终属于CPU1。 因此,如果这适用于TX,则它对RX不起作用是有意义的。 我是否遗漏了一些东西来实现这种所有权转移? 我认为这是核心之间所有权转移所需的唯一事情。

    //----------------------------------

    //设置CPU2的GPIO
    //为CAN-A TX/RX和CAN-B TX/RX设置GPIO针脚多路复用
    GPIO_SetupPinMux (36,GPIO _MUX_CPU2,6);//GPIO36 - CANRXA
    GPIO设置PIN选项(36,GPIO输入,GPIO _异步);
    GPIO_SetupPinMux (37,GPIO _MUX_CPU2,6);//GPIO37 - CANTXA
    GPIO设置引脚选项(37,GPIO输出,GPIO推送);

    //----------------------------------

    非常感谢,

    尼古拉

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

    大家好,

    我丢失了与CPU2连接相关的字段CAN_A的DevCfgRegs CPUEL8寄存器。 因此,尽管将CANbus的所有权转让给CPU2,但外围设备最初并未连接。 现在它开始工作了。

    感谢您的建议。

    尼古拉