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.

[参考译文] RTOS/F28M36P63C2:在CAN总线上收到奇数消息后退出hwi后的HARDFAULT

Guru**** 2589265 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/660557/rtos-f28m36p63c2-hardfault-after-exiting-hwi-after-receiving-odd-message-on-canbus

部件号:F28M36P63C2
主题:controlSUITE中讨论的其他部件

工具/软件:TI-RTOS

您好,

在大约100个PCB上使用同一个CANopen驱动器工作了几年之后,从未遇到过问题,现在突然,我有一个设备连接到canbus,该设备在总线上发出虚假(非CANopen)和非常奇怪的消息 (例如,数据超过8字节的消息)。 这仅在启动此设备时,甚至在它发出启动消息之前。

因此,问题产生于非常奇怪的非CANopen协议类型的消息。

我激活了接收中断,当第一条消息进入时,处理器启动HWI,通过HWI,但在退出HWI时,处理器启动HARDFAULT。

代码:

#include "inc/HW_memmap.h"
#include "inc/HW_types.h"
#include "inc/HW_ints.h"

#include "inc/HW_NVIC.h"
#include "inc/HW_NVIC.h"#include "inc/HW_sysctl.h"#gp堆"inc/dc.xdilt #dc.xdil/xdim/<xdc.h>#indu/<inc/xdc.xdc.xdilt #indu/<inc/<inc/<inc/xdc.cru/<inc/<inc/xdc.xdidrab/<inc/sy>
#dc.cfg/sy>#idrabr.xdc/头


/xdc.xdc.xdc.h>









包含<inc/<inc/<inc/<inc/<inc/dc.cf/xdc.xdc/头/<inc/<inc/<inc/<inc/<inc.cfrabrabrabr.cfg/sy>#dc.cfg/sy>#idrabr.x






文件*/
#include <ti/IPC/MessageQ.h>
#include <ti/IPC/MultiProc.h>/*

BIOS标头文件*/
#include <ti/RBIOS/BIOS.h>
#include <ti/BufferBIOS/Headers/HeapBuf.h>
#include <ti/Buffer/Toxbuth><slot/toxbft/buti><slidio/bf><toxbidio/bidio/but/but/buti/buth>
#t/bf><toxbuti/buti/buti/buti/buti/buti/buti><bfh/bidi/buti/buti/buti/buti/bidi/buti>#dio/buti/buti/buth/buti>#dio/bf>#dio/buti/bidi/buti>#dio/buti/bf>#dio/bf


















		
UINT8		CAN1_NothingToTransmit;

UINT16		CAN0_MessageAmountFor10ms;
UINT16		CAN0_MessageAmountFor10msCounter;
UINT16		CAN1_MessageAmountFor10ms;
UINT16		CAN1_MessageAmountFor10msCounter;


unsigned long CAN0_RxBufferOverflow;
unsigned long CAN1_RxBufferOverflow;

unsigned long		long CAN0_NodeUpdate;
unsigned long		CAN1_NodeUpdate;

