📄 can.cpp
字号:
{
ev_receive(EV_CAN_TIMER|EV_CAN_EOPD, EV_WAIT|EV_ANY, 0, &events_r);
//有接收中断发生
if(events_r & EV_CAN_EOPD)
{
CanDaemonReceiver();
}
//CAN定时
if(events_r & EV_CAN_TIMER )
{
CanTimer++;
//若有接收的信息没有被处理,则处理,监视,不希望调用太频繁。
if( ( CanTimer % (200/MIN_CAN_TIMER) ) == 0)
{
CanDaemonReceiver();
}
//发送操作,主要为发送链路结束请求,第一层控制发送频率
for(i=0; i<CanStationCount; i++)
{
for(j=0; j<2; j++)
{
if( CanCB[i].fStart[j] == TRUE )
{
//由(MAX_END_LINK_TIME-MIN_END_LINK_TIME)/MIN_CAN_TIMER决定重发的次数
if( CanCB[i].StopSendCount[j] != 0xffff )
{
if( CanCB[i].StopSendCount[j] > (MIN_END_LINK_TIME/MIN_CAN_TIMER) )
{
//开始发送链路结束请求
if( CanCB[i].StopSendCount[j] < (MAX_END_LINK_TIME/MIN_CAN_TIMER) )
{
MyAddr = CanCB[i].Addr + COMMAND_PRI;
CellBuf[0] = (MyAddr>>3)&0xff;
CellBuf[1] = (MyAddr<<5)&0xff;
CellBuf[2] = 3;
CellBuf[3] = REQUEST_LINK_END;
if( j==0 )
{
CellBuf[4] = NORMAL_CHANNEL;
}
else
{
CellBuf[4] = URGENCY_CHANNEL;
}
CellBuf[5] = CanCB[i].SendEnd[j];
PutToCommand(CellBuf, i);
CanCB[i].StopSendCount[j] ++;
//等待,防止重复进入
//?????????????????/多个模块问题
//tm_wkafter(TICK2MS(20));
}
//超过了最大重发次数,复位链路
else
{
RequstResetLink(j, i, 10);
}
}
else
{
CanCB[i].StopSendCount[j] ++;
}
}
}
}
}
//led判断
if( fSendLed == TRUE )
{
GlintCanLed(TRUE, FALSE );
fSendLed = FALSE;
}
if( fReceLed == TRUE )
{
GlintCanLed(FALSE, FALSE );
}
//状态寄存器,监视发送,防止发送停止而缓冲有数据
//for debug
//BeginSendCell();
#if( CAN_STATION ==TRUE )
for(i=0; i<CanStationCount; i++)
{
//单板程序启动时,每隔1秒发送一次请求复位链路的命令(单板)
if( (CanCB[i].fStart[0]==FALSE) || (CanCB[i].fStart[1]==FALSE) )
{
if( (CanTimer % (1200/MIN_CAN_TIMER)) == 0 )
{
if( CanCB[i].fStart[0] == FALSE )
{
RequstResetLink(0, i, 12);
}
if( CanCB[i].fStart[1] == FALSE )
{
RequstResetLink(1, i, 13);
}
}
}
}
#endif
//复位链路控制
//查询所有的链路标志,看是否有复位标志
if( CanTimer % (500/MIN_CAN_TIMER) == 0 )
{
for(i=0; i<CanStationCount; i++)
{
for(j=0; j<2; j++)
{
if( CanCB[i].fStart[j] == FALSE )
{
//在此链路发送,链路启动帧
if( j==0 )
{
MyAddr = CanCB[i].Addr + NORMAL_PRI;
CellBuf[0] = (MyAddr>>3)&0xff;
CellBuf[1] = (MyAddr<<5)&0xff;
CellBuf[2] = 1;
CellBuf[3] = 0xc0;
PutToNormal(CellBuf, i);
BeginSendCell();
}
else
{
MyAddr = CanCB[i].Addr + URGENCY_PRI;
CellBuf[0] = (MyAddr>>3)&0xff;
CellBuf[1] = (MyAddr<<5)&0xff;
CellBuf[2] = 1;
CellBuf[3] = 0xc0;
PutToUrgency(CellBuf, i);
BeginSendCell();
}
}
}
}
}
//监视从应用层下发的接收缓冲,若由数据则拆包
if( RUBufWPoint != RUBufRPoint )
{
MakeSendCell(ReceMode[RUBufRPoint]&0xffff, ReceUpBuffer[RUBufRPoint], ReceLength[RUBufRPoint], (ReceMode[RUBufRPoint]>>31) );
RUBufRPoint ++;
RUBufRPoint %= MAX_RUP_BUF;
DF_PostMessage(CanUpTaskId,SM_COMMIDLE);
}
if( fReceFrameOk == TRUE )
{
if( CanDelay > MAX_CAN_DELAY )
{
DF_PostMessage(CanUpTaskId,SM_COMMIDLE);
fReceFrameOk = FALSE;
CanDelay = 0;
}
else
{
CanDelay ++;
}
}
}
}
}
void CanInitStatic(void)
{
DWORD i;
for(i=0; i<CanStationCount; i++)
{
//此块对应的分板的站址,0为无效
CanCB[i].Addr = 0;
//单元接收序号
CanCB[i].ROrder[0] = 0;
CanCB[i].ROrder[1] = 0;
//单元发送序号
CanCB[i].SOrder[0] = 1;
CanCB[i].SOrder[1] = 1;
//#if( CAN_STATION == TRUE )
//链路启动状态
CanCB[i].fStart[0] = FALSE;
CanCB[i].fStart[1] = FALSE;
//#else
//链路启动状态
//CanCB[i].fStart[0] = TRUE;
//CanCB[i].fStart[1] = TRUE;
//#endif
//当前桢起始单元序号
CanCB[i].StartCellOrder[0] = 0;
CanCB[i].StartCellOrder[1] = 0;
//当前桢中的总共的单元数据,不包括控制单元
CanCB[i].FrameLength[0] = 0;
CanCB[i].FrameLength[1] = 0;
//当前处理到的单元序号,在一桢中
CanCB[i].FrameOrder[0] = 0;
CanCB[i].FrameOrder[1] = 0;
//发送链路结束请求时,最后一个单元的序号
CanCB[i].SendEnd[0] = 0;
CanCB[i].SendEnd[1] = 0;
//当前丢失的单元(正在复要的)
CanCB[i].RequestCell[0] = 0;
CanCB[i].RequestCell[1] = 0;
CanCB[i].RequestCount[0] = 0;
CanCB[i].RequestCount[1] = 0;
//
CanCB[i].StopSendCount[0] = 0xffff;
CanCB[i].StopSendCount[1] = 0xffff;
//普通发送缓冲
CanCB[i].NSBufRPoint = 0;
CanCB[i].NSBufWPoint = 0;
//紧急上传发送缓冲
CanCB[i].USBufRPoint = 0;
CanCB[i].USBufWPoint = 0;
//命令发送缓冲
CanCB[i].CSBufRPoint = 0;
CanCB[i].CSBufWPoint = 0;
//接收缓冲
//一般接收缓冲
CanCB[i].NRBufRPoint = 0;
CanCB[i].NRBufWPoint = 0;
//紧急接收缓冲
CanCB[i].URBufRPoint = 0;
CanCB[i].URBufWPoint = 0;
//命令接收缓冲
CanCB[i].CRBufRPoint = 0;
CanCB[i].CRBufWPoint = 0;
//for debug
CanCB[i].NormalSendAll = 0;
CanCB[i].NormalReceAll = 0;
CanCB[i].CommandSendAll = 0;
CanCB[i].CommandReceAll = 0;
CanCB[i].UrgencySendAll = 0;
CanCB[i].UrgencyReceAll = 0;
}
NSUBufRPoint = 0;
NSUBufWPoint = 0;
USUBufRPoint = 0;
USUBufWPoint = 0;
RUBufRPoint = 0;
RUBufWPoint = 0;
//保证第一次能够发送COMMIDLE消息
fReceFrameOk = TRUE;
IsrErrorCount = 0;
CanDelay = 0;
}
//for debug
DWORD HouTaiTaskID;
void HouTaiTask(DWORD);
#if(TEST_SHARD==TRUE)
BYTE TestBuf[16];
DWORD CanCount;
#endif
DWORD CanInitial(DWORD PortSort)
{
DWORD i;
DWORD PDevId[MAX_STATION];
//根据系统得到CAN网的信息,如配置了多少分板
CanStationCount = GetDeviceNum( (PORT_CANBUS + PortSort) );
//CanStationCount = MAX_STATION;
//大于系统最大允许数量
if( CanStationCount > MAX_STATION )
{
return FALSE;
}
//动态申请内存
CanCB = new TCanCBlock[CanStationCount];
if( CanCB == NULL )
{
return FALSE;
}
//初始化静态变量
CanInitStatic();
//根据系统得到CAN网的信息,每个分板的地址为什么
GetDeviceIDSet(PDevId, PORT_CANBUS + PortSort );
for(i=0; i<CanStationCount; i++)
{
CanCB[i].Addr = GetDeviceAddress(PDevId[i]);
}
CanUpTaskId = GetAppID();
//for(i=0; i<CanStationCount; i++)
//{
// CanCB[i].Addr = i+1;
//}
//CanCB[0].Addr = 4;
//***********************************************
#if ( TEST_SHARD == TRUE )
//for debug
//初始化硬件
InitCanHard();
DWORD MyCount = 0;
BYTE Status;
//站号,优先级最低。
WORD Temp = 99;
TestBuf[0] = (Temp>>3)&0xff;
TestBuf[1] = (Temp<<5)&0xff;
TestBuf[2] = 0;
TestBuf[3] = 0;
TestBuf[4] = 8;
TestBuf[5] = 0;
TestBuf[6] = 0;
TestBuf[7] = 0;
TestBuf[8] = 0;
TestBuf[9] = 5;
TestBuf[10] = 6;
TestBuf[11] = 7;
TestBuf[12] = 8;
//设置CAN网中断
DF_SetIntVector(SV_CANBUS, CanIsr,PortSort);
CanCount = 0;
//为发送准备
Write2510Bytes(Txb0Sidh, TestBuf, MAX_CELL_SIZE);
//开始发送
MCP2510BitFunc(Txb0Ctrl, 0x08, 0x08);
CanCount ++;
TestBuf[5] = CanCount>>24;
TestBuf[6] = CanCount>>16;
TestBuf[7] = CanCount>>8;
TestBuf[8] = CanCount;
DWORD Temp1;
for(;;)
{
if( CanCount != Temp1 )
{
SetTpuIoStatus(7, IS_HIGH);
}
else
{
SetTpuIoStatus(7, IS_LOW);
}
Temp1 = CanCount;
tm_wkafter(10);
}
#endif
#if( TEST_RHARD == TRUE )
InitCanHard();
//设置CAN网中断
DF_SetIntVector(SV_CANBUS, CanIsr,PortSort);
for(;;);
#endif
//***********************************************
//初始化硬件
InitCanHard();
//生成CAN管理任务
if( t_create("CAND", 0xb1, 4096, 512, 0, &CanDaemonTaskId) != SUCCEED )
{
return FAIL;
}
if( t_start(CanDaemonTaskId, T_SUPV|T_PREEMPT|T_NOTSLICE, (TTASK_ENTRY)CanDaemon,0) != SUCCEED )
{
return FAIL;
}
//*******************************************for debug
//创建后台任务
//if( t_create("HOUT", 10, 4096, 512, 0, &HouTaiTaskID) != SUCCEED )
//{
// return FAIL;
//}
//if( t_start(HouTaiTaskID, T_SUPV|T_PREEMPT|T_NOTSLICE, (TTASK_ENTRY)HouTaiTask,0) != SUCCEED )
//{
// return FAIL;
//}
//CanUpTaskId = DF_CreateTask("HOUT",(TTASK_ENTRY)HouTaiTask,0xf0,3096,0,0,0);
//*******************************************
//熄灭收发灯
GlintCanLed(TRUE, FALSE);
GlintCanLed(FALSE, FALSE);
//设置CAN网中断
DF_SetIntVector(CANBUS1_INT_VECTOR, CanIsr,PortSort);
//允许CAN网中断,要求后台任务优先级要比CAN网任务高
DF_EnableInt(CANBUS1_INT_VECTOR);
return SUCCEED;
}
//*********************************************************for debug
DWORD FrameCount;
BYTE SendCount;
DWORD SendError;
void HouTaiTask(DWORD appid)
{
WORD i;
BYTE UpBuf[256];
BYTE MyBuf[256];
WORD SendCount2 = 0;
WORD SendCount1 = 0;
WORD CheckSum;
for(i=0; i<256; i++)
{
MyBuf[i] = i+1;
}
MyBuf[0] = 240;
CheckSum = 0;
for(i=1; i<240; i++)
{
CheckSum += MyBuf[i];
}
tm_wkafter(MS2TICK(4000));
WORD WaitSendTime;
TMessage msg;
//启动遥控等待时间定时器
DF_SetTimer(0, 0, 500);
DWORD Status = ERR_MESSAGE_OK;
while(Status != ERR_MESSAGE_QUIT)
{
//调用取消息函数,从任务消息队列头,取需要处理的消息
Status = DF_GetMessage(appid,&msg);
//判断接收的消息是否为有效消息
if(Status == ERR_MESSAGE_OK)
{
//根据消息执行功能
switch( LOWORD(msg.lParam) )
{
//系统定时
case SM_TIMEOUT:
if( CanCB[0].fStart[1] == TRUE )
{
MyBuf[1] = SendCount2;
CheckSum = 0;
for(i=1; i<240; i++)
{
CheckSum += MyBuf[i];
}
MyBuf[240] = (CheckSum>>8)&0xff;
MyBuf[241] = CheckSum&0xff;
if( CanWrite(0, MyBuf, 242, ((WCF_URGENT<<31)|4) ) != 0 )
{
SendCount2 ++;
}
}
break;
case SM_READCOMM:
CanRead(0, UpBuf);
//for debug
CheckSum = 0;
for(i=1; i<UpBuf[0]; i++)
{
CheckSum += UpBuf[i];
}
if( ((CheckSum>>8)&0xff) == UpBuf[ UpBuf[0] ] )
{
if( (CheckSum&0xff) == UpBuf[ UpBuf[0]+1 ] )
{
FrameCount ++;
//返回
//CanWrite(0, UpBuf, 26, ((WCF_NORMAL<<31)|CanCB[0].Addr) );
if( SendCount != UpBuf[1] )
{
SendError ++;
}
SendCount = UpBuf[1];
SendCount ++;
}
}
break;
case SM_COMMIDLE:
SendCount1 ++;
break;
default:
break;
}
}
}
}
//*********************************************************for debug
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -