gateway.cxgate
来自「CAN 网关原代码,汽车电子中的总线网关」· CXGATE 代码 · 共 517 行 · 第 1/2 页
CXGATE
517 行
#include "peripherals.h"
#include "gateway_data_dims.h"
#include "gateway.h"
#include "load_meas.h"
#pragma MESSAGE DISABLE C2705
#pragma CODE_SEG XGATE_CODE
#pragma DATA_SEG __RPAGE_SEG XGATE_DATA
/* takes node descriptor and Rx frame ID and resolves it into pointer to a frame with a matching ID */
/* returns NULL in case the frame was not found */
/* based on binary seach algorithm, the IDs need to be sorted in ascending order for the function to work */
/* adopted code from http://fxr.watson.org/fxr/source/libkern/bsearch.c */
tRxFrmDescr *RxFindFrmId(int FrmId, tNodeDescr *node) {
tRxFrmDescr *base=(node->rx_idx_start_p);
int i;
int result;
tRxFrmDescr *p;
for (i = node->rx_idx_cnt; i != 0; i >>= 1) {
p = base + (i >> 1);
result = FrmId-(p->ID);
/* if spot on, return the index */
if (result==0) return(p);
/* moving right? */
if (result>0) {
/* adjust the index and base */
base=p+1;
i--;
}
}
return (NULL);
}
#if (GATEWAY_TX_FRM_CNT>0)
/* this routine copies a signal */
/* signals are supposed to be in Little Endian (bit 0 in a message is LSB of byte 0) */
/* parameters: signal destination, pointer to 8-byte data buffer, position of the signal in the buffer, size of the signal in bits minus 1 (0 means copy 1 bit)*/
/* it returns 1 in case src and dest data differ, 0 otherwise */
int CopySignalChk(tSignalDestDescr *dest, unsigned char *srcp, char src_pos, signed char size) {
int change=0;
unsigned int data;
unsigned int mask;
unsigned char *destp=TxTable[dest->frame_no].Data; /* pointer to destination data */
char dest_pos=dest->position; /* destination position */
size++; /* adjust the size - all this is needed to be able to represent 64 bit long signal in 6 bits */
destp+=dest_pos>>3; /* adjust destination pointer if position is outside of the first byte */
dest_pos&=0x07;
/* transfer first byte */
srcp+=src_pos>>3; /* adjust source pointer if position is outside of the byte it points to */
src_pos&=0x07; /* trim position */
mask=~(0xff<<size); /* mask now determines which bits belong to the signal after shifting down to bit 0 position */
mask<<=dest_pos; /* shift the mask so it determines which bits we need to copy in the destination byte */
data=(*srcp)+((*(srcp+1))<<8); /* load source data */
data>>=src_pos; /* shift the signal down to begin at bit 0 */
data<<=dest_pos; /* shift the signal up to align it with its destination */
data&=mask; /* filter data bits with the mask */
if (((*destp)&mask)!=(data&0x0ff)) { /* change in data contents? */
change=1; /* adjust change */
*destp=((*destp)&(~mask))|data; /* clear bits belonging to the signal and or the new data in */
}
size-=(8-dest_pos);
if (size>0) { /* do not bother with any of the remaining code if the copy is complete (optimization for small signals) */
src_pos+=(8-dest_pos);/* source position needs to be adjusted by the number of bits which have been alredy copied */
srcp+=src_pos>>3; /* adjust source pointer if position is outside of the byte it points to */
src_pos&=0x07; /* trim position */
destp++; /* point to the next destination byte */
/* transfer whole bytes (if any) */
while(size>8) {
data=(*srcp)+((*(srcp+1))<<8); /* load source data */
data>>=src_pos; /* shift the signal down to begin at bit 0 */
if ((*destp)!=(data&0xff)) { /* change in data contents? */
change=1; /* adjust change */
*destp=data; /* copy new data in */
}
size-=8; /* adjust size and source pointer */
srcp++;
destp++; /* point to the next destination byte */
}
/* transfer remaining bits (if any) */
if (size>0) {
mask=~(0xff<<size); /* mask now determines which bits belong to the signal after shifting down to bit 0 position */
data=(*srcp)+((*(srcp+1))<<8); /* load source data */
data>>=src_pos; /* shift the signal down to begin at bit 0 */
data&=mask; /* filter data bits with the mask */
if (((*destp)&mask)!=(data&0xff)) { /* change in data contents? */
change=1; /* adjust change */
*destp=((*destp)&(~mask))|data; /* clear bits belonging to the signal and or the new data in */
}
}
}
return(change);
}
/* this routine copies a signal */
/* signals are supposed to be in Big Endian (bit 0 in a signal is MSB (bit 7) of byte 0 (first byte in the buffer)) */
/* parameters: signal destination, pointer to 8-byte data buffer, position of the signal in the buffer, size of the signal in bits minus 1 (0 means copy 1 bit)*/
/* it returns 1 in case src and dest data differ, 0 otherwise */
int CopySignalChkBE(tSignalDestDescr *dest, unsigned char *srcp, char src_pos, signed char size) {
int change=0;
unsigned int data;
unsigned int mask;
unsigned char *destp=TxTable[dest->frame_no].Data; /* pointer to the destination data */
char dest_pos=dest->position; /* destination position */
size++; /* adjust the size - needed to be able to represent 64 bit long signal in 6 bits */
destp+=(dest_pos>>3); /* adjust the destination pointer */
dest_pos&=0x07; /* trim position */
/* transfer first byte */
srcp+=src_pos>>3; /* adjust source pointer if position is outside of the first byte */
src_pos&=0x07; /* trim position */
mask=~(0xffff>>size); /* mask now determines which bits belong to the signal (mask is now aligned to MSB) */
mask>>=dest_pos; /* shift the mask so it determines which bits we need to copy into the destination byte */
mask>>=8; /* move the mask into the lower byte */
data=((*srcp)<<8)+(*(srcp+1)); /* load source data (first byte in MSB, second byte in LSB) */
data<<=src_pos; /* shift the signal up to begin at bit 15 (MSB) */
data>>=dest_pos; /* shift the signal down to align it with its destination */
data>>=8; /* move the data into the lower byte */
data&=mask; /* filter data bits with the mask */
if (((*destp)&mask)!=data) { /* change in data contents? */
change=1; /* indicate change */
*destp=((*destp)&(~mask))|data; /* clear bits belonging to the signal and or the new data in */
}
size-=(8-dest_pos); /* decrease the number of bits left to copy */
if (size>0) { /* do not bother with any of the remaining code if the copy is complete (optimization for small signals) */
src_pos+=(8-dest_pos); /* source position needs to be adjusted by the number of bits which have been alredy copied */
srcp+=src_pos>>3; /* adjust source pointer if position is outside of the byte it points to */
src_pos&=0x07; /* trim position */
destp++; /* point to the next destination byte */
/* transfer whole bytes (if any) */
while(size>8) {
data=((*srcp)<<8)+(*(srcp+1)); /* load source data */
data<<=src_pos; /* shift the signal up to begin at bit 15 */
data>>=8; /* move the byte into the lower byte of the word */
if ((*destp)!=data) { /* change in data contents? */
change=1; /* indicate change */
*destp=data; /* copy new data in */
}
size-=8; /* adjust size and source pointer */
srcp++;
destp++; /* point to the next destination byte */
}
/* transfer remaining bits (if any) */
if (size>0) {
mask=~(0xffff>>size); /* mask now determines which bits belong to the signal (mask is now aligned to MSB) */
mask>>=8; /* move the mask into the lower byte */
data=((*srcp)<<8); /* load source data */
data<<=src_pos; /* shift the signal up to begin at bit 15 */
data>>=8; /* move the data into the lower byte */
data&=mask; /* filter data bits with the mask */
if (((*destp)&mask)!=data) { /* change in data contents? */
change=1; /* indicate change */
*destp=((*destp)&(~mask))|data; /* clear bits belonging to the signal and or the new data in */
}
}
}
return(change);
}
/* copies data from source to destination & checks for data changes */
/* returns 1 if source data differ from data at destination (before copying) and 0 if data are all the same */
int CopyDataChk(unsigned char * src, unsigned char * dest, int count) {
int result=0;
while(count) {
if ((*src)!=(*dest)) {
result=1;
*dest=*src;
}
dest++;
src++;
count--;
}
return(result);
}
/* copies signals from a buffer into their destinations */
/* frame_p is pointer to the Rx frame */
void CopySignals(unsigned char *buffer, tRxFrmDescr *frame_p) {
tSignalDescr *sig_addr; /* address of signal descriptor */
tSignalDestDescr *sigdest_addr; /* address of signal desctination descriptor */
int i,j;
int datachange;
/* point sig_addr to the first signal descriptor */
sig_addr = frame_p->pSignalDescr;
/* now process all the signals in the incomming frame */
for (i=frame_p->SignalCount;i>0;i--) {
/* update the sigdest_addr to point to the first destination */
sigdest_addr = (tSignalDestDescr*)((char*)sig_addr + sizeof(tSignalDescr));
/* go through all the signal destinations */
for (j=sig_addr->dests_no;j>0;j--) {
/* copy the signal */
if (frame_p->byte_copy) {
/* byte copy */
datachange=CopyDataChk(buffer + sig_addr->position, TxTable[sigdest_addr->frame_no].Data+sigdest_addr->position, (sig_addr->size)+1);
} else {
/* bit copy */
#ifdef LITTLE_ENDIAN
/* little endian */
datachange=CopySignalChk(sigdest_addr, buffer, sig_addr->position, sig_addr->size);
#else
/* big endian */
datachange=CopySignalChkBE(sigdest_addr, buffer, sig_addr->position, sig_addr->size);
#endif
}
/* transmit the destination frame in case it is to be transmitted on datachange */
/* the following expression is evaluated left-to-right, hence the more complicated condition is not evaluated if datachange==0 */
if ((datachange)&&(TxTable[sigdest_addr->frame_no].TxonDataChg)) {
FrameTransmit(&TxTable[sigdest_addr->frame_no]);
/* if not transmitted on datachange, check whether it is to be transmitted on reception */
} else if (TxTable[sigdest_addr->frame_no].TxonRx) {
FrameTransmit(&TxTable[sigdest_addr->frame_no]);
}
/* update sigdest_addr to point to the next destination */
sigdest_addr++;
}
/* after processing all the signal destinations the sigdest_addr points to the next signal descriptor */
sig_addr = (tSignalDescr*)sigdest_addr;
}
}
#endif
/* assignes bit at specified position in a buffer with specified value */
void BitAssign(int value, char position, unsigned char *buffer) {
/* increase the pointer by the number of whole bytes */
buffer+=position>>3;
/* trim position to within the byte pointed to by buffer */
position &= 0x07;
if (value) {
/* set the bit */
#ifdef LITTLE_ENDIAN
(*buffer) |= 1<<position;
#else
(*buffer) |= 0x80>>position;
#endif
} else {
/* clear the bit */
#ifdef LITTLE_ENDIAN
(*buffer) &= ~(1<<position);
#else
(*buffer) &= ~(0x80>>position);
#endif
}
}
/* this function is called in response to Rx Timeout */
/* it is only called after specified number of timeouts for the specific frame */
/* the parameter is the Rx frame pointer which caused the timeout */
void RxTimeoutHandler(tRxFrmDescr *frame_p) {
}
/* this function is called in response to frame reception */
/* the parameters are the Rx frame pointer which caused the event and pointer to the node descriptor to which the frame belongs */
void RxHandler(tRxFrmDescr *frame_p, tNodeDescr *node) {
}
/* this function is called in response to not receiving enough data or checksum error (Lin) */
/* the parameters are the Rx frame pointer which caused the event and pointer to the node descriptor to which the frame belongs */
void RxInvalidHandler(tRxFrmDescr *frame_p, tNodeDescr *node) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?