//*****************************************************************************************
// CAN0中断0
//*****************************************************************************************
void
CAN0Int0 (void)
{
未签名的long ulStatus;
无符号短整型索引;
tCANMsgObject sCANMessage;
无符号char数据[8];

//读取CAN中断状态以查找中断原因
ulStatus = CANIntStatus (CAN0_BASE,CAN_INT_STS_Cause);

//如果原因是控制器状态中断,则获取状态
IF (ulStatus == CAN_INT_INT0ID_STATUS)
{
	G_CAN0Status = CANStatusGet (CAN0_BASE,CAN_STS_CONTROL);
	如果(g_CAN0Status) g_BErrFlag =1;
}
//检查原因是否是来自邮箱的邮件
否则,如果(ulStatus < 32)
{
CAN0_MessageAmountFor10msCounter++;
sCANMessage.pucMsgData =数据;
	CANMessageGet (CAN0_BASE,ulStatus,(tCANMsgObject *)&sCANMessage,1);
		索引= CAN0RxBufferM.WriteIndex;
	如果(Index ==(CAN0BUFFERSIZE -1)) Index = 0;
	Else索引+= 1;
	IF (Can0RxBufferM.ReadIndex != Index)
	{
		IF (sCANMessage.ulMsgID > 2048)
		{
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].cob_id =0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].len = 0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[0]=0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[1]= 0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[2]= 0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[3]=0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[4]=0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[5]=0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[6]=0;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[7]= 0;
			Can0RxBufferM.WriteIndex =索引;

			semaphore_post(StartCan0Receive);//发送到任务:开始分析消息
		}
		其它
		{
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].cob_id = sCANMessage.ulMsgID;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].len = sCANMessage.ulMsgLen;
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[0]= Data[0];
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[1]= Data[1];
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[2]= Data[2];
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[3]= Data[3];
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[4]= Data[4];
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[5]= Data[5];
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[6]= Data[6];
			Can0RxBufferM.Message[Can0RxBufferM.WriteIndex].data[7]= Data[7];
			//将指针设置为缓冲区中的下一个空位置

			Can0RxBufferM.WriteIndex =索引;

			semaphore_post(StartCan0Receive);//发送到任务:开始分析消息
		}
	
	否则
		CAN0_RxBufferOverflow++;
}
//已发送邮箱:已发送传输
否则,如果(ulStatus == 32)
{
	CAN0_MessageAmountFor10msCounter++;
	//更新读取缓冲区指针,因为数据已传输
	Can0TxBufferM.ReadIndex++;
	IF (Can0TxBufferM.ReadIndex == CAN0BUFFERSIZE) Can0TxBufferM.ReadIndex =0;
	//检查要传输的其他消息
	IF (Can0TxBufferM.ReadIndex != Can0TxBufferM.WriteIndex)
	{
		// set sSEND mailbox
			sCANMessage.ulMsgID = Can0TxBufferM.Message[Can0TxBufferM.ReadIndex].cob_id;
			sCANMessage.ulMsgIDMask = 0;
			sCANMessage.ulFlags = MSG_TX_INT_enable;sCAN0TxMessage.BufferM.B.Msbf_Msbfrm.CANxT.CANMS_Bfr.CANxMES.MESSA.CAN.MESSAGE_MESSAGE_MS_MESSAGE.CAN.MESSAGE.CAN.MESSAGE.CAN.MESSAGE.CAN.MESSAGE.CANMS_MESSAMESSAGE.MESSAGE.MS_MESSAGE.CAN.MESSAGE.CANE.MESSAGE.MESSAGE.MS_MESSAGE.MS_MS_MS_MESSAGE.MESSAGE.CANO.MESSAGE.MESSAGE.MESSAGE.MESSAGE.
			
			
			
				
		ELSE CANMessageSet(CAN0_BASE, 32,&sCANMessage, MSG_OBJ_TYPE_TX);
		}
	ELSE CAN0_NothingToTransmit = 1;
	//清除中断
CANIntClear (CAN0_BASE,ulStatus);
}
否则
{
CANIntClear (CAN0_BASE,ulStatus);
}
}//*********************************************************************************************************



// CAN1中断0
//*****************************************************************************************

void
CAN1Int0 (void)
{
未签名的long ulStatus;
无符号短整型索引;
tCANMsgObject sCANMessage;
无符号char数据[8];

//读取CAN中断状态以查找中断原因
ulStatus = CANIntStatus (CAN1_BASE,CAN_INT_STS_Cause);

//如果原因是控制器状态中断,则获取状态
IF (ulStatus == CAN_INT_INT0ID_STATUS)
{
	G_CAN1Status = CANStatusGet (CAN1_BASE,CAN_STS_CONTROL);
	如果(g_CAN1Status) g_BErrFlag =1;
}
//检查原因是否是来自邮箱的邮件
否则,如果(ulStatus < 32)
{
CAN1_MessageAmountFor10msCounter++;
sCANMessage.pucMsgData =数据;
	CANMessageGet (CAN1_BASE,ulStatus,(tCANMsgObject *)&sCANMessage,1);
		索引= Can1RxBufferM.WriteIndex;
	如果(索引==(CAN1BUFFERSIZE -1))索引=0;
	Else索引+= 1;
	IF (Can1RxBufferM.ReadIndex != Index)
	{
		IF (sCANMessage.ulMsgID > 2048)
		{
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].cob_id =0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].len = 0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[0]=0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[1]= 0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[2]= 0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[3]=0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[4]=0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].DATA[5]=0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[6]=0;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[7]= 0;
			Can1RxBufferM.WriteIndex =索引;

			semaphore_post(StartCan1Receive);//发送到任务:开始分析消息
	}
	否则
	{

		Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].cob_id = sCANMessage.ulMsgID;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].len = sCANMessage.ulMsgLen;
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[0]= Data[0];
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[1]= Data[1];
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[2]= Data[2];
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[3]= Data[3];
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[4]= Data[4];
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[5]= Data[5];
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[6]= Data[6];
			Can1RxBufferM.Message[Can1RxBufferM.WriteIndex].data[7]= Data[7];
			//将指针设置为缓冲区中的下一个空位置

			Can1RxBufferM.WriteIndex =索引;

			semaphore_post(StartCan1Receive);//发送到任务:开始分析消息
		}
	
	else CAN1_RxBufferOverflow+;
}
//已发送邮箱:已发送传输
否则,如果(ulStatus == 32)
{
	CAN1_MessageAmountFor10msCounter++;
	//更新读取缓冲区指针,因为数据已传输
	Can1TxBufferM.ReadIndex++;
	IF (Can1TxBufferM.ReadIndex == CAN1BUFFERSIZE) Can1TxBufferM.ReadIndex =0;
	//检查要传输的其他消息
	IF (Can1TxBufferM.ReadIndex != Can1TxBufferM.WriteIndex)
	{
		// set send mailbox
			sCANMessage.ulMsgID = Can1TxBufferM.Message[Can1TxBufferM.ReadIndex].cob_id;
			sCANMessage.ulMsgIDMask = 0;
			sCANMessage.ulFlags = MSG_TX_INT_enable;
			sCANEMES.PxMsgData = Can1TxMessage.BufferM,
			
			CANE.Message
				= CANE1.TxBufferM, CAN.ST_MESSAM_消息类型CAN1CAN1CAN.ST_ST_STREM_
		ELSE CANMessageSet(CAN1_BASE,32,&sCANMessage,MSG_OBJ_TYPE_TX);
		}
	ELSE CAN1_NothingToTransmit = 1;
	//清除中断
CANIntClear (CAN1_BASE,ulStatus);
}
否则
{
CANIntClear (CAN1_BASE,ulStatus);
}
}//*********************************************************************************************************





