?? ican.c
字號:
#include "config.h"
OS_FLAG_GRP *ican_pevent;//系統消息指針
iCANSLV iCANdeviceList[ICAN_SLV_NUM];//輪訓列表
/*******************************************/
#if ican_DRAM_Enalbe
INT8U dram[2048];//動態內存
#endif
/*******************************************/
INT8U ican_cet,ALL_OVER;//0未連接,1建立連接,2重復id
DEVICERCSR myDEVICERCSR; //從站數據邏輯地址表
INT8U deviceinf[32] =
{ /*類別********************************邏輯地址***********數組中的位置/長度*****/
0x00,0x01, //生產商ID 0xE0--0xE1 0/2
0x01,0x00, //產品類型 0xE2--0xE3 2/2
0x01,0x00, //產品型號 0xE4--0xE5 4/2
0xE8,0x03, //產品硬件版本 0xE6--0xE7 6/2
0xE8,0x03, //產品固件版本 0xE8--0xE9 8/2
0x80,0x40,0x32,0x03, //序列號 0xEA--0xED 10/4
0x02, //本機節點ID 0xEE
0xff, //CAN波特率 0xff為無效 0xEF
0x31,0x00,0x1C,0x00, //用戶特殊波特率 0xF0--0xF3
0xff, //循環模式定時 0xF4
0xff, //主站通訊定時 0xF5
0xff, //狀態改變觸發使能 0xF6
0xff, //主站地址 0xF7
0xff, //輸入輸出通道選擇 0xF8
0xff, //輸入輸出配置參數 0xF9
0xff,0xff,0xff,0xff,0xff,0xff //保留 0xFA--0xFF
};
/******************************iCAN申請動態內存**************************
作者:張森
日期:2008年4月6日
*************************************************************************/
#if ican_DRAM_Enalbe
void *ican_malloc(INT32U size)
{INT8U *p;
if(size>0)
{
p=reg_malloc (size);//申請
if(p==NULL)//內存滿
{
return (NULL);
}
else
{
return p;
}
}
else
{
return (NULL);
}
}
#endif
/******************************iCAN I/O初始化***************************
作者:張森
日期:2008年4月6日
*************************************************************************/
void ican_io_init(INT8U DI_len,INT8U *p_DI_len,INT8U DO_len,INT8U *p_DO_len,INT8U AI_len,INT8U *p_AI_len,INT8U AO_len,INT8U *p_AO_len)
{
myDEVICERCSR.DILen=DI_len;
myDEVICERCSR.DOLen=DO_len;
myDEVICERCSR.AILen=AI_len;
myDEVICERCSR.AOLen=AO_len;
myDEVICERCSR.pDIData=p_DI_len;
myDEVICERCSR.pDOData=p_DO_len;
myDEVICERCSR.pAIData=p_AI_len;
myDEVICERCSR.pAOData=p_AO_len;
}
/************************iCAN主站初始化**********************************
作者:張森
日期:2008年4月2日
**************************************************************************/
void master_init()
{
INT8U i,err;
ican_pevent=OSFlagCreate(0,&err);
iCANdeviceList[deviceinf[0x0e]].sla_status=3;
/*******************************************/
#if ican_DRAM_Enalbe
ican_init_mempool (dram,2048);//初始化動態內存
for(i=0;i<ICAN_SLV_NUM;i++)
{
iCANdeviceList[i].P_DILen =NULL;
iCANdeviceList[i].P_DOLen =NULL;
iCANdeviceList[i].P_AILen =NULL;
iCANdeviceList[i].P_AOLen =NULL;
}
#else
for(i=1;i<=CANXS;i++)
{
iCANdeviceList[i].DILen=2;
iCANdeviceList[i].P_DILen=&Vbuf[10*(i-1)];
iCANdeviceList[i].DOLen=2;
iCANdeviceList[i].P_DOLen =&Vbuf[10*(i-1)+2];
iCANdeviceList[i].AILen=4;
iCANdeviceList[i].P_AILen =&Vbuf[10*(i-1)+4];
iCANdeviceList[i].AOLen=3;
iCANdeviceList[i].P_AOLen =&Vbuf[3*(i-1)+173];
}
for(i=CANXS+1;i<6;i++)
{
iCANdeviceList[i].sla_status=3;
}
iCANdeviceList[6].DILen=7;
iCANdeviceList[6].P_DILen=&Vbuf[50];
iCANdeviceList[6].DOLen=7;
iCANdeviceList[6].P_DOLen =&Vbuf[57];
iCANdeviceList[6].AILen=10;
iCANdeviceList[6].P_AILen =&Vbuf[198];
iCANdeviceList[6].AOLen=0;
iCANdeviceList[6].P_AOLen =NULL;
#endif
/*******************************************/
CAN_Init(CAN1,5);
}
/******************************連續讀取從站數據命令**************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
SourceID 資源ID
SubSourceID 子資源ID(當SourceID<0xf9時,忽略子節點地址)
length 讀取長度
*****************************************************************************/
void ican_read_sla(INT8U DestMACID,INT8U SourceID,INT8U SubSourceID,INT8U length)
{INT8U read_sla_buf[2];
if(SourceID<0xf9)
{
ican_send(DestMACID,0,0x02,SourceID,&length,1);
}
else
{
read_sla_buf[0]=SubSourceID;
read_sla_buf[1]=length;
ican_send(DestMACID,0,0x02,SourceID,read_sla_buf,2);
}
}
/******************************連續讀取從站數據響應**************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
SourceID 資源ID (如有資源節點請放入*p的第一位)
*p的數據長度
*****************************************************************************/
void ican_read_sla_respond(INT8U DestMACID,INT8U SourceID,INT8U *p,INT8U D_long)
{
ican_send(DestMACID,1,0x02,SourceID,p,D_long);
}
/******************************連續寫入從站數據命令**************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
SourceID 資源ID(如有資源節點請放入*p的第一位)
*p 寫入的數據指針
D_long *p的數據長度
******************************************************************************/
void ican_write_sla(INT8U DestMACID,INT8U SourceID,INT8U *p,INT8U D_long)
{
ican_send(DestMACID,0,0x01,SourceID,p,D_long);
}
/******************************連續寫入從站數據響應***************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
SourceID 資源ID
******************************************************************************/
void ican_write_sla_respond(INT8U DestMACID,INT8U SourceID)
{
ican_send(DestMACID,1,0x01,SourceID,&SourceID,0); //&SourceID只起到格式作用,并不傳送
}
/******************************建立邏輯鏈接命令******************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
Cyclicmaster 主站通訊定時參數
******************************************************************************/
void ican_create_cnnet_sla (INT8U DestMACID)
{
INT8U create_cnnet_sla_buf[2];
create_cnnet_sla_buf[0]=deviceinf[0x0e];
create_cnnet_sla_buf[1]=deviceinf[0x15];
ican_send(DestMACID,0,0x04,0xf7,create_cnnet_sla_buf,2);
}
/******************************建立邏輯鏈接響應******************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
Cyclicmaster 主站通訊定時參數
******************************************************************************/
void ican_create_cnnet_sla_respond (INT8U DestMACID)
{
INT8U ican_create_cnnet_sla_respond[4];
ican_create_cnnet_sla_respond[0]=myDEVICERCSR.DILen;
ican_create_cnnet_sla_respond[1]=myDEVICERCSR.DOLen;
ican_create_cnnet_sla_respond[2]=myDEVICERCSR.AILen;
ican_create_cnnet_sla_respond[3]=myDEVICERCSR.AOLen;
ican_send(DestMACID,1,0x04,0xf7,ican_create_cnnet_sla_respond,4);
}
/******************************刪除邏輯鏈接命令******************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
******************************************************************************/
void ican_del_cnnet_sla(INT8U DestMACID)
{
ican_send(DestMACID,0,0x05,0xf7,&deviceinf[0x0e],1);
}
/******************************刪除邏輯鏈接響應******************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
******************************************************************************/
void ican_del_cnnet_sla_respond(INT8U DestMACID)
{
ican_send(DestMACID,1,0x05,0xf7,&DestMACID,0);//&DestMACID只起到格式作用,并不傳送
}
/*********************************復位從站命令*********************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
*******************************************************************************/
void ican_reset_sla(INT8U DestMACID)
{
ican_send(DestMACID,0,0x06,0x00,&DestMACID,1);
}
/*********************************復位從站響應*********************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
*******************************************************************************/
void ican_reset_sla_respond(INT8U DestMACID)
{
ican_send(DestMACID,1,0x06,0x00,&DestMACID,0);//&DestMACID只起到格式作用,并不傳送
}
/*********************************MACID檢測命令*********************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
*********************************************************************************/
void ican_check_slaID(INT8U DestMACID)
{
INT8U ican_check_slaID_buf[5];
ican_check_slaID_buf[0]=DestMACID;
ican_check_slaID_buf[1]=deviceinf[0x0a];
ican_check_slaID_buf[2]=deviceinf[0x0b];
ican_check_slaID_buf[3]=deviceinf[0x0c];
ican_check_slaID_buf[4]=deviceinf[0x0d];
ican_send(DestMACID,0,0x07,0x00,ican_check_slaID_buf,5);
}
/*********************************MACID檢測響應*********************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
*********************************************************************************/
void ican_check_slaID_respond(INT8U DestMACID)
{
INT8U ican_check_slaID_buf[5];
ican_check_slaID_buf[0]=DestMACID;
ican_check_slaID_buf[1]=deviceinf[0x0a];
ican_check_slaID_buf[2]=deviceinf[0x0b];
ican_check_slaID_buf[3]=deviceinf[0x0c];
ican_check_slaID_buf[4]=deviceinf[0x0d];
ican_send(DestMACID,1,0x07,0x00,ican_check_slaID_buf,5);
}
/***********************************錯誤響應*************************************
作者:張森
日期:2008年4月6日
參數:DestMACID 目標ID
SourceID 資源ID號
ERRID 錯誤類型
*********************************************************************************/
void ican_respond_err(INT8U DestMACID,INT8U SourceID,INT8U ERRID)
{
ican_send(DestMACID,1,0x0f,SourceID,&ERRID,1);
}
/***********************************消息處理*************************************
作者:張森
日期:2008年4月8日
參數:*p 消息隊列中儲存的動態內存的地址
*p_iCANSLV 從站列表結構體指針
*********************************************************************************/
void ican_respond(INT8U *p,iCANSLV *p_iCANSLV)
{
INT8U *p_buf,d_long,SrcMACID,ACK,FunCID,SourceID,err;
M(31,4)=M(31,5)=0;
p_buf=p;
p++;
d_long=*p;//長度
p++;
SrcMACID=*p;//數據來源
p++;
ACK=*p;//響應
p++;
FunCID=*p;//功能碼
p++;
SourceID=*p;//資源編號
p++;//數據的第一位
if (ACK==0)//請求幀
switch(FunCID)
{
case write_port://寫入數據
if(ican_cet==1)
{
if(SourceID<=0x1f)
{
ican_respond_err(SrcMACID,SourceID,cmd_unsupport); //資源不支持此命令
}
else
if(SourceID<=0x3f)
{
if(SourceID+d_long-1<=0x3f)//數據長度沒有超出
{
array_copy(p,&myDEVICERCSR.pDOData[SourceID-0x20],d_long);
ican_write_sla_respond(SrcMACID,SourceID);
}
else
{
ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符
}
}
else
if(SourceID<=0x5f)
{
ican_respond_err(SrcMACID,SourceID,cmd_unsupport); //資源不支持此命令
}
else
if(SourceID<=0x7f)
{
if(SourceID+d_long-1<=0x7f)//數據長度沒有超出
{
array_copy(p,&myDEVICERCSR.pAOData[SourceID-0x60],d_long);
ican_write_sla_respond(SrcMACID,SourceID);
}
else
{
ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符
}
}
else
{
ican_respond_err(SrcMACID,SourceID,res_unfound);//資源不存在
}
}
else
{
ican_respond_err(SrcMACID,SourceID,cnet_unexist); //沒有建立連接
}
break;
case read_port ://讀取數據
if(ican_cet==1)
{
if(SourceID<=0x1f)
{
if(SourceID+*p-1<=0x1f)//數據長度沒有超出
{
ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pDIData[SourceID],*p);
}
else
{
ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符
}
}
else
if(SourceID<=0x3f)
{
if(SourceID+*p-1<=0x3f)//數據長度沒有超出
{
ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pDIData[SourceID-0x20],*p);
}
else
{
ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符
}
}
else
if(SourceID<=0x5f)
{
if(SourceID+*p-1<=0x5f)//數據長度沒有超出
{
ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pAIData[SourceID-0x40],*p);
}
else
{
ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符
}
}
else
if(SourceID<=0x7f)
{
if(SourceID+*p-1<=0x7f)//數據長度沒有超出
{
ican_read_sla_respond(SrcMACID,SourceID,&myDEVICERCSR.pAIData[SourceID-0x60],*p);
}
else
{
ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//命令格式不符
}
}
else
{
ican_respond_err(SrcMACID,SourceID,res_unfound);//資源不存在
}
}
else
{
ican_respond_err(SrcMACID,SourceID,cnet_unexist); //沒有建立連接
}
break;
// case slv_to_mas_trigger ://從站自己觸發的數據 沒有這種情況
// break;
case creat_cnet://建立連接
if(d_long==2&& *p<0x40 )
{
if(ican_cet==1)
{
ican_respond_err(SrcMACID,SourceID,cmd_unsupport); //已經在連接狀態
}
else
{
ican_cet=1;
deviceinf[0x17]=*p;
p++;
deviceinf[0x15]=*p;
ican_create_cnnet_sla_respond(SrcMACID);//連接成功
}
}
else
{
ican_respond_err(SrcMACID,SourceID,funcID_parameter_unsupport);//參數格式不對
}
break;
case del_cnet://刪除鏈接
if(d_long==1&& *p<0x40 )
{
if(ican_cet==1)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -