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.
工具/软件: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函数。 但问题仍然存在。
我现在不知道。 有人能帮助男人吗?
您好、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); }
我认为第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 总线传输成功。 这会导致以下问题-如果"真正理解"是一个问题:
我不相信你已经达到了那个“神圣的地方”——
您的代码揭示了巧妙的巧妙结合和复杂性-设计严格的测试程序-真正造成"压力"-可能证明是一项值得的练习... (至少值得考虑...)