//配置CAN0
//*****************************************************************************************
void
Board_initCAN0(void)
{
	tCANMsgObject sMsgObject;

	tCANBitClkParms CanClkParams;

//初始化全局变量
	CAN0_NothingToTransmit = 1;
	CAN0_MessageAmountFor10ms = 0;
	CAN0_MessageAmountFor10msCounter = 0;


	//初始化缓冲区
	Can0TxBufferM.ReadIndex = 0;
	Can0TxBufferM.WriteIndex = 0;

	Can0RxWriterM.ReadeIndex = 0;
	

	禁用缓冲区
HWREG (sysctl_MWRALLOW)= 0xA5A5A5A5;

// CAN总线0的外设
SysCtlPeripheralEnable(sysctl_Periph_GPIOA);

//配置GPIO引脚多工以选择这些引脚的CAN0功能。
//此步骤选择可用于这些引脚的替代功能。
//如果您的部件支持GPIO引脚功能多路复用,则必须执行此操作。
//请参阅数据表以查看每个引脚分配了哪些功能。

GPIOPinConfigure(GPIO_PA4_CAN0RX);
GPIOPinConfigure(GPIO_PA5_CAN0TX);

//在GPIO引脚上启用备用功能。 以上步骤选择
//可用的替代功能。 此步骤实际上启用
//这些引脚的替代功能,而不是GPIO。
GPIOPinTypeCAN (GPIO_Porta_base,GPIO PIN_4 | GPIO PIN_5);

//已为CAN设置GPIO端口和引脚。 CAN外围设备
//必须启用。
SysCtlPeripheralEnable(sysctl_Periph_CAN0);

//初始化CAN控制器
CANInit (CAN0_BASE);

//可以为设置计时,使M3/主子系统时钟不工作
CANClkSourceSelect(CAN0_BASE,CAN_CLK_M3);

//设置CAN总线的比特率。 此功能设置CAN
//额定配置的总线定时。 您可以实现更多的控制
//通过CAN总线定时,改为使用函数CANBitTimingSet()
//(如果需要)。
//此处,CAN总线设置为250 kHz。 在下面的函数中,
//调用SysCltlClockGatet()用于确定其时钟速率
//用于为CAN外围设备计时。 这可以替换为
//固定值(如果知道系统时钟的值),保存额外的值
//函数调用。

// CANBitRateSet (CAN0_BASE,SysClockGet (system_clock_speed),25万);

CanClkParams.uQuantumPrescaler = 50;//=> 250kBaud和8 quanta
CanClkParams.uSJW = 1;
CanClkParams.uSyncPropPhase1Seg = 6;// Phase1(+1)+ Phase2(+1)+1必须等于Quanta的数量
CanClkParams.uPhase2Seg = 1;//=> 87.5 % 采样

CANBitTimingSet(CAN0_BASE,&CanClkParams);

//在CAN外围设备上启用中断。 此示例使用静态
//中断处理程序的分配,表示处理程序的名称
//位于启动代码的矢量表中。 如果要使用动态
//矢量表的分配,则还必须调用CANIntRegister()
//此处。
// CANIntRegister (CAN0_BASE,CANIntHandler);//如果使用动态矢量
CANIntEnable (CAN0_BASE,CAN_INT_IE0);//| CAN_INT_STATUS | CAN_INT_ERROR);

//在RAM矢量表
// IntRegister中注册中断处理程序(INT_CAN0INT0,CAN0IntHandler);

//启用处理器上的CAN中断(NVIC)。
IntEnable (INT_CAN0INT0);


//重试时启用自动总线
HWREG (CAN0_BASE + CAN_O_CTL)|= CAN_CTL_ABO;
HWREG (CAN0_BASE + CAN_O_ABOTR)= 50;// 50 Vbus周期后

//启用CAN以进行操作。
CANEnable (CAN0_BASE);


Can0TxBufferM.BufferSize = CAN0BUFFERSIZE;
Can0RxBufferM.BufferSize = CAN0BUFFERSIZE;


//设置接收邮箱,忽略扩展的联合
sMsgObject.ulMsgID = 0x0;
sMsgObject.ulMsgIDMask = 0x1FFFFFF800;	//最大ID为127
sMsgObject.ulFlags = MSG_OBJ_FIFO | MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_EXT_FILTER;

CANMessageSet (CAN0_BASE,1,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE,2,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE,3,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE,4,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE,5,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE,6,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN0_BASE,7,&sMsgObject,MSG_OBJ_TYPE_RX);
sMsgObject.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_EXT_FILTER;
CANMessageSet (CAN0_BASE,8,&sMsgObject,MSG_OBJ_TYPE_RX);

}//*************************************************************************************************


//配置CAN1
//*****************************************************************************************
void
Board_initCAN1(void)
{
	tCANMsgObject sMsgObject;

	tCANBitClkParms CanClkParams;

	//初始化全局变量
	CAN1_NothingToTransmit =1;

	//初始化缓冲区
	Can1TxBufferM.ReadIndex = 0;
	Can1TxBufferM.WriteIndex = 0;

	Can1RxBuffer0;Can1BufferM.ReadIndex
	= 0

//禁用保护
HWREG (sysctl_MWRALLOW)= 0xA5A5A5A5;

// CAN总线的外围设备1
SysCtlPeripheralEnable(sysctl_Periph_GPIOF);

//配置GPIO引脚多工以选择这些引脚的CAN0功能。
//此步骤选择可用于这些引脚的替代功能。
//如果您的部件支持GPIO引脚功能多路复用,则必须执行此操作。
//请参阅数据表以查看每个引脚分配了哪些功能。

GPIOPinConfigure(GPIO_PF0_CAN1RX);
GPIOPinConfigure(GPIO_PF7_CAN1TX);

//在GPIO引脚上启用备用功能。 以上步骤选择
//可用的替代功能。 此步骤实际上启用
//这些引脚的替代功能,而不是GPIO。
GPIOPinTypeCAN (GPIO_PORTF_BASE,GPIO PIN_0 | GPIO PIN_7);

//已为CAN设置GPIO端口和引脚。 CAN外围设备
//必须启用。
SysCtlPeripheralEnable(sysctl_Periph_CAN1);

//初始化CAN控制器
CANInit (CAN1_BASE);

//可以为设置计时,使M3/主子系统时钟不工作
CANClkSourceSelect(CAN1_BASE,CAN_CLK_M3);

//设置CAN总线的比特率。 此功能设置CAN
//额定配置的总线定时。 您可以实现更多的控制
//通过CAN总线定时,改为使用函数CANBitTimingSet()
//(如果需要)。
//此处,CAN总线设置为250 kHz。 在下面的函数中,
//调用SysCltlClockGatet()用于确定其时钟速率
//用于为CAN外围设备计时。 这可以替换为
//固定值(如果知道系统时钟的值),保存额外的值
//函数调用。

// CANBitRateSet (CAN1_BASE,SysClockGet (system_clock_speed),25万);

CanClkParams.uQuantumPrescaler = 50;//=> 250kBaud和8 quanta
CanClkParams.uSJW = 1;
CanClkParams.uSyncPropPhase1Seg = 6;// Phase1(+1)+ Phase2(+1)+1必须等于Quanta的数量
CanClkParams.uPhase2Seg = 1;//=> 87.5 % 采样

CANBitTimingSet(CAN1_base,和CanClkParams);

//在CAN外围设备上启用中断。 此示例使用静态
//中断处理程序的分配,表示处理程序的名称
//位于启动代码的矢量表中。 如果要使用动态
//矢量表的分配,则还必须调用CANIntRegister()
//此处。
// CANIntRegister (CAN0_BASE,CANIntHandler);//如果使用动态矢量
CANIntEnable (CAN1_BASE,CAN_INT_IE0);

//在RAM矢量表
// IntRegister中注册中断处理程序(INT_CAN0INT0,CAN0IntHandler);

//启用处理器上的CAN中断(NVIC)。
IntEnable (INT_CAN1INT0);

//重试时启用自动总线
HWREG (CAN1_BASE + CAN_O_CTL)|= CAN_CTL_ABO;
HWREG (CAN1_BASE + CAN_O_ABOTR)= 50;// 50 Vbus周期后

//启用CAN以进行操作。
CANEnable (CAN1_BASE);

Can1TxBufferM.BufferSize = CAN1BUFFERSIZE;
Can1RxBufferM.BufferSize = CAN1BUFFERSIZE;

//设置接收邮箱,忽略扩展的联合!!
sMsgObject.ulMsgID = 0x0;//0xFFFF000;	//最大ID为1270;
sMsgObject.ulMsgIDMask = 0x1FFFFFF800;	//最大ID为127
// sMsgObject.ulFlags = MSG_OBJ_FIFO | MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_EXT_FILTER;
sMsgObject.ulFlags = MSG_OBJ_FIFO | MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_EXT_FILTER;

CANMessageSet (CAN1_BASE,1,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN1_BASE,2,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN1_BASE,3,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN1_BASE,4,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN1_BASE,5,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN1_BASE,6,&sMsgObject,MSG_OBJ_TYPE_RX);
CANMessageSet (CAN1_BASE,7,&sMsgObject,MSG_OBJ_TYPE_RX);
sMsgObject.ulFlags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_EXT_FILTER;	//忽略扩展帧!!!
CANMessageSet (CAN1_BASE,8,&sMsgObject,MSG_OBJ_TYPE_RX);

}//*************************************************************************************************



//任务(在TI-RTOS GUI中定义)
//检查是否需要传输任何内容以及传输邮箱是否为空
//*****************************************************************************************
void
CheckCan0Transmission (void){

	while (1){
	
		semaphore_pend(StartCan0Transmit,BIOS_wait_forever;//等待其他线程检查传输
		//检查传输//如果
		(Can0TxBufferM.ReadIndex != Can0TxBufferM.WriteIndex)&&CAN0_NothingToTransmit)
		,检查传输是否需要启动
		tCANMsgObject sCANMessage;

		//设置发送邮箱
			// ReadIndex指针上的消息被传输,
			//但指针在传输后更新(中断后)
			//这是为了保护数据,因为它是用指针而不是副本发送的。
			sCANMessage.ulMsgID = Can0TxBufferM.Message[Can0TxBufferM.ReadobjIndex].cob_id;sCANMSG_MsulMESSAGE_Msm_Msmage.0_MsulMESSAG_MSG_MSG_MSG_USG=
			
			
			sCANMessage.pucMsgData = Can0TxBufferM.Message[Can0TxBufferM.ReadIndex].data;
			sCANMessage.ulMsgLen = Can0TxBufferM.Message[Can0TxBufferM.ReadIndex].len;
			CAN0_NothingToTransmit =0;
			IF (Can0TxBufferM.Message[Can0TxBufferM.ReadIndex].RTR)
				CANMessageSet (CAN0_BASE,32,&sCANMessage, MSG_OBJ_TYPE_TX_REMOTE );
		Else CANMessageSet (CAN0_BASE,32,&sCANMessage,MSG_OBJ_TYPE_TX);
		}}}}//*********************************************************************************************************
	




