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.

[参考译文] CCS/TM4C1294NCPDT:在 RX 消息目标 ISR 中调用 CANMessageGet 时、有时进入 FaultISR 的程序(它运行3-4次、之后进入 FaultISR)。

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/704576/ccs-tm4c1294ncpdt-the-program-to-go-faultisr-sometimes-it-working-for-3-4-times-and-after-that-go-to-faultisr-when-calling-canmessageget-in-rx-message-object-isr

器件型号:TM4C1294NCPDT

工具/软件:Code Composer Studio

我正在使用 TX 软件 FIFO 和 RX 软件 FIFO 来开发 CANBUS 库。

我实现了接收数据并在 ISR 中放入 RX FIFO。 但是、当程序大约接收3-4次(随机)的消息时、它会转到 FaultISR。

然后、我找到问题所在、并在函数 CANMessageGet 中发现它存在故障。 然后、我使用以下文档 http://www.ti.com/lit/an/spma043/spma043.pdf 中的诊断方法

我发现程序总是以2个不同的代码停止。

1) 1)在  CANBUS driverlib 的函数_CANDataRegRead 中。

 

2)在 编译器的 lib/src/memcpy_t2.asm 文件中。

我尝试找到更多解决方案。 并发现线程 Mdoe 和句柄模式不能同时调用函数 CANMessageSet 和 CANMessageGet。 然后、我在调用函数之前放置 IntDisable、并将 IntEnable 放置在线程模式代码中、以防止同时调用该2函数。 但问题仍然存在。

