#ifndef _CANFRAME_H_ #define _CANFRAME_H_ #include "stdBool.h" /* */ /*******************宏*********************/ /*设置支持最大的标识符*/ #define CAN_MAXSTD 0x20 /*设置支持最大的地址*/ #define CAN_MAXADDR 0x30 /*设置互斥锁 操作系统上多任务使用*/ #define CAN_LOCK 0 #define CAN_DATA_SIZE 4 /**********普通类型***********/ typedef unsigned char CFUint8; typedef unsigned short CFUint16; typedef unsigned int CFUint32; typedef signed char CFInt8; typedef signed short CFInt16; typedef signed int CFInt32; /*CAN数据帧中的上下行方式*/ /*属于写数据,对接受方有写含义*/ #define CAN_WRITE 1 /*属于读数据,对接受方没有写含义*/ #define CAN_READ 0 /*CAN通信上的协议命令定义*/ /* * 8BIT数据命令 * 0BIT:判断该数据是写的还是被读的 * 1-3BIT:长度 * 4-7BIT:命令类型 */ #pragma pack(1) typedef struct { CFUint8 WR:1; CFUint8 len:3; CFUint8 type:4; }CFCmd; /*can通信上的格式*/ typedef struct { CFCmd cmd; /*该协议帧的命令*/ CFUint8 addr; /*该协议帧的地址*/ CFUint8 data[CAN_DATA_SIZE]; /*协议帧的数据*/ CFUint8 sn; /*发送序号,每次发送成功加1*/ }CanFormat; #pragma pack() /*定义函数指针*/ typedef void(*TFunc)(void* parameter); /*记录当前状态*/ typedef enum { CanTalk_Normal, CanTalk_SendFailed, /*发送失败*/ CanTalk_RecTimeOut, /*接受超时*/ }CanTalkStu; /*模式 用于监听,或者写数据*/ /*普通监听数据*/ #define CANTalk_Listen 0x00 /*监听数据,回复读数据*/ #define CANTalk_Listen_Read 0x01 /*总线写绑定*/ #define CANTalk_Write 0x02 /*总线写绑定,回复读数据*/ #define CANTalk_Write_needRead 0x03 /*用于周期触发,还是改写触发*/ #define CANTalk_Period 0x00 #define CANTalk_Trigger 0x01 #if CAN_LOCK == 1 typedef void* CANMutex; #endif /*记录当前的方式*/ typedef struct { CFUint8 mode:3; CFUint8 trigger:2; CFUint8 other:3; }CanTalkWay; /*CAN通信架构的信息记录*/ typedef struct { /*用于记录时间周期*/ CFInt16 sendLastTime; /*记录发送的上一次时间*/ CFInt16 sendPeriodTimeout; /*记录发送周期超时时间*/ CFInt16 sendTimeout; /*记录超时发送时间*/ CFInt16 recLastTime; /*记录上一次接受时间*/ CFInt16 recTimeOut; /*记录接受超时*/ bool isSend; /*是否需要发送数据*/ bool isRUpdate; /*是否读更新*/ bool isWUpdate; /*是否写更新*/ bool isSendSucess; /*是否发送成功,用于需要回复的模式*/ CanTalkStu stu; /*用于记录通信状态*/ CanTalkWay way; /*记录该通信因子的方式*/ TFunc rfunc; /*用于接受到数据后的回调函数*/ TFunc sfunc; /*用于发送成功后进入的回调函数*/ TFunc efunc; /*用于出现错误后进入的回调函数*/ /*CAN通信上的数据位*/ CFUint8 wdata[CAN_DATA_SIZE]; CFUint8 rdata[CAN_DATA_SIZE]; /*绑定的数据长度*/ CFUint8 bindlen; /*发送序号*/ CFUint8 sn; /*接受到发送序号*/ CFUint8 rn; #if CAN_LOCK == 1 /*用于多线程的锁*/ CANMutex mutex; #endif }CanTalkInfo; typedef CanTalkInfo* CanTalkHandle; typedef struct { CanTalkHandle* fifo; unsigned int std; unsigned int addr; }CanHandle; extern CanHandle allCanHandle; //extern CanTalkHandle allCanHandle[CAN_MAXSTD][CAN_MAXADDR]; /******************************************************函数**************************************************************/ extern void FCanFrameInit(void); /*创建一个CAN通信因子*/ extern CanTalkHandle createCanHandle(CanHandle* handle,unsigned int std,unsigned int addr,unsigned int bindlen,unsigned char mode,unsigned char trigger); #define FCreateCanHandle(a,b,c,d,e) createCanHandle(&allCanHandle,a,b,c,d,e) /************************回调函数***************************/ /*绑定CAN上的发送成功函数*/ extern void FBindCanWriteSucessFuc(CanTalkHandle handle,TFunc func); /*绑定CAN上的读取到新数据的回调函数*/ extern void FBindCanReadyreadFuc(CanTalkHandle handle,TFunc func); /*绑定CAN数据产生错误的回调函数*/ extern void FBindCanErrorFuc(CanTalkHandle handle,TFunc func); /************************************************超时设置********************************************************/ /*设置CAN通信因子上的发送超时时间*/ extern void FSetCanSendTimeout(CanTalkHandle handle,int timeOut); /*设置CAN通信因子上的周期发送超时时间*/ extern void FSetCanSendPeriodTimeout(CanTalkHandle handle,int timeOut); /*设置CAN通信上的接受超时时间*/ extern void FSetCanRecTimeout(CanTalkHandle handle,int timeOut); /**********************************************获取数据**********************************************************/ /*获取CAN得到的写数据*/ extern void FGetCanWData(CanTalkHandle handle,void* rData,const int len); extern int getCanWDataS(CanHandle* handle,unsigned int std,unsigned int addr,void* rData,const int len); #define FGetCanWDataS(a,b,c,d) getCanWDataS(&allCanHandle,a,b,c,d) /*获取CAN得到的读数据*/ extern void FGetCanRData(CanTalkHandle handle,void* rData,const int len); extern int getCanRDataS(CanHandle* handle,unsigned int std,unsigned int addr,void* rData,const int len); #define FGetCanRDataS(a,b,c,d) getCanRDataS(&allCanHandle,a,b,c,d) /****************************************************设置数据*********************************************************/ /*设置CAN的发送数据*/ extern int FSetCanData(CanTalkHandle handle,void* data,const int len); extern int setCanDataS(CanHandle* handle,unsigned int std,unsigned int addr,void* data,const int len); #define FSetCanDataS(a,b,c,d) setCanDataS(&allCanHandle,a,b,c,d) /*CAN定时运行的任务*/ extern void canTask(CanHandle* handle); #define FCanTask() canTask(&allCanHandle) /*从硬件中得到数据源*/ extern int pushCanFrame(CanHandle* handle,const int stdvalue, CanFormat rdata); #define FPushCanFrame(a,b) pushCanFrame(&allCanHandle,a,b) /*设置can的发送序号*/ extern int setCansn(CanHandle* handle,unsigned int std,unsigned int addr,unsigned char sn); #define FSetCansn(a,b,c) setCansn(&allCanHandle,a,b,c) /*获取can的发送序号*/ extern int getCansn(CanHandle* handle,unsigned int std,unsigned int addr); #define FGetCansn(a,b) getCansn(&allCanHandle,a,b) /*获取can的接受发送序号*/ extern int getCanrn(CanHandle* handle,unsigned int std,unsigned int addr); #define FGetCanrn(a,b) getCanrn(&allCanHandle,a,b) /* *设置集群号,表示在一个集群号内不允许有相同的仲裁段出现 *那么不同集群号,则可以有相同的仲裁出现 *仲裁段8位,剩余的4位留来作为集群号 *can的标志帧的仲裁段是12位 */ extern void setClusterNumber(unsigned char number); /************************************************对外的宏接口*******************************************/ /********************************************需要移植****************************************************/ /***********需要根据不同平台调整的函数*************/ /*写CAN数据*/ extern int FWriteCan(unsigned int std,void* wdata,const unsigned int len); #if CAN_LOCK == 1 extern CANMutex cancreateMutex(void); extern void canLock(CANMutex mutex); extern void canUnlock(CANMutex mutex); #else #define cancreateMutex() #define canLock(x) #define canUnlock(x) #endif #define can_malloc malloc #define can_free free #endif