//任务(在TI-RTOS GUI中定义)
//检查是否需要传输任何内容以及传输邮箱是否为空
//*****************************************************************************************
void
CheckCan1Transmission (void){

	while (1){
	
		semaphore_pend(StartCan1Transmit,BIOS_wait_forever);//等待其他线程检查传输
		//检查
		传输//如果(Can1TxBufferM.ReadIndex != Can1TxBufferM.WriteIndex)&&CAN1_NothingToTransmit)
		,则检查传输是否需要停止
		tCANMsgObject sCANMessage;

		//设置发送邮箱
			// ReadIndex指针上的消息被传输,
			//但指针在传输后更新(中断后)
			//这是为了保护数据,因为它是用指针而不是副本发送的。
			sCANMessage.ulMsgID = Can1TxBufferM.Message[Can1TxBufferM.ReadobjIndex].cob_id;sCANMSG_MsulMESSAGE_Msmage.0;
			
			
			sCANMessage.pucMsgData = Can1TxBufferM.Message[Can1TxBufferM.ReadIndex].data;
			sCANMessage.ulMsgLen = Can1TxBufferM.Message[Can1TxBufferM.ReadIndex].len;
			CAN1_NothingToTransmit = 0;
			IF (Can1TxBufferM.Message[Can1TxBufferM.ReadIndex].RTr)
				CANMessageSet (CAN1_BASE,32,&sCANMessage,MSG_OBJ_TYPE_TX_REMOTE);
		Else CANMessageSet (CAN1_BASE,32,&sCANMessage,MSG_OBJ_TYPE_TX);
		}}}}//*********************************************************************************************************
	




//任务(在TI-RTOS GUI中定义)
//检查是否需要接收任何内容
//*****************************************************************************************
void
CheckCan0Reception(void){


	while (1)
	{//
		保持并等待接收数据
		semaphore_pend(StartCan0Receive,BIOS_wait_forever );//等待其他线程检查传输
		//检查
		是否接收到某些内容,while (Can0RxBufferM.ReadIndex != Can0RxBufferM.WriteIndex){
		
//代码...
		}
	}//*********************************************************************************************************




//任务(在TI-RTOS GUI中定义)
//检查是否需要接收任何内容
//*****************************************************************************************
void
CheckCan1Reception(void){


	while (1)
	{//
		保持并等待接收数据
		semaphore_pend(StartCan1Receive,BIOS_wait_forever );//等待其他线程检查传输
		//检查
		是否接收到某些内容while (Can1RxBufferM.ReadIndex != Can1RxBufferM.WriteIndex){
		
//代码...
		}
	}
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    • 能否在Contolsuite (C:\ti\controlSUITE\DEVICE_SUPPORT\f28m36x\v220\F28M36x_Examples_Masters\CAN_loop\m3)中尝试此示例? 它是为自检模式编写的,但可轻松修改以进行外部传输。

     

    • 您是否在多台设备(代码相同)上看到过此行为?

     

    • 对于您看到的超过8个字节的帧,帧的开头(SOF,MSGID,数据长度等)是否看起来像有效的CAN帧? 您是否拥有范围捕获?

     

    • 总线上是否有任何CAN-FD节点?

     

    • 重现此问题的难易程度如何? 您是否可以“随意”复制它?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我发现了问题。 由于candevice提供的数据不稳定,DLC有时超过8个(例如 14)。
    因为要设置数据的数据数组只有8个字节,并且在中断例程中声明:
    无符号char数据[8];
    本说明:
    CANMessageGet (CAN1_BASE,ulStatus,(tCANMsgObject *)&sCANMessage,1);
    堆栈混乱,覆盖返回地址等。

    将初始化更改为:
    无符号的char数据[16];

    解决了它:)