我现在不知道。 有人能帮助男人吗?

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

    感谢您参考故障 ISR 文档以开始针对此问题进行调试、非常有帮助!

    您提到了线程模式和句柄模式、您是否正在使用 RTOS? 您能否为这些函数发布代码? 虽然我理解您所介绍的内容、但我很难找到解决问题的方法、因为我对您的代码的结构没有任何了解。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     您好、Ralph、

     对于线程模式、我指的是在主循环中运行的代码。 对于 句柄模式、我是指在 ISR 上运行的代码。 很抱歉、如果我让您感到困惑。

    问题发生在401行。 如果我删除这一行。 该程序可以正常运行。

    #include "hal_ca.h"
    #include "hal_system.h"
    
    #include 
    #include 
    #include "inc/hw_memmap.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_ca.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/ca.h"
    #include "driverlib/interrupt.h"
    #include "driverlib_debug.f_sym.h"#include "#define "t_dec.n_ce.h"#define "t_ctrine.h"#include "driverlib_sym.inc_ctrine.h
    
    
    
    
    
    32U
    #define CAN_RX_BUF_LEN 32U
    
    #define TX_OBJECT_ID 32U
    #define RR_OBJECT_ID 31U
    #define RX_OBJECT_ID_BEGIN 1U
    #define RX_OBJECT_ID_END 30u
    
    #define DEFAULT_CAN_SPEED 125000U
    #define DEFAULT_CAN_RETRY 5u
    
    #define Sending _no 0U
    #define Sending;Yes 1U
    
    
    typedef 结构{
    uint32_t GPIO_TX_BASE;
    uint16_t GPIO_TX_Pin;
    uint32_t GPIO_TX_PIN_cfg;
    uint32_t GPIO_TX_SYSCTL_PERIPh;
    
    uint32_t GPIO_Rx_BASE;
    uint16_t GPIO_Rx_Pin;
    uint32_t GPIO_Rx_PIN_cfg;
    uint32_t GPIO_Rx_sysctl_periph;
    
    uint32_t CAN_BASE;
    uint32_t CAN_int;
    uint32_t SYSCTL_PERIPh;
    
    uint32_t OBJ_STATUS;
    
    uint8_t 发送;
    
    HAL_CAN_msg_t *TX_Buf;
    uint16_t TX_Buf_len;
    simple_q_t TX_q;
    
    HAL_CAN_msg_t * rx_buf;
    uint16_t RX_Buf_len;
    simple_q_t RX_q;
    }platform_context_t;
    
    static hal_can_msg_t g_CAN0_TX_BUf[CAN_TX_BUF_LEN];
    static hal_CAN_msg_t g_CAN0_RX_BUf[CAN_RX_BUF_LEN];
    
    static platform_context_t g_CAN0_ctx ={.}
    .GPIO_TX_BASE = GPIO_PORta_base、
    GPIO_TX_Pin = GPIO_PIN_1、
    GPIO_TX_PIN_cfg = GPIO_PA1_CAN0TX、
    .GPIO_TX_SYSCTL_PERIPh = SYSCTL_PERIPH_GPIOA、
    
    .GPIO_Rx_BASE = GPIO_PORta_base、
    GPIO_Rx_Pin = GPIO_PIN_0、
    GPIO_Rx_PIN_cfg = GPIO_PA0_CAN0RX、
    gpio_rx_sysctl_periph = SYSCTL_Periph_GPIOA、
    
    .TX_Buf = g_CAN0_TX_Buf、
    .TX_Buf_len = CAN_TX_BUF_LEN、
    
    Rx_Buf = g_CAN0_Rx_Buf、
    rx_Buf_len = CAN_RX_BUF_LEN、
    
    .cAN_BASE = CAN0_BASE、
    .cAN_int = INT_CAN0、
    .sysctl_periph = sysctl_Periph_CAN0、
    };
    
    静态 hal_can_t g_can[]={
    {.channel=0、.platform_data=&g_CAN0_ctx}
    ;
    
    static void clear_object (hal_can_t *p_hdl、uint8_t id);
    static uint8_t get_free_object (hal_can_t *p_hdl);
    static void t_zh_zh_t_zh_t_zh_translr (hal_doc_zh_t_zh_t_zh_zh_t_zh_ant_zh_t_zh_ant_zh_t_an_zh_event_zh_zh_zh_zh_t_t_zh_zh_t_t_an_zh_an_zh_zh_t_an_an_zh_zh_an_an_zh_zh_t_an_zh_an_an_zh_t_an_an_zh_an_an_zh_zh_an_ormandr
    、
    t_an_zh_an_an_zh_an_an_zh_zh_zh_an_zh_zh
    
    
    
    
    uint16_t i = 0;
    uint16_t ch_count = sizeof (g_can)/sizeof (hal_CAN_t);
    
    对于(i=0;i platform_data;
    
    /*清除所有对象句柄。 *
    P_ctx->obj_status = 0x00000000;
    p_ctx->发送=发送否;
    
    simple_q_init (&p_ctx->TX_q、p_ctx->TX_Buf、sizeof (hal_CAN_msg_t)、p_ctx->TX_Buf_len);
    simple_q_set_overwrite (&p_ctx->TX_q、simple_Q_OVERWRITABLE);
    simple_q_init (&p_ctx->rx_q、p_ctx->rx_buf、sizeof (hal_can_msg_t)、p_ctx->rx_buf_len);
    
    SysCtlPeripheralEnable (p_ctx->GPIO_Rx_SYSCTL_PERIPh);
    SysCtlPeripheralEnable (p_ctx->GPIO_TX_SYSCTL_PERIPh);
    
    GPIOPinConfigure (p_ctx->GPIO_Rx_PIN_cfg);
    GPIOPinConfigure (p_ctx->GPIO_TX_PIN_cfg);
    
    GPIOPinTypeCAN (p_ctx->GPIO_Rx_BASE、p_ctx->GPIO_Rx_Pin);
    GPIOPinTypeCAN (p_ctx->GPIO_TX_BASE、p_ctx->GPIO_TX_Pin);
    
    SysCtlPeripheralEnable (p_ctx->sysctl_periph);
    
    CANInit(p_ctx->CAN_BASE );
    CANBitRateSet (p_ctx->CAN_BASE、hal_system_get_clock ()、default_CAN_speed);
    
    CANIntEnable (p_ctx->CAN_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
    
    IntPrioritySet (p_ctx->CAN_int、0x40);
    IntEnable (p_ctx->CAN_int);
    
    CANEnable (p_ctx->CAN_BASE);
    CANRetrySet (p_ctx->CAN_BASE、DEFAULT_CAN_RETRY);
    
    返回 HAL_CAN_SUCCESS;
    }
    
    hal_CAN_Result_t hal_CAN_SET_retry (hal_CAN_t * p_hndl、hal_CAN_Bool_t retry)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    
    如果(重试= HAL_CAN_TRUE){
    CANRetrySet (p_ctx->CAN_BASE、TRUE);
    } 否则{
    CANRetrySet (p_ctx->CAN_BASE、false);
    }
    
    返回 HAL_CAN_SUCCESS;
    }
    
    hal_CAN_Result_t hal_CAN_SET_speed (hal_CAN_t * p_hndl、uint32_t speed)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    
    CANBitRateSet (p_ctx->CAN_BASE、hal_system_get_clock()、speed);
    
    返回 HAL_CAN_SUCCESS;
    }
    
    uint16_t hal_CAN_SEND (hal_CAN_t * p_hndl、const hal_CAN_msg_t * p_msg)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    HAL_CAN_Result_t 结果= HAL_CAN_SUCCESS;
    
    IntDisable (p_ctx->CAN_int);
    
    if (p_ctx->sending = sending _no){
    SEND_DATA (p_hndl、p_msg);
    p_ctx->发送=发送_是;
    结果= HAL_CAN_SUCCESS;
    } 否则{
    if (simple_q_push (&p_ctx->TX_q、p_msg)=simple_q_succeeding){
    结果= HAL_CAN_SUCCESS;
    } 否则{
    结果= HAL_CAN_FAIL;
    }
    }
    
    IntEnable (p_ctx->CAN_int);
    
    返回结果;
    }
    
    hal_CAN_Result_t hal_CAN_SEND_RR (hal_CAN_t *p_hdl、uint32_t dst、hal_CAN_RR_TY_t 类型)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    tMsgObjType msg_type = MSG_OBJ_TYPE_RX;
    tCANMsgObject msg;
    
    MSG.ui32MsgID = dst;
    MSG.pui8MsgData = 0;
    MSG.ui32MsgLen = 0;
    
    if (type = HAL_CAN_RR_RX){
    MSG_TYPE = MSG_OBJ_TYPE_RX_REMOTE;
    } 否则、如果(type = HAL_CAN_RR_TX){
    MSG_TYPE = MSG_OBJ_TYPE_TX_REMOTE
    ;} 否则、如果(type = HAL_CAN_RR_TXRX){
    MSG_TYPE = MSG_OBJ_TYPE_RxTx_REMOTE
    ;}
    
    /*线程模式和句柄模式不能同时调用 CANMessageSet 和 CANMessageGet。 *
    IntDisable (p_ctx->CAN_int);
    CANMessageSet (p_ctx->CAN_BASE、RR_object_ID、&msg、msg_type);
    IntEnable (p_ctx->CAN_int);
    
    返回 HAL_CAN_SUCCESS;
    }
    
    hal_CAN_Result_t hal_CAN_SET_Receive (hal_CAN_t * p_ndl、const hal_CAN_filter_t * p_filter、uint16_t * rtn_id)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    tCANMsgObject msg_obj;
    uint8_t id = 0;
    
    ID = get_free 对象(p_hndl);
    
    if (id!= 0xff){
    if (rtn_id!= 0){
    *rtn_id = id;
    }
    
    MSG_obj.ui32MsgID = p_filter->frame_id;
    MSG_obj.ui32MsgIDMask = p_filter->frame_id_mask;
    MSG_OBJ.ui32Flags = MSG_OBJ_USE_ID_FILTER | MSG_OBJ_RX_INT_ENABLE;
    
    /*线程模式和句柄模式不能同时调用 CANMessageSet 和 CANMessageGet。 *
    IntDisable (p_ctx->CAN_int);
    CANMessageSet (p_ctx->CAN_BASE、id、&msg_obj、MSG_OBJ_TYPE_RX);
    IntEnable (p_ctx->CAN_int);
    
    返回 HAL_CAN_SUCCESS;
    } 否则{
    返回 HAL_CAN_FAIL;
    }
    }
    
    hal_CAN_Result_t hal_CAN_clear_receive (hal_CAN_t * p_hndl、uint16_t id)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    
    IntDisable (p_ctx->CAN_int);
    
    CANMessageClear (p_ctx->CAN_BASE、id);
    clear_object (p_hndl、id);
    
    IntEnable (p_ctx->CAN_int);
    
    返回 HAL_CAN_SUCCESS;
    }
    
    uint16_t hal_CAN_is _available (hal_CAN_t * p_hndl)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    uint16_t 大小= 0;
    
    IntDisable (p_ctx->CAN_int);
    size = simple_q_size (&p_ctx->Rx_q);
    IntEnable (p_ctx->CAN_int);
    
    返回大小;
    }
    
    hal_CAN_Result_t hal_CAN_read (hal_CAN_t * p_hndl、hal_CAN_msg_t * p_rtn_msg)
    {
    platform_context_t * p_ctx =(platform_context_t*) p_hndl->platform_data;
    }
    
    void hal_can_tick (hal_can_t * p_hndl、uint32_t ms)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hnddl->platform_data;
    
    }
    
    void hal_can_IRQ (hal_can_t *p_hndl)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    uint32_t int_status = 0;
    uint32_t CAN_STATUS = 0;
    uint32_t CAN_LEC = 0;
    uint8_t object_index = 0;
    
    INT_STATUS = CANIntStatus (p_ctx->CAN_BASE、CAN_INT_STS_CAUST);
    
    if (int_status = CAN_INT_INTID_STATUS){
    CANIntClear (p_ctx->CAN_BASE、CAN_INT_INTID_STATUS);
    
    CAN_STATUS = CANStatusGet (p_ctx->CAN_BASE、CAN_STS_CONTROL);
    
    if ((CAN_STATUS & CAN_STATUS_TXOK)=CAN_STATUS_TXOK){
    
    }
    
    if ((CAN_STATUS & CAN_STATUS_RXOK)=CAN_STATUS_RXOK){
    
    }
    
    CAN_LEC = CAN_STATUS & CAN_STATUS_LEC_MASK;
    
    if (CAN_LEC!= CAN_STATUS_LEC_NONE){
    /*发生总线关闭。 重新启用它。 *
    if ((CAN_STATUS & CAN_STATUS_BUS_OFF)= CAN_STATUS_BUS_OFF){
    CANEnable (p_ctx->CAN_BASE);
    }
    }
    
    否则、如果((int_status >0)&&(int_status <= 32)){
    /*消息对象中断。 *
    object_index = int_status;
    
    if ((object_index >= RX_object_ID_begin)&&
    (object_index <= RX_object_ID_end){
    
    /* RX 中断。 *
    RX_IRQ_handler (p_hndl、object_index);
    } 否则、如果(object_index = rrr_object_ID){
    /* RR 中断。 *
    rr_irq_handler (p_hndl、object_index);
    } 否则、如果(object_index = TX_object_ID){
    /* TX 中断。 *
    TX_IRQ_handler (p_hndl、object_index);
    }
    
    }
    
    
    静态空 clear_object (hal_ca_t *p_hndl,uint8_t id)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    
    p_ctx->obj_status &&~(1 << id);
    }
    
    静态 uint8_t get_free_object (hal_can_t *p_hndl)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    uint8_t i = 0;
    uint8_t id = 0xff;
    
    对于(i=RX_OBJECT_ID_BEGIN;i<=RX_OBJECT_ID_END;i++){
    如果((p_ctx->obj_status &(1< obj_status |=(1< platform_data;
    tCANMsgObject msg;
    
    MSG.ui32MsgID = p_msg->id;
    MSG.pui8MsgData =(uint8_t*) p_msg->data;
    MSG.ui32MsgLen = p_msg->data_len;
    MSG.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
    
    CANMessageSet (p_ctx->CAN_BASE、TX_OBJECT_ID、&msg、MSG_OBJ_TYPE_TX);
    }
    
    静态空 TX_IRQ_handler (hal_CAN_t * p_hndl、uint8_t object_id)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    HAL_CAN_msg_t msg;
    
    CANIntClear (p_ctx->CAN_BASE、object_id);
    
    如果(simple_q_size (&p_ctx->TX_q)> 0){
    simple_q_pop (&p_ctx->TX_q、&msg);
    SEND_DATA (p_hndl、&msg);
    } 否则{
    p_ctx->发送=发送否;
    }
    
    //debug_print ("TX IRQ:id="%d、flags=0x%.8x\r\n"、object_id、p_msg->ui32Flags);
    }
    
    静态空 Rx_IRQ_handler (hal_can_t *p_hndl、uint8_t object_id)
    {
    volatile platform_context_t *p_ctx =(volatile platform_context_t*) p_hnddl->platform_data;
    HAL_CAN_msg_t msg;
    tCANMsgObject CAN_msg;
    
    CANIntClear (p_ctx->CAN_BASE、object_id);
    
    /*从硬件获取消息对象。 *
    CANMessageGet (p_ctx->CAN_BASE、object_id、CAN_msg、true);
    //
    msg.data_len = p_msg->ui32MsgLen;
    // memcpy (msg.data、p_msg->pui8&MsgData、msg.data_len);
    // memcp_msgid =简单
    
    的 msg&sgq;//
    
    DEBUG_PRINT ("RX IRQ:id=%d、flags=0x%.8x\r\n"、object_id、CAN_msg.ui32Flags);
    }
    
    静态空 RR_IRQ_handler (hal_CAN_t * p_hndl、uint8_t object_id)
    {
    platform_context_t *p_ctx =(platform_context_t*) p_hndl->platform_data;
    
    //debug_print ("RR IRQ:flags=0x%.8x\r\n"、p_msg->ui32Flags);
    }
    

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

    [引用 user="Burin SAPSIRi">问题发生在第401行。 如果我删除这一行。 该程序可以正常运行。[/quot]

    您(是否意识到)第401行(提交时)基本上是空白的-您不是?    始终最好选择"列出故障代码"-以消除(任何)疑虑!

    怀疑'tCANMsgObject CAN_msg;' 是提到的行-但这不能保证...

    *** 请注意,“ tCANMsgObject msg” (之前出现两次)报告已成功。    可能(这)是 您(相反)的意图?

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

    我认为第401行是:

    CANMessageGet (p_ctx->CAN_BASE、object_id、CAN_msg、true); 

    由于我不知道故障条件发生时的寄存器值、因此我假设要存储 CAN 数据的位置的指针已损坏。 这应该是一个自动变量的地址 tCANMsgObject can_msg.This should be on the stack. What address did it try to write to? Is this a stack overflow issue?

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

    尊敬的 Bob:

      非常感谢。

      这是问题的关键。 我忘记了为目标缓冲区分配要读取的地址。

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

    也许在座的人(仍然)想知道、在失败之前、"被遗忘的地址"是如何工作的、至少3到4次?    (事实直接取自海报的主题/标题:(它运行3-4次-然后转至 Fault_ISR。)

    "被遗忘的地址"(以某种方式到达可用的地址位置)甚至重复成功3次、这一事实证明很难接受-甚至更难理解...

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

    我想堆栈声明的变量没有初始化、变量内的值将是存储在该地址上的前一个值。 指针的值不是无效地址。 这就是为什么它可以工作一段时间。

    但是、当指针的值指向无效地址时、它将是非法访问。 并转至故障 ISR。

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

    我对这种"思考"不是那么"关心"。

    原因如下: someway /某种程度上是一个"有效地址"(具体化)、这使3-4次 CAN 总线传输成功。   这会导致以下问题-如果"真正理解"是一个问题:

    • 编译器(或其他一些 MCU/编程器件)是否可以(真正)成功"生成"正确地址的机制?   (我不知道-但我知道、"依赖"不保证/认证初始化"-是灾难的可能!   (在许多关键学科(其中一些学科)中、显然是不允许的、我的公司提供...)
    • 及时(在这3-4个报告"厚度"后-您的流程"故障"。   然而-如果它适用于3-4次尝试-为什么您的"新方法"不会受到(相同) 3-4次限制?   在每次调用函数之前、是否重新加载了正确的地址(以确保最大的安全性)?
    • 我相信、当人们"真正理解"时、就可以"按需指挥故障!"   (即、您完全知道如何创建一  个)硬币的另一面-"避免错误"需要仔细研究并"排除"各种"故障机制-以便每个都可以有效地"防护带"-理想情况下可以防止!

    我不相信你已经达到了那个“神圣的地方”——

    您的代码揭示了巧妙的巧妙结合和复杂性-设计严格的测试程序-真正造成"压力"-可能证明是一项值得的练习...   (至少值得考虑...)