📄 ccpsim.c
字号:
/*----------------------------------------------------------------------------
| File:
| CCPSIM.C
|
| Project:
| CCP Driver Example
| CCPSIM - PC Emulation of a ECU using CCP
|
----------------------------------------------------------------------------*/
#define STRICT
#include <windows.h>
#include "stdio.h"
#include "conio.h"
// CAN driver
#include "VCanD.h"
// CCP driver
#include "CCP.h"
// ECU simulation
#include "ecu.h"
///////////////////////////////////////////////////////////////////////
// Defines
#define CCP_CANAPE
#define APP_NAME "CCPsim"
///////////////////////////////////////////////////////////////////////
// Statics
static void canMain( void );
// Datensegment-Pointer
#ifdef __BORLANDC__
#define isDllAddr 0x58
extern CCP_BYTE __isDLL;
static CCP_DWORD dataSeg = (CCP_DWORD)(&__isDLL-isDllAddr);
#else
extern CCP_BYTE __xc_a;
static CCP_DWORD dataSeg = (CCP_DWORD)&__xc_a;
#endif
///////////////////////////////////////////////////////////////////////
// Globals
int hwType = HWTYPE_VIRTUAL;
int hwChannel = 0;
int hwIndex = 0;
VportHandle gPortHandle = INVALID_PORTHANDLE;
Vaccess gChannelMask = 0;
Vaccess gPermissionMask = 0;
VDriverConfig *gDriverConfig = 0;
unsigned int gBitRate = 0;
int gDebugLevel = 1;
static HANDLE threadHandle = 0;
static CCP_DWORD threadId = 0;
static int threadRunning = 0;
unsigned long gDtoId = 0x000007e1;
unsigned long gCroId = 0x00000667;
unsigned short gStationAddr = 57;
#ifdef CCP_CANAPE
int hwType0 = -1, hwIndex0 = -1, hwChannel0 = -1;
int hwType1 = -1, hwIndex1 = -1, hwChannel1 = -1;
Vstatus _EXPORT_DECL ncdSetApplConfig(char *appId, int appChannel, int hwType, int hwIndex, int hwChannel);
Vstatus _EXPORT_DECL ncdGetApplConfig(char *appId, int appChannel, int *hwType, int *hwIndex, int *hwChannel);
#endif
#ifdef CCP_LATENCY_TEST
unsigned int ccpLatencyTime = 0;
#endif
///////////////////////////////////////////////////////////////////////
// InitDriver ()
//---------------------------------------------------------------------
// initializes the CAN driver
static Vstatus InitDriver( int hwType, int hwIndex, int hwChannel )
{
Vstatus vErr;
VsetAcceptance acc;
char name[16];
// Open the driver
vErr = ncdOpenDriver ();
if (vErr) goto error;
// Select a channel
gChannelMask = ncdGetChannelMask(hwType,hwIndex,hwChannel);
if (gChannelMask==0) return VERR_HW_NOT_PRESENT;
// If a virtual channel is used,
// make sure CANape channel 0 is configured to virtual channels
#ifdef CCP_CANAPE
if (hwType==HWTYPE_VIRTUAL) {
ncdGetApplConfig("CANape",0,&hwType0,&hwIndex0,&hwChannel0);
ncdGetApplConfig("CANape",1,&hwType1,&hwIndex1,&hwChannel1);
if (hwType0!=HWTYPE_VIRTUAL) {
ncdSetApplConfig("CANape",0,HWTYPE_VIRTUAL,0,0);
ncdSetApplConfig("CANape",1,HWTYPE_VIRTUAL,0,1);
printf("CANape has been reconfigured to use virtual channels !\n");
}
}
#endif
// Open a port
gPermissionMask = (gBitRate>0) ? gChannelMask : 0; // If no bitrate specified, don't init
sprintf(name,"CCPsim-%u",CCP_STATION_ADDR);
vErr = ncdOpenPort(&gPortHandle,name,gChannelMask, gPermissionMask, &gPermissionMask, 1024);
if (vErr) goto error;
// If permission to initialize
if (gPermissionMask) {
// Initialize the channels
vErr = ncdSetChannelBitrate(gPortHandle,gPermissionMask,gBitRate);
if (vErr) goto error;
// Reset the clock
vErr = ncdResetClock(gPortHandle);
if (vErr) goto error;
}
// Enable TX and TXRQ notifications
vErr = ncdSetChannelMode(gPortHandle,gChannelMask,1,1);
if (vErr) goto error;
// Set the acceptance filter
acc.code = CCP_CRO_ID;
acc.mask = (acc.code&0x80000000UL) ? 0x9FFFFFFFUL : 0x7FF; // relevant=1
vErr = ncdSetChannelAcceptance(gPortHandle,gChannelMask,&acc);
if (vErr) goto error;
return VSUCCESS;
error:
printf("ERROR: %s",ncdGetErrorString(vErr));
if (gPortHandle!=INVALID_PORTHANDLE) {
ncdClosePort(gPortHandle);
gPortHandle = INVALID_PORTHANDLE;
}
return vErr;
} // end InitDriver ()
///////////////////////////////////////////////////////////////////////
// CleanUp()
//---------------------------------------------------------------------
// close the port and the CAN driver
static Vstatus CleanUp(void)
{
ncdClosePort(gPortHandle);
gPortHandle = INVALID_PORTHANDLE;
#ifdef CCP_CANAPE
if (hwType0!=-1&&hwType0!=HWTYPE_VIRTUAL) {
ncdSetApplConfig("CANape",0,hwType0,hwIndex0,hwChannel0);
ncdSetApplConfig("CANape",1,hwType1,hwIndex1,hwChannel1);
}
#endif
ncdCloseDriver();
return VSUCCESS; // No error handling
} // ..end CleanUp()
CCP_BYTE canSendId( CCP_DWORD id, CCP_BYTE len, CCP_BYTEPTR msg ) {
Vstatus vErr;
Vevent event;
event.tag = V_TRANSMIT_MSG;
event.tagData.msg.id = id;
event.tagData.msg.flags = 0;
event.tagData.msg.dlc = len;
memcpy(&event.tagData.msg.data[0],msg,8);
vErr = ncdTransmit(gPortHandle, gChannelMask, &event);
if (vErr) {
printf("ERROR: %s\n",ncdGetErrorString(vErr));
return 0;
}
return 1;
}
///////////////////////////////////////////////////////////////////////
// ccpSend()
//---------------------------------------------------------------------
// Callback for ccp.c to send the CRM message
CCP_BYTE ccpSendId( CCP_DWORD id, CCP_BYTE len, CCP_BYTEPTR msg ) {
canSendId( id, len, msg );
if (gDebugLevel>=3 || (gDebugLevel==2 && msg[0]==0xff)) {
int i;
printf("TX: ");
for (i=0;i<len;i++) printf(" %02X",msg[i]);
printf("\n");
}
return 1;
}
// ccpSend() -------------------------------------------------------------------
//
void ccpSend(CCP_BYTEPTR msg ) {
ccpSendId(gDtoId,8,msg);
}
/**************************************************************************/
// CCPsim FLASH Emulation
/**************************************************************************/
#if defined(CCP_PROGRAM)
#define FLASH ccpFlash
#define FLASH_SIZE 1024*256
#define FLASH_START &ccpFlash[0]
#define FLASH_LAST &ccpFlash[FLASH_SIZE-1]
CCP_DWORD ccpCalPage = 0;
CCP_BYTE ccpFlash[FLASH_SIZE] = {0};
// ccpGetCalPage ---------------------------------------------------------------
//
// Call:
// - ccpCommand(), CC_GET_CAL_PAGE
// - ccpGetCalPage()
CCP_DWORD ccpGetCalPage( void ) {
return ccpCalPage;
}
// ccpSetCalPage ---------------------------------------------------------------
//
// Call:
// - ccpCommand(), CC_SET_CAL_PAGE
// - Calpage detect from ccp.MTA[0]
void ccpSetCalPage( CCP_DWORD a ) {
ccpCalPage = a;
#ifdef CCP_TESTMODE
if (gDebugLevel) {
printf("Set Calibration Page to %s\n",(a)?"FLASH":"RAM");
}
#endif
}
void ccpWriteFlash( void ) {
FILE *f = fopen("CCPSIM.DAT","wb");
if (f) {
fwrite(ccpFlash,FLASH_SIZE,1,f);
fclose(f);
}
}
int ccpReadFlash( void ) {
FILE *f = fopen("CCPSIM.DAT","rb");
int n;
if (f) {
n = fread(ccpFlash,FLASH_SIZE,1,f);
fclose(f);
return n;
}
return 0;
}
static void ccpInitFlash( void ) {
int i;
if (ccpReadFlash() && *(CCP_DWORD*)&ccpFlash[CALRAM_SIZE-4]==0x0055AAFF) {
for (i=0;i<CALRAM_SIZE;i++) CALRAM[i] = ccpFlash[i];
#ifdef CCP_TESTMODE
if (gDebugLevel) {
printf("\nInitialized calibration RAM from FLASH\n\n");
}
#endif
} else {
for (i=0;i<CALRAM_SIZE;i++) ccpFlash[i] = CALRAM[i];
ccpWriteFlash();
}
}
// ccpFlashClear() -------------------------------------------------------------
//
// -> Flash is set to 0xff
//
// Call:
// - ccpCommand(), CC_CLEAR_MEMORY
// - check protection state
//#pragma argsused
void ccpFlashClear( CCP_BYTEPTR a, CCP_DWORD size ) {
int i;
for (i=0;i<CALRAM_SIZE;i++) ccpFlash[i] = 0xff;
}
// ccpFlashProgramm() ----------------------------------------------------------
// a is a pointer to RAM or FLASH depending on ccpCalPage
// for ccpCalPage == RAM it is redirected to FLASH
//
// The example shows only how to flash calibration RAM. It don't shows
// how to flash programs.
// Call:
// - ccpCommand(), CC_PROGRAM
// - ccpCommand(), CC_PROGRAM6
// - check protection state
CCP_BYTE ccpFlashProgramm( CCP_BYTEPTR data, CCP_BYTEPTR a, CCP_BYTE size ) {
int i;
if (size==0) { // Flashen von Programmen
for (i=0;i<CALRAM_SIZE;i++) CALRAM[i] = ccpFlash[i];
ccpWriteFlash();
ccp.SessionStatus &= ~SS_CONNECTED; /* DISCONNECT */
} else { // Flashen von Parametern
for (i=0;i<size;i++) {
CCP_BYTEPTR f = (ccpCalPage==0) ? ccpFlash + (a-CALRAM) : a;
if (f>=ccpFlash&&f<ccpFlash+FLASH_SIZE) {
f[i] = data[i];
} else {
printf("WARNING: illegal memory access, address=0x%08X\n",f);
}
}
}
return CCP_WRITE_OK;
}
#endif
/**************************************************************************/
// ccpCheckWriteAccess, ccpGetPointer, ccpGetSeed, ccpUnlock
// ccpDisableNormalOperation, ccpUserBackground
// Platform and implementation specific functions for the CCP driver
/**************************************************************************/
// ccpCheckWriteAccess()
//
// goal in that exmple:
// -> protect FLASH addresses
// -> protect struct ccp
//
// Call:
// - ccpCommand(), CC_DNLOAD, CC_DNLOAD6
// - check protection state
// - ccpWriteMTA()
#if defined(CCP_WRITE_PROTECTION)
CCP_BYTE ccpCheckWriteAccess( CCP_BYTEPTR a, CCP_BYTE size ) {
// Protect FLASH
#ifdef CCP_PROGRAM
if (a>=FLASH_START && a<=FLASH_LAST) {
printf("WARNING: illegal FLASH write access, address=0x%08X, size=%u\n",a,size);
return CCP_WRITE_DENIED;
}
#endif
// Protect CCP
if ((a>(CCP_BYTEPTR)&ccp) && (a<((CCP_BYTEPTR)&ccp)+sizeof(struct ccp))) {
printf("WARNING: illegal write access to CCP area, address=0x%08X, size=%u\n",a,size);
return CCP_WRITE_DENIED;
}
return CCP_WRITE_OK;
}
#endif
// ccpGetPointer() -------------------------------------------------------------
//
// Convert a CCP CCP_BYTE,CCP_DWORD address to a C pointer
// #pragma argsused
// Call 1:
// - ccpCommand(), CC_SET_MTA
// - ccpGetPointer()
// - ccpSetMTA()
//
// Call 2:
// - ccpCommand(), CC_SHORT_UPLOAD
// - ccpGetPointer()
// - ccpSetMTA()
// - ccpReadMTA()
//
// Call 3:
// - ccpCommand(), CC_WRITE_DAQ
CCP_BYTEPTR ccpGetPointer( CCP_BYTE addr_ext, CCP_DWORD addr ) {
CCP_BYTEPTR a = (CCP_BYTEPTR)(addr+dataSeg);
if (addr<2) return (CCP_BYTEPTR)addr;
#if defined(CCP_CALPAGE)
if (a>=(CCP_BYTE*)&CALRAM_START && a<=(CCP_BYTE*)&CALRAM_LAST) { // Address within Calibration RAM
if (ccpCalPage==0) { // RAM
return (CCP_BYTEPTR)a;
} else { // FLASH
return (CCP_BYTEPTR)(ccpFlash+(a-(CCP_BYTE*)&CALRAM_START));
}
} else
#endif
{
return (CCP_BYTEPTR)a;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -