846 lines
21 KiB
C
846 lines
21 KiB
C
/***********************************************************************
|
||
* @file name: candrvctrl.c
|
||
* @create date: 2022-11-19
|
||
* @author
|
||
* @version: V 1.0.0
|
||
* @remark:
|
||
这个模块对can外设进行统一管理,忽略MCU接口的不同,对外一个统一的接口
|
||
MCU的更换不涉及到这里
|
||
************************************************************************/
|
||
|
||
/*********************************************************************************************************************
|
||
//CANDRVCTRL 作为传输协议与can驱动之间的中间层,作为一个纽带来将两者进行连接
|
||
//
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// CAN驱动<------> 驱动管理层
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//can通道id和can消息帧id两者之间的同事用canid来表示容易出现混淆,
|
||
// 故用chan表示can通道
|
||
// 用frmid表示can消息帧id
|
||
//
|
||
//
|
||
//can驱动层将需要给传输层控制的接口通过st_cancb * RegisterCanIF(st_canif *if) 接口传给此模块
|
||
//st_cancb * RegisterCanIF(st_canif *if) 驱动层将某接口的控制权交给CanDrvCtrl模块
|
||
//参数st_canif 是驱动统一交给CanDrvCtrl 的接口列表,其中ConfigCan ,canSend和canid必须提供
|
||
//返回回调函数,驱动必须在适当的时候对其进行调用
|
||
*********************************************************************************************************************/
|
||
|
||
#include "porting.h"
|
||
#include "candrvctrl.h"
|
||
|
||
#if 0
|
||
#define M_DEBUGF printf
|
||
#else
|
||
#define M_DEBUGF(...) ;
|
||
#endif
|
||
|
||
#define MAX_CAN_IF_NUM 2
|
||
#define PROTOCOL_VALID(PL) (PL.prompt[0] !=0) //判断是否有协议安装在某个接口,通过协议名字来进行
|
||
#define SET_PROTOCOL_INVALID(PL) (PL.prompt[0] =0)
|
||
|
||
typedef enum
|
||
{
|
||
e_step_send_idle=0, //空闲等待发送条件到达,进入e_step_send,通过定时器操作
|
||
e_step_send, //进行发送然后进入e_step_waitack等待, //通过消息触发
|
||
e_step_waitack, //通过定时器
|
||
e_step_resend, //进行重发,当超时或等应答过程出现异常的时候
|
||
e_step_fail, //已经发送失败
|
||
e_step_suc, //发送成功
|
||
}st_sendstep;
|
||
|
||
|
||
typedef struct
|
||
{
|
||
unsigned int frmid; //can信息id
|
||
unsigned char sendindex;
|
||
unsigned char datalen;
|
||
unsigned char data[8];
|
||
unsigned int msgident;
|
||
void(*cb)(unsigned int msgident,unsigned int result);
|
||
}st_senditem;
|
||
typedef struct
|
||
{
|
||
unsigned int frmid; //can信息id
|
||
unsigned char datalen;
|
||
unsigned char data[8];
|
||
}st_recitem;
|
||
|
||
|
||
typedef struct
|
||
{
|
||
unsigned char stimes;
|
||
st_sendstep step;
|
||
st_senditem sending; //当前正在发送的数据
|
||
unsigned char waittime; //等待的时间
|
||
unsigned char retrytimes;
|
||
}st_sendmsg;
|
||
|
||
|
||
typedef struct
|
||
{
|
||
st_canif canif;
|
||
st_pl pl;
|
||
unsigned char linkSts;
|
||
st_fifo_t rec;
|
||
st_fifo_t send;
|
||
unsigned char *prec;
|
||
unsigned char *psend;
|
||
st_sendmsg smsg; //当前发送消息
|
||
}st_if;
|
||
|
||
static void hdlIfSendSuccessCb(unsigned char chan,unsigned int index);
|
||
static void hdlIfBusErrorCb(unsigned char chan,bool sending);
|
||
static void hdlIfBusErrorStsCb(unsigned char chan,bool sending);
|
||
static bool hdlIfFrmReceve(unsigned char chan,unsigned int canid,const unsigned char *data,unsigned char len);
|
||
static void HdlSendMsgSuccess(st_if* pif,unsigned char index);
|
||
static void hdlIfBusOffCb(unsigned char chan);
|
||
|
||
static st_if CanIF[MAX_CAN_IF_NUM];
|
||
static st_cancb canifcb ={
|
||
hdlIfSendSuccessCb,
|
||
hdlIfBusErrorCb,
|
||
hdlIfBusErrorStsCb,
|
||
hdlIfBusOffCb,
|
||
hdlIfFrmReceve};
|
||
|
||
|
||
static st_if* GetIfFromChanel(unsigned char chan)
|
||
{
|
||
unsigned char i;
|
||
|
||
for(i=0;(i<NELEMENTS(CanIF))&&(CanIF[i].canif.chan != 0xFF);i++)
|
||
{
|
||
|
||
if(CanIF[i].canif.chan == chan)
|
||
{
|
||
return &CanIF[i];
|
||
}
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
static void hdlIfSendSuccessCb(unsigned char chan,unsigned int index)
|
||
{
|
||
st_if* pif=GetIfFromChanel(chan);
|
||
|
||
if(pif != NULL)
|
||
{
|
||
HdlSendMsgSuccess(pif,index);
|
||
}
|
||
}
|
||
static void hdlIfBusErrorCb(unsigned char chan,bool sending)
|
||
{
|
||
st_if* pif;
|
||
|
||
pif=GetIfFromChanel(chan);
|
||
if(pif != NULL)
|
||
{
|
||
if(pif->linkSts <= e_sts_closed)
|
||
{
|
||
if(pif->canif.canClose != NULL) pif->canif.canClose(chan);
|
||
}
|
||
else if(pif->linkSts == e_err_sending && sending)
|
||
{
|
||
M_DEBUGF("[CDCtrl]hdlIfBusErrorStsCb: 检测到总线发送异常!\n");
|
||
pif->linkSts = e_err_sending;
|
||
can_kill( E_CAN_MSG_SIG,e_err_sending,chan);
|
||
}
|
||
else if(pif->linkSts != e_err_sending && sending == false)
|
||
{
|
||
M_DEBUGF("[CDCtrl]hdlIfBusErrorStsCb: 检测到总线接收异常!\n");
|
||
pif->linkSts = e_err_receive;
|
||
can_kill( E_CAN_MSG_SIG,e_err_receive,chan);
|
||
}
|
||
else
|
||
{
|
||
/* 其他情况忽略 */
|
||
}
|
||
}
|
||
}
|
||
static void hdlIfBusErrorStsCb(unsigned char chan,bool sending)
|
||
{
|
||
hdlIfBusErrorCb(chan,sending);
|
||
}
|
||
|
||
|
||
|
||
static void hdlIfBusOffCb(unsigned char chan)
|
||
{
|
||
st_if* pif;
|
||
|
||
pif=GetIfFromChanel(chan);
|
||
if(pif != NULL)
|
||
{
|
||
if(pif->linkSts <= e_sts_closed)
|
||
{
|
||
if(pif->canif.canClose != NULL) pif->canif.canClose(chan);
|
||
}
|
||
else
|
||
{
|
||
M_DEBUGF("[CDCtrl]hdlIfBusOffCb: 检测到总线BUSOFF!\n");
|
||
pif->linkSts = e_err_bussoff;
|
||
can_kill( E_CAN_MSG_SIG,e_err_bussoff,chan);
|
||
}
|
||
}
|
||
}
|
||
static st_recitem tmpRItem;
|
||
static bool hdlIfFrmReceve(unsigned char chan,unsigned int canid,const unsigned char *data,unsigned char len)
|
||
{
|
||
st_if* pif;
|
||
|
||
pif = GetIfFromChanel(chan);
|
||
|
||
if(pif != NULL && pif->linkSts >= e_sts_working)
|
||
{
|
||
if(e_err_receive == pif->linkSts)
|
||
{
|
||
pif->linkSts=e_sts_working;
|
||
}
|
||
|
||
if(pif->pl.flg&CAN_FLG_SYNCRECEIVE)
|
||
{
|
||
if(pif->pl.hdlRecCanMsg!=NULL) pif->pl.hdlRecCanMsg(canid,data,len);
|
||
}
|
||
else
|
||
{
|
||
tmpRItem.frmid = canid;
|
||
tmpRItem.datalen = len;
|
||
if(tmpRItem.datalen > 0 && tmpRItem.datalen<=8) CAN_COPY(tmpRItem.data,data,tmpRItem.datalen);
|
||
|
||
sfifo_write(&pif->rec,&tmpRItem);
|
||
if(sfifo_full(&pif->rec))
|
||
{
|
||
M_DEBUGF("[CDCtrl]hdlIfFrmReceve: 接收缓冲已满\n");
|
||
pif->linkSts=e_err_overfllow;
|
||
can_kill( E_CAN_MSG_SIG,e_err_overfllow,chan);
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
//注册通信接口和初始化
|
||
st_cancb * RegisterCanIF(const st_canif *IF)
|
||
{
|
||
unsigned char i;
|
||
|
||
if(IF == NULL || IF->ConfigCan == NULL || IF->canSend==NULL ) return NULL;
|
||
|
||
for(i=0;i<NELEMENTS(CanIF);i++)
|
||
{
|
||
if(CanIF[i].canif.chan == IF->chan) return NULL;
|
||
}
|
||
|
||
for(i=0;i<NELEMENTS(CanIF);i++)
|
||
{
|
||
if(CanIF[i].canif.chan == 0xFF)
|
||
{
|
||
CAN_COPY((void*)&(CanIF[i].canif),(void*)IF,sizeof(st_canif));
|
||
CanIF[i].linkSts = e_sts_unused;
|
||
return &canifcb;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//处理发送工作
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
|
||
//重发
|
||
static TIMER waitSendAck=0;
|
||
#define WAIT_ACK_TIME 2
|
||
#define WAIT_ACK_INTERVAL 10
|
||
static void waitSendMsgAck(TIMER tmr_id)
|
||
{
|
||
unsigned char i;
|
||
|
||
for(i=0;i<MAX_CAN_IF_NUM;i++)
|
||
{
|
||
if(CanIF[i].linkSts < e_sts_working)
|
||
{
|
||
continue;
|
||
}
|
||
//发送失败后大约10ms重新发送
|
||
if(CanIF[i].smsg.step == e_step_send) can_kill( E_CAN_MSG_SIG,e_sts_needsend,CanIF[i].canif.chan);
|
||
|
||
if(CanIF[i].smsg.step == e_step_waitack)
|
||
{
|
||
CanIF[i].smsg.waittime++;
|
||
if(CanIF[i].smsg.waittime>= WAIT_ACK_TIME)
|
||
{
|
||
CanIF[i].smsg.step = e_step_resend;
|
||
can_kill( E_CAN_MSG_SIG,e_sts_needsend,CanIF[i].canif.chan);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
static void StartResendMsgTmr(void)
|
||
{
|
||
if(waitSendAck == 0) waitSendAck = can_timer_create(waitSendMsgAck);
|
||
if(can_timer_switch(waitSendAck) == false) can_timer_start(waitSendAck, WAIT_ACK_INTERVAL);
|
||
}
|
||
|
||
|
||
static void HdlAllSengMsgSts(st_if* pif)
|
||
{
|
||
bool flg = false;
|
||
|
||
#if CAN_SEND_FASET_MODE > 0
|
||
do {
|
||
flg = false;
|
||
#endif
|
||
switch(pif->smsg.step)
|
||
{
|
||
case e_step_send_idle: //空闲等待发送条件到达,进入e_step_send,通过定时器操作
|
||
if(pif->linkSts >= e_sts_working)
|
||
{
|
||
if(sfifo_empty(&(pif->send))==false)
|
||
{
|
||
if(sfifo_read(&(pif->send),&(pif->smsg.sending)))
|
||
{
|
||
pif->smsg.step=e_step_send;
|
||
pif->smsg.stimes = 0;
|
||
pif->smsg.waittime = 0;
|
||
}
|
||
flg = true;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case e_step_send: //进行发送然后进入e_step_waitack等待, //通过消息触发
|
||
pif->smsg.sending.sendindex = pif->canif.canSend(pif->canif.chan,pif->smsg.sending.frmid,pif->smsg.sending.data,pif->smsg.sending.datalen);
|
||
|
||
pif->smsg.stimes++;
|
||
if(pif->smsg.sending.sendindex != 0xFF)
|
||
{
|
||
pif->smsg.step=e_step_waitack;
|
||
pif->smsg.waittime = 0;
|
||
flg = true;
|
||
if(pif->linkSts == e_err_sending) pif->linkSts = e_sts_working;
|
||
}
|
||
else
|
||
{
|
||
if(pif->smsg.stimes >= pif->pl.resendTimes)
|
||
{
|
||
pif->smsg.step=e_step_fail;
|
||
flg = true;
|
||
}
|
||
}
|
||
break;
|
||
#if 1
|
||
case e_step_waitack: //通过定时器
|
||
break;
|
||
case e_step_resend: //进行重发,当超时或等应答过程出现异常的时候
|
||
if(pif->smsg.stimes >= pif->pl.resendTimes)
|
||
{
|
||
pif->smsg.step=e_step_fail;
|
||
}
|
||
else
|
||
{
|
||
pif->smsg.step=e_step_send;
|
||
}
|
||
flg = true;
|
||
break;
|
||
case e_step_fail: //已经发送失败
|
||
pif->smsg.step=e_step_send_idle;
|
||
if(pif->smsg.sending.cb != NULL) {pif->smsg.sending.cb(pif->smsg.sending.msgident,_FAILURE);}
|
||
else if (pif->pl.hdlCommSent != NULL) {pif->pl.hdlCommSent(pif->smsg.sending.msgident,_FAILURE);}
|
||
flg = true;
|
||
break;
|
||
case e_step_suc: //发送成功
|
||
pif->smsg.step=e_step_send_idle;
|
||
#if CAN_SEND_FASET_MODE > 0
|
||
if(pif->smsg.sending.cb != NULL) {can_kill(E_CAN_MSG_CB_SIG, (unsigned int)(pif->smsg.sending.cb),pif->smsg.sending.msgident);}
|
||
else if (pif->pl.hdlCommSent != NULL) {can_kill(E_CAN_MSG_CB_SIG, (unsigned int)(pif->pl.hdlCommSent),pif->smsg.sending.msgident);}
|
||
#else
|
||
if(pif->smsg.sending.cb != NULL) {pif->smsg.sending.cb(pif->smsg.sending.msgident,_SUCCESS);}
|
||
else if (pif->pl.hdlCommSent != NULL) {pif->pl.hdlCommSent(pif->smsg.sending.msgident,_SUCCESS);}
|
||
#endif
|
||
flg = true;
|
||
break;
|
||
#endif
|
||
}
|
||
#if CAN_SEND_FASET_MODE > 0
|
||
}while(flg == true && (pif->smsg.step != e_step_fail));
|
||
#endif
|
||
if(flg) can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
|
||
|
||
}
|
||
|
||
|
||
static void HdlSendMsgError(st_if* pif)
|
||
{
|
||
if(pif->smsg.step == e_step_waitack)
|
||
{
|
||
M_DEBUGF("[CDCtrl]chan%d第%d(%d)次发送失败\n",pif->canif.chan,pif->smsg.stimes,pif->pl.resendTimes);
|
||
if(pif->smsg.stimes >= pif->pl.resendTimes)
|
||
{
|
||
pif->smsg.step = e_step_fail;
|
||
}
|
||
else
|
||
{
|
||
pif->smsg.step = e_step_resend;
|
||
}
|
||
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
|
||
}
|
||
else
|
||
{
|
||
M_DEBUGF("[CDCtrl]HdlSendError,当前发送步骤%d!=%d\n",pif->smsg.step,e_step_waitack);
|
||
}
|
||
}
|
||
|
||
static void HdlSendMsgSuccess(st_if* pif,unsigned char index)
|
||
{
|
||
//M_DEBUGF("[CDCtrl]chan=%d,%o sendOK(%d)\n",pif->canif.chan,index,pif->smsg.step);
|
||
|
||
if(pif->smsg.step == e_step_waitack||pif->smsg.step ==e_step_resend)
|
||
{
|
||
if(pif->smsg.sending.sendindex == index)
|
||
{
|
||
pif->smsg.step = e_step_suc;
|
||
|
||
#if CAN_SEND_FASET_MODE > 0
|
||
if(pif->linkSts >= e_sts_working) HdlAllSengMsgSts(pif);
|
||
#else
|
||
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
M_DEBUGF("[CDCtrl]chan %d,index :%o#%o\n",pif->canif.chan,index,pif->smsg.sending.sendindex);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*********************************************************************************************************************
|
||
//CANDRVCTRL 作为传输协议与can驱动之间的中间层,作为一个纽带来将两者进行连接
|
||
//
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// 驱动管理层<------> 传输协议 **************************
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
//bool InstallProtocalToIF(unsigned char canid, st_pl* pif, st_cl * pcanif); 将某个接口与协议之间进行连接
|
||
// 同一时间,一个接口仅仅可以与一个协议进行连接
|
||
//参数st_pl, 是协议层需要提供的接口,这些信息在需要的时候被CANDRVCTRL调用
|
||
//参数st_cl, 是CANDRVCTRL 提供的接口, 协议层可以通过这些接口进行数据发送等
|
||
*********************************************************************************************************************/
|
||
|
||
static bool plSend(unsigned char chan,unsigned int frmid,unsigned char *data,unsigned char len,unsigned int msgident,void(*cb)(unsigned int msgident,unsigned int result))//若长度为0则表示是远程帧。
|
||
{
|
||
st_senditem send;
|
||
st_if* pif=NULL;
|
||
|
||
pif=GetIfFromChanel(chan);
|
||
|
||
if(pif ==NULL ||pif->linkSts<=e_sts_closed|| len>8 || sfifo_full(&pif->send)) return false;
|
||
|
||
SYS_ENTER_CRITICAL();
|
||
if (pif->linkSts == e_err_bussoff || pif->linkSts < e_sts_working)
|
||
{
|
||
SYS_EXIT_CRITICAL();
|
||
return false;
|
||
}
|
||
|
||
send.cb = cb;
|
||
send.frmid = frmid;
|
||
send.datalen = len;
|
||
send.msgident = msgident;
|
||
if(data == NULL) send.datalen = 0;
|
||
if(send.datalen>0 && send.datalen<=8) CAN_COPY(send.data,data,send.datalen);
|
||
send.sendindex = 0xFF;
|
||
|
||
sfifo_write(&pif->send,&send);
|
||
|
||
if(pif->smsg.step == e_step_send_idle)
|
||
{
|
||
#if CAN_SEND_FASET_MODE > 0
|
||
HdlAllSengMsgSts(pif);
|
||
#else
|
||
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
|
||
#endif
|
||
}
|
||
SYS_EXIT_CRITICAL();
|
||
return true;
|
||
}
|
||
|
||
static bool plReceive(unsigned char chan,unsigned int* frmid,unsigned char *data,unsigned char* len)//若长度为0则表示是远程帧。
|
||
{
|
||
st_recitem rec;
|
||
st_if* pif=GetIfFromChanel(chan);
|
||
|
||
if(pif ==NULL ||pif->linkSts<=e_sts_closed || data==NULL || (pif->pl.flg&CAN_FLG_SYNCRECEIVE)) return false;
|
||
|
||
if(sfifo_empty(&pif->rec)) return false;
|
||
|
||
if(sfifo_read(&pif->rec,&rec)==0) return false;
|
||
*frmid = rec.frmid;
|
||
*len = rec.datalen;
|
||
if(rec.datalen > 0 && rec.datalen<=8) CAN_COPY(data,rec.data,rec.datalen);
|
||
|
||
if (pif->linkSts == e_err_overfllow)
|
||
{
|
||
pif->linkSts = e_sts_working;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
static unsigned int plGetCurrentLinkSts(unsigned char chan) //获取当前链状态
|
||
{
|
||
st_if* pif=NULL;
|
||
|
||
|
||
pif=GetIfFromChanel(chan);
|
||
|
||
if(pif !=NULL) return pif->linkSts;
|
||
|
||
return 0;
|
||
}
|
||
|
||
static bool plConfigBus(unsigned char chan,unsigned short krate, bool highdomain,bool listen)
|
||
{
|
||
st_if* pif=GetIfFromChanel(chan);
|
||
|
||
if(pif ==NULL ||pif->linkSts<=e_sts_unused) return false;
|
||
|
||
if(pif->canif.ConfigCan != NULL)
|
||
{
|
||
if(pif->canif.ConfigCan(chan,krate,highdomain,listen))
|
||
{
|
||
if(pif->psend != NULL)
|
||
{
|
||
sfifo_init(&pif->send,pif->psend,sizeof(st_senditem),pif->pl.msgNumber);
|
||
}
|
||
if((pif->pl.flg&CAN_FLG_SYNCRECEIVE)==0 && (pif->prec != NULL))
|
||
{
|
||
sfifo_init(&pif->rec,pif->prec,sizeof(st_recitem),pif->pl.msgNumber);
|
||
}
|
||
pif->linkSts = e_sts_working;
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
static bool plcanBusFilterInit(unsigned char chan,unsigned int *filterID_array, unsigned short filterID_total)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
static bool plCloseLink(unsigned char chan)
|
||
{
|
||
st_if* pif=GetIfFromChanel(chan);
|
||
|
||
if(pif ==NULL ||pif->linkSts<=e_sts_closed) return false;
|
||
pif->linkSts = e_sts_closed;
|
||
|
||
if(pif->canif.canClose != NULL) pif->canif.canClose(chan);
|
||
|
||
if(pif->smsg.step != e_step_send_idle)
|
||
{
|
||
if(pif->smsg.sending.cb != NULL)
|
||
{
|
||
if(pif->smsg.step == e_step_suc)
|
||
{
|
||
pif->smsg.sending.cb(pif->smsg.sending.msgident,_SUCCESS);
|
||
}
|
||
else if(pif->smsg.step == e_step_fail)
|
||
{
|
||
pif->smsg.sending.cb(pif->smsg.sending.msgident,_FAILURE);
|
||
}
|
||
else
|
||
{
|
||
pif->smsg.sending.cb(pif->smsg.sending.msgident,_ABANDON);
|
||
}
|
||
}
|
||
else if (pif->pl.hdlCommSent != NULL)
|
||
{
|
||
if(pif->smsg.step == e_step_suc)
|
||
{
|
||
pif->pl.hdlCommSent(pif->smsg.sending.msgident,_SUCCESS);
|
||
}
|
||
else if(pif->smsg.step == e_step_fail)
|
||
{
|
||
pif->pl.hdlCommSent(pif->smsg.sending.msgident,_FAILURE);
|
||
}
|
||
else
|
||
{
|
||
pif->pl.hdlCommSent(pif->smsg.sending.msgident,_ABANDON);
|
||
}
|
||
}
|
||
}
|
||
|
||
while(sfifo_empty(&(pif->send))==false)
|
||
{
|
||
if(sfifo_read(&(pif->send),&(pif->smsg.sending)))
|
||
{
|
||
if(pif->smsg.sending.cb != NULL) pif->smsg.sending.cb(pif->smsg.sending.msgident,_ABANDON);
|
||
else if (pif->pl.hdlCommSent != NULL) {pif->pl.hdlCommSent(pif->smsg.sending.msgident,_ABANDON);}
|
||
}
|
||
}
|
||
|
||
|
||
memset(&pif->smsg,0x00,sizeof(pif->smsg));
|
||
|
||
return true;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////////
|
||
//CanDrvCtrl 模块消息处理部分
|
||
////////////////////////////////////////////////////////////////////////////////////////////
|
||
static void hdlCanCtrlMsg(e_link_sts msg,unsigned char chan)
|
||
{
|
||
st_if* pif=GetIfFromChanel(chan);
|
||
if(pif == NULL) return;
|
||
|
||
switch(msg)
|
||
{
|
||
case e_sts_needsend:
|
||
if(pif->linkSts >= e_sts_working) HdlAllSengMsgSts(pif);
|
||
break;
|
||
case e_err_overfllow:
|
||
if(pif->linkSts >= e_sts_working && pif->pl.hdlBusError!= NULL)
|
||
{
|
||
pif->pl.hdlBusError(e_err_overfllow);
|
||
}
|
||
break;
|
||
case e_err_receive:
|
||
|
||
if(pif->linkSts >= e_sts_working && pif->pl.hdlBusError!= NULL)
|
||
{
|
||
pif->pl.hdlBusError(e_err_receive);
|
||
}
|
||
|
||
break;
|
||
case e_err_sending:
|
||
if(pif->linkSts >= e_sts_working)
|
||
{
|
||
HdlSendMsgError(pif);
|
||
if(pif->pl.hdlBusError!= NULL)pif->pl.hdlBusError(e_err_sending);
|
||
}
|
||
break;
|
||
case e_err_bussoff:
|
||
if(pif->linkSts >= e_sts_working)
|
||
{
|
||
if(pif->smsg.step == e_step_waitack)
|
||
{
|
||
pif->smsg.step = e_step_fail;
|
||
can_kill( E_CAN_MSG_SIG,e_sts_needsend,pif->canif.chan);
|
||
}
|
||
|
||
if(pif->pl.hdlBusError!= NULL)
|
||
{
|
||
pif->pl.hdlBusError(e_err_bussoff);
|
||
}
|
||
else
|
||
{
|
||
plCloseLink(pif->canif.chan);
|
||
plConfigBus(pif->canif.chan, 0, 0, 0);
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
//达到这里则出错
|
||
break;
|
||
}
|
||
}
|
||
|
||
static void CAN_MSG_SIG_FUNC(unsigned int signal, int para1, int para2)
|
||
{
|
||
hdlCanCtrlMsg(para1, para2);
|
||
}
|
||
|
||
|
||
static void CAN_MSG_CB_SIG_FUNC(unsigned int signal, int para1, int para2)
|
||
{
|
||
void (*hdlCommSent)(unsigned int canid, unsigned int result);
|
||
|
||
hdlCommSent = (void *)para1;
|
||
|
||
if (hdlCommSent != NULL)
|
||
{
|
||
hdlCommSent(para2, _SUCCESS);
|
||
}
|
||
}
|
||
|
||
|
||
//协议层需要提供能接口
|
||
|
||
bool InstallProtocalToIF(unsigned char chan, st_pl* ppl, st_cl * pcl)
|
||
{
|
||
st_if* pif = NULL;
|
||
st_pl *p_pl;
|
||
|
||
pif=GetIfFromChanel(chan);
|
||
|
||
if(pif == NULL || ppl == NULL||pcl==NULL) return false;
|
||
|
||
if(ppl->prompt[0]== 0 || pif->linkSts != e_sts_unused)
|
||
{
|
||
M_DEBUGF("[CDCtrl]InstallProtocalToIF:协议名字为空或接口已安装有协议(%d)\n",pif->linkSts);
|
||
return false;
|
||
}
|
||
|
||
if((ppl->flg&CAN_FLG_SYNCRECEIVE) && ppl->hdlRecCanMsg == NULL)
|
||
{
|
||
M_DEBUGF("[CDCtrl]InstallProtocalToIF: 未提供hdlRecCanMsg 接口\n");
|
||
return false;
|
||
}
|
||
|
||
pif->pl.msgNumber = ppl->msgNumber;
|
||
if(pif->pl.msgNumber == 0) pif->pl.msgNumber=50; //默认是50
|
||
|
||
pif->psend = CAN_MALLOC(sizeof(st_senditem)*pif->pl.msgNumber);
|
||
if(pif->psend != NULL)
|
||
{
|
||
sfifo_init(&pif->send,pif->psend,sizeof(st_senditem),pif->pl.msgNumber);
|
||
}
|
||
else
|
||
{
|
||
M_DEBUGF("[CDCtrl]InstallProtocalToIF:内存分配失败,请求分配内存空间%d*%d\n",sizeof(st_senditem),pif->pl.msgNumber);
|
||
return false;
|
||
}
|
||
|
||
if((ppl->flg&CAN_FLG_SYNCRECEIVE)==0)
|
||
{
|
||
pif->prec = CAN_MALLOC(sizeof(st_recitem)*pif->pl.msgNumber);
|
||
if(pif->prec != NULL)
|
||
{
|
||
sfifo_init(&pif->rec,pif->prec,sizeof(st_recitem),pif->pl.msgNumber);
|
||
}
|
||
else
|
||
{
|
||
CAN_FREE(pif->psend);
|
||
pif->psend = NULL;
|
||
M_DEBUGF("[CDCtrl]InstallProtocalToIF:内存分配失败,请求分配内存空间%d*%d\n",sizeof(st_senditem),pif->pl.msgNumber);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
pif->pl.flg = ppl->flg;
|
||
p_pl = &(pif->pl);
|
||
|
||
memset(p_pl->prompt,0x00,sizeof(ppl->prompt));
|
||
CAN_COPY(p_pl->prompt,ppl->prompt,sizeof(ppl->prompt)-1);
|
||
p_pl->hdlBusError = ppl->hdlBusError;
|
||
p_pl->hdlRecCanMsg= ppl->hdlRecCanMsg;
|
||
p_pl->resendTimes = ppl->resendTimes;
|
||
p_pl->hdlCommSent = ppl->hdlCommSent;
|
||
|
||
pcl->canBusFilterInit = plcanBusFilterInit;
|
||
pcl->ConfigBus = plConfigBus;
|
||
pcl->GetCurrentLinkSts = plGetCurrentLinkSts;
|
||
pcl->REC = plReceive;
|
||
pcl->SEND = plSend;
|
||
pcl->CloseLink = plCloseLink;
|
||
|
||
pif->linkSts = e_sts_closed;
|
||
|
||
|
||
return true;
|
||
|
||
}
|
||
|
||
|
||
bool UninstallProtocalToIF(unsigned char chan, st_pl* ppl)
|
||
{
|
||
st_if* pif=NULL;
|
||
|
||
pif=GetIfFromChanel(chan);
|
||
|
||
if(ppl == NULL || pif == NULL) return false;
|
||
|
||
if(CAN_CMPY(ppl->prompt,pif->pl.prompt,sizeof(ppl->prompt)-1) != 0)
|
||
{
|
||
M_DEBUGF("协议层接口指针不匹配\n");
|
||
return false;
|
||
}
|
||
|
||
//将状态切换到未使用状态
|
||
pif->linkSts = e_sts_unused;
|
||
|
||
if(pif->canif.canCloseFilter != NULL)
|
||
{
|
||
pif->canif.canCloseFilter(chan);
|
||
}
|
||
if(pif->canif.canClose != NULL)
|
||
{
|
||
pif->canif.canClose(chan);
|
||
}
|
||
|
||
//释放空间
|
||
if((pif->pl.flg&CAN_FLG_SYNCRECEIVE)==0 && pif->prec != NULL)
|
||
{
|
||
CAN_FREE(pif->prec);
|
||
pif->prec = NULL;
|
||
}
|
||
if(pif->psend != NULL)
|
||
{
|
||
CAN_FREE(pif->psend);
|
||
pif->psend = NULL;
|
||
}
|
||
|
||
|
||
memset(&pif->pl,0x00,sizeof(st_pl));
|
||
memset(&pif->smsg,0x00,sizeof(st_sendmsg));
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
void InitCanDrvCtrlMode(void)
|
||
{
|
||
unsigned char i;
|
||
|
||
for(i=0;i<NELEMENTS(CanIF);i++)
|
||
{
|
||
memset(&CanIF[i],0x00,sizeof(st_if));
|
||
CanIF[i].canif.chan = 0xFF;
|
||
}
|
||
StartResendMsgTmr();
|
||
|
||
can_signal(E_CAN_MSG_SIG, CAN_MSG_SIG_FUNC);
|
||
can_signal(E_CAN_MSG_CB_SIG, CAN_MSG_CB_SIG_FUNC);
|
||
}
|
||
|
||
//#if DBG_CANCTRL > 0
|
||
#if 0
|
||
const static char* stsprompt[]={
|
||
"e_sts_empty",
|
||
"e_sts_unused",
|
||
"e_sts_closed",
|
||
"e_sts_working",
|
||
};
|
||
const static char* errprompt[]={
|
||
"e_err_receive",
|
||
"e_err_sending",
|
||
"e_err_overfllow",
|
||
};
|
||
|
||
void DprintCanDrvCtrl(void)
|
||
{
|
||
unsigned char i;
|
||
|
||
for(i=0;i<NELEMENTS(CanIF);i++)
|
||
{
|
||
M_DEBUGF("[%d]:%d:%s\n",i,CanIF[i].canif.chan,(CanIF[i].linkSts<80)?stsprompt[CanIF[i].linkSts]:errprompt[CanIF[i].linkSts-80]);
|
||
if(CanIF[i].linkSts > e_sts_unused)
|
||
{
|
||
M_DEBUGF("\tprotocol:%s\n",CanIF[i].pl.prompt);
|
||
}
|
||
M_DEBUGF("\tMsg Step:%d\n",CanIF[i].smsg.step);
|
||
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
|