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 + -
显示快捷键?