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.

[参考译文] MSP432E401Y:续:CAN 控制器模块在系统启动时有时不可用

Guru**** 2577385 points
Other Parts Discussed in Thread: MSP-EXP432E401Y

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/874777/msp432e401y-continued-can-controller-module-sometimes-unavailable-at-system-startup

器件型号:MSP432E401Y
主题中讨论的其他器件:MSP-EXP432E401Y

我关于此主题的第一个主题已锁定、但此问题未解决。

我已经使用从 CCS 应用商店下载的“cangpioxrx”示例程序在 MSP-EXP432E401Y Launchpad 板上重现了该问题。

CAN 驱动程序是 SimpleLink SDK 中的库存驱动程序、我们未对其进行修改。

我已修改此示例应用以将 UART7用于控制台。

连接到引脚 PC4和 PC5的 RS-232转换器的逻辑电平提供串行输出。

这样做的原因是需要多次循环电源以捕获故障模式、而这种循环电源会断开调试器串行端口。

固态常闭继电器用于循环供电。

如果程序可以将其添加到 GPIO_WRITE 行(CONFIG_GPIO_CYCLEPOWER、1);

它不在故障模式下,然后重新启动电源。

PA7 GPIO 控制继电器输入。

继电器为 Crydom MPDCD3-B、它会中断我断开的 USB 电缆中的5V 线路。

 

在故障模式下、它会一直卡在 CAN_open 中、如下面的调用堆栈所示。 CAN0PDS 为4。

在3458引导时、故障模式发生5次、故障率为0.145%。

 调试器中的“系统重置”不会清除故障模式。 就我所能说的、只有循环通电才能实现这一目的。

 

 

 

终端输出:

==按 USR_SW1发送消息=

CAN0PDS 值@1 00000004

CAN0PDS 值@2 00000004

CAN0PDS 值@3 0000003F

==按 USR_SW1发送消息=

CAN0PDS 值@1 00000004

CAN0PDS 值@2 00000004

CAN0PDS 值@3 0000003F

==按 USR_SW1发送消息=

CAN0PDS 值@1 00000004

CAN0PDS 值@2 00000004

 

显示故障模式的方法不是将其设为“CAN0PDS Value @3 0000003F”

电源保持开启状态、因为它卡在 CAN_open 中、如图所示。

 

void * mainThread (void * arg0)
{
pthread_t 线程0;
pthread_attr_t attrs;
struct sched_param primParam;
内部 REC;
内部 detachState;
内部32_t 状态;

/*跟踪发送的帧*/
帧 Sent = 0;

/*调用驱动程序初始化函数*/
GPIO_init();
// CAN_init();
display_init();

/*
*打开 CAN 实例。
* CAN_PARAMS filterID 和 filterMask 决定要接收的消息。
*

// GEHC JCP 稍后移动此文件,使其不会在故障模式下挂起

// CAN_Params canParams;
// CAN_Params_init (&canParams);
// canParams.filterID = 0x001;
// canParams.filterMask = 0x001;
// CAN = CAN_open (CONFIG_CAN_0、&canParams);

/*打开 UART 的显示实例*/
Display_Params displayParams;
Display_Params_init (&displayParams);
Display = Display_open (Display_Type_UART、&displayParams);

display_print0 (display、0、0、"==按 USR_SW1发送消息="");

/*配置 LED 和按钮引脚*/
GPIO_setConfig (CONFIG_GPIO_LED_0、GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
GPIO_setConfig (CONFIG_GPIO_button_1、
GPIO_CFG_IN_pu | GPIO_CFG_IN_INT_FALLING);

/*
*创建同步信标;TX 显示将在此等待
*信号量、直到按下 GPIO 按钮。
*
状态= SEM_INIT (&txSem、0、0);
if (status!= 0){
Display_printf (display、0、0、"创建 txSem\n"Error);
while (1);
}

/*安装按钮回调*/
GPIO_setCallback (CONFIG_GPIO_button_1、gpioButtonFxn);

/*启用中断*/
GPIO_enableInt (CONFIG_GPIO_button_1);

/*创建应用程序线程*/
pthread_attr_init (atttrs);
priParam.sched_priority = 1;
pthread_attr_setschedparam (&attrs、&priParam);

detachState = pthread_create_detached;
retc = pthread_attr_setdetachstate (&attrs、detachState);
retc |= pthread_attr_setstacksize (&attrs、THREADSTACKSIZE);
retc |= pthread_create (&thread0、&attrs、txThread、NULL);
如果(retc!= 0){
/* pthread_create()失败*/
while (1);
}

/*
*每次接收到 CAN 帧时切换 Board_GPIO_LED0。
*还将接收到的 CAN 帧 ID 打印出到 UART 显示屏。
* CAN_Params filterID、filterMask 控制 CAN_Read 完成的频率。
*
CAN_Frame canFrame ={0};

// GEHC JCP
char jpstr[64];

unsigned long CAN0PDS =*(unsigned long*)(0x400FE298)); // TI 没有此寄存器的定义

sprintf (jpstr、"CAN0PDS 值@1 %08X"、CAN0PDS);
display_print0 (display、0、0、jpstr);

CAN_init();

CAN0PDS =*((unsigned long*)(0x400FE298));
sprintf (jpstr、"CAN0PDS 值@2 %08X"、CAN0PDS);
display_print0 (display、0、0、jpstr);


CAN_Params 和 CANParams;
CAN_Params_init (&canParams);
canParams.filterID = 0x001;
canParams.filterMask = 0x001;
CAN = CAN_OPEN (CONFIG_CAN_0、&CANParams);

CAN0PDS =*((unsigned long*)(0x400FE298)); //不会使其处于故障模式
sprintf (jpstr、"CAN0PDS 值@3 %08X"、CAN0PDS);
display_print0 (display、0、0、jpstr);

Task_sleep (1000);

GPIO_WRITE (CONFIG_GPIO_CYCLEPOWER、1);

//\ GEHC JCP

while (1){
CAN_Read (CAN、&canFrame、sizeof (canFrame));
Display_Print1 (显示、0、0、
"消息已接收。 接收到的帧 ID:0x%3x"、
canFrame.id);
GPIO_TOGGLE (CONFIG_GPIO_LED_0);
}
}

 

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

    您好!

    我已将其转发给团队成员以寻求支持。  

    此致、

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

    尊敬的 John:

    很抱歉耽误你的回答。 在 TI 驱动程序中、它可能是 CAN_open API 问题。 我在内部的相关资源中找到了一个问题、我们正在研究这个问题。  

    我将在有更新时立即提供更新。

    谢谢、

    Alexis

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

    尊敬的 John:

    我和我的同事在 CAN 上工作、这就是我收到的回复:  

    "从看、当 CAN_open 调用请求启用电源时、您似乎卡在电源驱动程序的这个代码块中。

    因此、电源驱动器会指示启用电源、然后等待获取外设已通电并准备就绪的标志、但绝不会接收到外设并陷入无限循环。 因此、不知怎么说、外设要么永远不会开启、要么启用电源的请求永远不会正确设置。 我建议首先查看的是时序。 在复位后,CAN 控制器准备就绪之前有一定的时间,因此我们可能正处于该时间的边缘。  将一个小的延迟输入代码中、看看这是否会影响此错误的频率、这可能是一个很好的起点。"

    如果添加延迟会增加误差的频率、请告诉我。  

    谢谢、

    Alexis

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

    您好 Alexis、

    我在 CAN_open()调用之前添加了一个 Task_sleep(10)。
    3245引导中发生了8次故障、发生次数为0.247%、比之前的0.145%更高、尽管这可能只是福禄克的统计数据。

    一旦芯片进入故障模式、我就可以连接调试器并单步执行代码、它仍然卡在 SysCtlPeripheralReady()中。

    在调试器中执行 CPU 复位或系统复位不会清除错误模式。

    如果有人提供了将项目上载到的位置、我可以上传项目的 zip 文件。

    -John Probert

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

    除上述内容外、还更改了 PowerMSP432E4.c 中的此代码

    while (!SysCtlPeripheralReady (id)
    ){
    // GEHC JCP
    asm (" nop");//浪费时间
    if (id =0xF0003400 &&++Breakit > 10000)
    {
    extern Display_Handle 显示;
    Display_print0 (display、0、0、"强制复位");
    //执行复位
    HWREG (NVIC_APINT)= NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ;
    }
    //\ GEHC JCP
    }; 

    在故障时刻之前和之后、结果是:

    ==按 USR_SW1发送消息=
    CAN0PDS 值@1 00000004
    CAN0PDS 值@2 00000004
    CAN0PDS 值@3 0000003F
    ==按 USR_SW1发送消息=
    CAN0PDS 值@1 00000004
    CAN0PDS 值@2 00000004
    CAN0PDS 值@3 0000003F
    ==按 USR_SW1发送消息=
    CAN0PDS 值@1 00000004
    CAN0PDS 值@2 00000004
    强制复位
    ==按 USR_SW1发送消息=
    CAN0PDS 值@1 00000004
    CAN0PDS 值@2 00000004
    强制复位
    ==按 USR_SW1发送消息=
    CAN0PDS 值@1 00000004
    CAN0PDS 值@2 00000004
    强制复位

    结论:

    线路

    HWREG (NVIC_APINT)= NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ; 

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

    最后一个帖子应该以结束

    "重置不够深入、无法清除问题。"

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

    我通过进一步的测试发现:

    /RESET 引脚置为有效/置为无效将清除错误。

    错误模式可通过 /RESET 引脚置为有效/置为无效而不进行下电上电操作来创建。

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

    经过广泛的测试、我找到了最适合简单调用的解决方案

    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_CAN0);

    引导代码中的代码。