This shows you the differences between two versions of the page.
robotsoftware:mobotware:rhd:plugins:hakocan [2012/09/06 16:06] claes created |
robotsoftware:mobotware:rhd:plugins:hakocan [2021/08/14 04:21] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== HakoCAN ====== | ||
- | ===== Doxygen documentation ===== | ||
- | [[http:// | ||
- | ===== Source Code ===== | ||
- | <sxh c; title: | ||
- | /** \file hakocan.h | ||
- | | ||
- | | ||
- | * | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | * | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | */ | ||
- | #ifndef HAKOCAN_H | ||
- | #define HAKOCAN_H | ||
- | |||
- | extern int initXML(char *); | ||
- | extern int periodic(int); | ||
- | //extern ”C” int terminate (void) ; //No shutdown function | ||
- | #define RPMCMD 0x200 | ||
- | #define CURVATURECMD 0x141 | ||
- | #define STEERINGREPORTREQ 0x408 | ||
- | #define STEERINGREPORT 0x409 | ||
- | #define CVTCONTROLCMD 0x080 | ||
- | #define STEERINGANGLECMD 0x142 | ||
- | #define HITCHCMD 0x090 | ||
- | #define CVTACK 0x750 | ||
- | #define STEERINGANGLEACK 0x75A | ||
- | #define STEERINGACK 0x758 | ||
- | #define HORNCMD 0x610 | ||
- | #define HORNACK 0x740 | ||
- | |||
- | #endif | ||
- | |||
- | </ | ||
- | |||
- | <sxh c; title: | ||
- | /** \file hakocan.c | ||
- | | ||
- | | ||
- | * | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | * | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | */ | ||
- | / | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | / | ||
- | #define HAKOCANVERSION " | ||
- | / | ||
- | # | ||
- | # | ||
- | / | ||
- | |||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | // | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | #include " | ||
- | #include " | ||
- | |||
- | /******** Global variables *************/ | ||
- | ///Index pointers for the variable database | ||
- | int iSteeringangleref, | ||
- | iSteeringangle, | ||
- | iNavigationmode, | ||
- | iHakostate1, | ||
- | iliftinggearpos, | ||
- | ig01, | ||
- | |||
- | //PThread definitions | ||
- | pthread_t canrx_thread, | ||
- | pthread_attr_t attr; | ||
- | |||
- | ///Number of CAN-messages to be send to CAN-bus in every cycle | ||
- | #define CANTXBUFSIZE 4 | ||
- | ///Number of CAN-messages to be received from the CAN-bus in every cycle | ||
- | #define CANRXBUFSIZE 3 | ||
- | #define DFLTENGSP 50 | ||
- | |||
- | #define BLOCK_MAX 200 | ||
- | |||
- | // Creation of communication buffers | ||
- | ///Receive buffer for CAN-messages | ||
- | struct canmsg_t canrxbuf[CANRXBUFSIZE]; | ||
- | ///Transmit buffer for CAN-messages | ||
- | struct canmsg_t cantxbuf[CANTXBUFSIZE]; | ||
- | ///CAN port pointer | ||
- | int can_dev, | ||
- | ///CAN port device identification string | ||
- | char canDevString[64]; | ||
- | char canDevString1[64]; | ||
- | ///Flag to indicate if HakoCan is running or not | ||
- | static volatile int hakocanRunning = -1; | ||
- | |||
- | //Function prototypes | ||
- | int initHakocan(void); | ||
- | void *canrx_task(void *); | ||
- | void *canrx_task1(void *); | ||
- | |||
- | /** \brief Initialization of the CAN-bus and all rx/tx buffers | ||
- | * | ||
- | * All buffers are initilized and database variables are created. | ||
- | * Finally, the RX Thread is spawned | ||
- | * | ||
- | */ | ||
- | int initHakocan(void) | ||
- | { | ||
- | //struct canmsg_t msg; | ||
- | //int ret; | ||
- | //union {float a;char b[4];}conv; | ||
- | |||
- | |||
- | // Open CAN port | ||
- | can_dev=open(canDevString, | ||
- | if (can_dev< | ||
- | fprintf(stderr," | ||
- | return -1; | ||
- | } | ||
- | if (canDevString1[0]!=0){ | ||
- | can_dev1=open(canDevString1, | ||
- | if (can_dev1< | ||
- | fprintf(stderr," | ||
- | return -1; | ||
- | } | ||
- | else{ | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | //Create CAN RX Thread | ||
- | pthread_attr_init(& | ||
- | pthread_attr_setinheritsched(& | ||
- | pthread_attr_setdetachstate(& | ||
- | |||
- | if (pthread_create(& | ||
- | perror(" | ||
- | return -1; | ||
- | } | ||
- | if (can_dev1){ | ||
- | pthread_attr_init(& | ||
- | pthread_attr_setinheritsched(& | ||
- | pthread_attr_setdetachstate(& | ||
- | if (pthread_create(& | ||
- | perror(" | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | |||
- | |||
- | //Create database variables (if everyting works) | ||
- | iSpeedref=createVariable(' | ||
- | iSteeringangleref | ||
- | icurvatureref | ||
- | iEnginespeedref | ||
- | ihitchposref | ||
- | iNavigationmoderef | ||
- | iliftinggearstateref | ||
- | ipowertakeoffstateref | ||
- | ig01 = createVariable(' | ||
- | ig02 = createVariable(' | ||
- | iptor = createVariable(' | ||
- | iauxr = createVariable(' | ||
- | ifll = createVariable(' | ||
- | iflr = createVariable(' | ||
- | ihlght | ||
- | irlght | ||
- | ihorn = createVariable(' | ||
- | iNavigationmode | ||
- | iSteeringangle | ||
- | icurvature | ||
- | iOdopulses= createVariable(' | ||
- | iEnginespeed= createVariable(' | ||
- | iHakostate0= createVariable(' | ||
- | iHakostate1= createVariable(' | ||
- | iHakostate2= createVariable(' | ||
- | iHakostate3= createVariable(' | ||
- | iliftinggearpos= createVariable(' | ||
- | ipowertakeoffspeed= createVariable(' | ||
- | ihornack= createVariable(' | ||
- | iswitchack=createVariable(' | ||
- | icvtack=createVariable(' | ||
- | isteeringack=createVariable(' | ||
- | if (can_dev1){ | ||
- | | ||
- | | ||
- | | ||
- | |||
- | return 1; | ||
- | } | ||
- | |||
- | /** \brief Entry-point for Can-Bus RX Thread | ||
- | * | ||
- | * Responsible for reading and parsing all CAN-Bus messages | ||
- | * | ||
- | */ | ||
- | void *canrx_task(void *not_used){ | ||
- | fprintf(stderr, | ||
- | |||
- | //Lock memory - No more allocations | ||
- | if (mlockall(MCL_CURRENT | MCL_FUTURE)) | ||
- | { | ||
- | perror(" | ||
- | exit(-1); | ||
- | } | ||
- | |||
- | /* use real-time (fixed priority) scheduler | ||
- | * set priority to one less than the maximum | ||
- | */ | ||
- | struct sched_param param; | ||
- | param.sched_priority = sched_get_priority_max(SCHED_RR) - 1; | ||
- | if (sched_setscheduler(0, | ||
- | perror(" | ||
- | pthread_exit(NULL); | ||
- | }; | ||
- | |||
- | if (signal(SIGPIPE, | ||
- | fprintf(stderr, | ||
- | |||
- | //Wait to make sure variables are created | ||
- | while (hakocanRunning < 0) usleep(100000); | ||
- | |||
- | while (hakocanRunning) { | ||
- | int ret, tmp; | ||
- | struct canmsg_t msg; | ||
- | union { | ||
- | short s; | ||
- | char b[2]; | ||
- | }conv; | ||
- | |||
- | //receive one CAN message | ||
- | ret=secureRead(can_dev, | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; //Shutdown! | ||
- | } else { | ||
- | // | ||
- | switch(msg.id) { | ||
- | case 0x105:{ | ||
- | conv.b[0]=msg.data[0]; | ||
- | conv.b[1]=msg.data[1]; | ||
- | // setVariable(iSteeringangle, | ||
- | conv.b[0]=msg.data[2]; | ||
- | conv.b[1]=msg.data[3]; | ||
- | tmp=conv.s; | ||
- | if ((msg.data[7] & | ||
- | tmp=-tmp; | ||
- | setVariable(iOdopulses, | ||
- | // setVariable(iEnginespeed, | ||
- | if (msg.data[6]==' | ||
- | setVariable(iNavigationmode, | ||
- | else | ||
- | setVariable(iNavigationmode, | ||
- | } | ||
- | break; | ||
- | |||
- | case 0x50:{ | ||
- | conv.b[0]=msg.data[0]; | ||
- | conv.b[1]=msg.data[1]; | ||
- | setVariable(iHakostate0, | ||
- | conv.b[0]=msg.data[2]; | ||
- | conv.b[1]=msg.data[3]; | ||
- | setVariable(iHakostate1, | ||
- | conv.b[0]=msg.data[4]; | ||
- | conv.b[1]=msg.data[5]; | ||
- | setVariable(iHakostate2, | ||
- | conv.b[0]=msg.data[6]; | ||
- | conv.b[1]=msg.data[7]; | ||
- | setVariable(iHakostate3, | ||
- | } | ||
- | break; | ||
- | case 0x145:{ | ||
- | setVariable(iliftinggearpos, | ||
- | setVariable(ipowertakeoffspeed, | ||
- | } | ||
- | break; | ||
- | |||
- | default : break; | ||
- | } | ||
- | } | ||
- | } //RX Loop ends | ||
- | |||
- | //Finish thread | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | pthread_exit(NULL); | ||
- | } | ||
- | |||
- | void *canrx_task1(void *not_used){ | ||
- | fprintf(stderr, | ||
- | |||
- | //Lock memory - No more allocations | ||
- | if (mlockall(MCL_CURRENT | MCL_FUTURE)) | ||
- | { | ||
- | perror(" | ||
- | exit(-1); | ||
- | } | ||
- | |||
- | /* use real-time (fixed priority) scheduler | ||
- | * set priority to one less than the maximum | ||
- | */ | ||
- | struct sched_param param; | ||
- | param.sched_priority = sched_get_priority_max(SCHED_RR) - 1; | ||
- | if (sched_setscheduler(0, | ||
- | perror(" | ||
- | pthread_exit(NULL); | ||
- | }; | ||
- | |||
- | if (signal(SIGPIPE, | ||
- | fprintf(stderr, | ||
- | |||
- | //Wait to make sure variables are created | ||
- | while (hakocanRunning < 0) usleep(100000); | ||
- | |||
- | while (hakocanRunning) { | ||
- | int ret; | ||
- | //int tmp; | ||
- | struct canmsg_t msg; | ||
- | union { | ||
- | short s; | ||
- | float f; | ||
- | int i; | ||
- | unsigned char b[4]; | ||
- | }conv; | ||
- | |||
- | //receive one CAN message | ||
- | ret=secureRead(can_dev1, | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; //Shutdown! | ||
- | } else { | ||
- | // | ||
- | switch(msg.id) { | ||
- | case 0x100: | ||
- | conv.b[0]=msg.data[0]; | ||
- | conv.b[1]=msg.data[1]; | ||
- | conv.b[2]=msg.data[2]; | ||
- | conv.b[3]=msg.data[3]; | ||
- | setVariable(iOdopulses1, | ||
- | break; | ||
- | case STEERINGREPORT: | ||
- | conv.b[0]=msg.data[0]; | ||
- | conv.b[1]=msg.data[1]; | ||
- | conv.b[2]=msg.data[2]; | ||
- | conv.b[3]=msg.data[3]; | ||
- | setVariable(icurvature, | ||
- | break; | ||
- | case CVTACK: | ||
- | conv.b[0]=msg.data[0]; | ||
- | conv.b[1]=msg.data[1]; | ||
- | conv.b[2]=msg.data[2]; | ||
- | conv.b[3]=msg.data[3]; | ||
- | setVariable(icvtack, | ||
- | break; | ||
- | | ||
- | case STEERINGACK: | ||
- | conv.b[0]=msg.data[0]; | ||
- | conv.b[1]=msg.data[1]; | ||
- | setVariable(isteeringack, | ||
- | break; | ||
- | | ||
- | case STEERINGANGLEACK: | ||
- | conv.b[0]=msg.data[0]; | ||
- | conv.b[1]=msg.data[1]; | ||
- | setVariable(iSteeringangle, | ||
- | break; | ||
- | |||
- | case 0x730: | ||
- | | ||
- | break; | ||
- | case HORNACK: | ||
- | | ||
- | break; | ||
- | |||
- | |||
- | default : break; | ||
- | } | ||
- | } | ||
- | } //RX Loop ends | ||
- | |||
- | //Finish thread | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | pthread_exit(NULL); | ||
- | } | ||
- | |||
- | |||
- | void setmask( | ||
- | char tmp; | ||
- | | ||
- | if (getWriteVariable(var, | ||
- | | ||
- | | ||
- | | ||
- | } | ||
- | |||
- | |||
- | /** \brief Transmit messages to the CAN bus | ||
- | * | ||
- | * Periodic function to transmit variables and | ||
- | * requests to the can-bus | ||
- | * | ||
- | */ | ||
- | extern int periodic(int tick) | ||
- | { | ||
- | |||
- | //Just return if CAN isn't running | ||
- | if (hakocanRunning < 0) return -1; | ||
- | |||
- | int ret; | ||
- | struct canmsg_t msg; | ||
- | union { | ||
- | short s; | ||
- | char b[2]; | ||
- | }conv; | ||
- | | ||
- | union { | ||
- | float f; | ||
- | int i; | ||
- | char b[4]; | ||
- | }conv1; | ||
- | # | ||
- | | ||
- | msg.id=0x110; | ||
- | msg.flags=0; | ||
- | msg.length=0; | ||
- | msg.data[0]=0x0; | ||
- | msg.data[1]=0x0; | ||
- | | ||
- | ret=secureWrite(can_dev,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | msg.id=0x150; | ||
- | msg.flags=0; | ||
- | msg.length=0; | ||
- | msg.data[0]=0x0; | ||
- | msg.data[1]=0x0; | ||
- | ret=secureWrite(can_dev,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | | ||
- | if (isUpdated(' | ||
- | isUpdated(' | ||
- | conv.s= -getWriteVariable(iSteeringangleref, | ||
- | msg.id=0x100; | ||
- | msg.flags=0; | ||
- | msg.length=8; | ||
- | msg.data[0]=conv.b[0]; | ||
- | msg.data[1]=conv.b[1]; | ||
- | conv.s= getWriteVariable(iSpeedref, | ||
- | msg.data[2]=conv.b[0]; | ||
- | msg.data[3]=conv.b[1]; | ||
- | msg.data[4]=getWriteVariable(iEnginespeedref, | ||
- | msg.data[5]=0; | ||
- | if (getWriteVariable(iNavigationmoderef, | ||
- | msg.data[6]=' | ||
- | else | ||
- | msg.data[6]=' | ||
- | msg.data[7]=0; | ||
- | ret=secureWrite(can_dev,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | if (isUpdated(' | ||
- | msg.id=0x130; | ||
- | msg.flags=0; | ||
- | msg.length=2; | ||
- | msg.data[0]=getWriteVariable(iliftinggearstateref, | ||
- | msg.data[1]=getWriteVariable(ipowertakeoffstateref, | ||
- | ret=secureWrite(can_dev,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | #endif | ||
- | if (can_dev1){ | ||
- | // Ask for encoderdata | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | // Ask for Steeringreport | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | |||
- | | ||
- | | ||
- | msg.id=0x600; | ||
- | msg.flags=0; | ||
- | msg.length=2; | ||
- | |||
- | setmask(& | ||
- | setmask(& | ||
- | setmask(& | ||
- | setmask(& | ||
- | setmask(& | ||
- | setmask(& | ||
- | setmask(& | ||
- | setmask(& | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | if (isUpdated(' | ||
- | msg.id=RPMCMD; | ||
- | msg.flags=0; | ||
- | msg.length=8; | ||
- | conv1.i=(getWriteVariable(iEnginespeedref, | ||
- | // convert to mHz | ||
- | //conv.i = (conv.i * 1000) / 60; | ||
- | msg.data[0]=0xc5; | ||
- | msg.data[1]=0; | ||
- | msg.data[4]=conv1.b[0]; | ||
- | msg.data[5]=conv1.b[1]; | ||
- | msg.data[6]=conv1.b[2]; | ||
- | msg.data[7]=conv1.b[3]; | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | if (isUpdated(' | ||
- | msg.id=CURVATURECMD; | ||
- | msg.flags=0; | ||
- | msg.length=4; | ||
- | conv1.f=getWriteVariable(icurvatureref, | ||
- | msg.data[0]=conv1.b[0]; | ||
- | msg.data[1]=conv1.b[1]; | ||
- | msg.data[2]=conv1.b[2]; | ||
- | msg.data[3]=conv1.b[3]; | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | if (isUpdated(' | ||
- | msg.id=CVTCONTROLCMD; | ||
- | msg.flags=0; | ||
- | msg.length=4; | ||
- | conv1.i=getWriteVariable(iSpeedref, | ||
- | msg.data[0]=conv1.b[0]; | ||
- | msg.data[1]=conv1.b[1]; | ||
- | msg.data[2]=conv1.b[2]; | ||
- | msg.data[3]=conv1.b[3]; | ||
- | msg.data[3]& | ||
- | msg.data[3]|=0xc0; | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | if (isUpdated(' | ||
- | msg.id=STEERINGANGLECMD; | ||
- | msg.flags=0; | ||
- | msg.length=2; | ||
- | conv.s=getWriteVariable(iSteeringangleref, | ||
- | msg.data[0]=conv.b[0]; | ||
- | msg.data[1]=conv.b[1]; | ||
- | | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | | ||
- | if (isUpdated(' | ||
- | msg.id=HITCHCMD; | ||
- | msg.flags=0; | ||
- | msg.length=4; | ||
- | conv1.i=getWriteVariable(ihitchposref, | ||
- | msg.data[0]=conv1.b[0]; | ||
- | msg.data[1]=conv1.b[1]; | ||
- | msg.data[2]=conv1.b[0]; | ||
- | msg.data[3]=conv1.b[1]; | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | |||
- | |||
- | msg.id=HORNCMD; | ||
- | msg.flags=0; | ||
- | msg.length=2; | ||
- | setmask(& | ||
- | ret=secureWrite(can_dev1,& | ||
- | if (ret<0) { | ||
- | fprintf(stderr," | ||
- | hakocanRunning = -1; | ||
- | return -1; | ||
- | } | ||
- | } | ||
- | | ||
- | | ||
- | return 1; | ||
- | } | ||
- | |||
- | / | ||
- | ///Struct for shared parse data | ||
- | typedef struct | ||
- | int depth; | ||
- | char skip; | ||
- | char enable; | ||
- | char found; | ||
- | }parseInfo; | ||
- | |||
- | //Parsing functions | ||
- | void XMLCALL hakocanStartTag(void *, const char *, const char **); | ||
- | void XMLCALL hakocanEndTag(void *, const char *); | ||
- | |||
- | |||
- | /** \brief Initialize the Crossbow HAL | ||
- | * | ||
- | * Reads the XML file and sets up the Crossbow settings | ||
- | | ||
- | * Finally the rx thread is started and the server | ||
- | * is ready to accept connections | ||
- | | ||
- | * \param[in] *char filename | ||
- | * Filename of the XML file | ||
- | | ||
- | * \returns int status | ||
- | * Status of the initialization process. Negative on error. | ||
- | */ | ||
- | extern int initXML(char *filename) { | ||
- | |||
- | parseInfo xmlParse; | ||
- | char *xmlBuf = NULL; | ||
- | int xmlFilelength; | ||
- | int done = 0; | ||
- | int len; | ||
- | FILE *fp; | ||
- | |||
- | //Print initialization message | ||
- | //Find revision number from SVN Revision | ||
- | char *i, | ||
- | i = strrchr(versionString,' | ||
- | strncpy(tempString, | ||
- | tempString[(i-versionString-6)] = 0; | ||
- | printf(" | ||
- | |||
- | |||
- | /* Initialize Expat parser*/ | ||
- | | ||
- | if (! parser) { | ||
- | fprintf(stderr, | ||
- | return -1; | ||
- | } | ||
- | |||
- | // | ||
- | | ||
- | // | ||
- | | ||
- | | ||
- | |||
- | //Open and read the XML file | ||
- | fp = fopen(filename," | ||
- | if(fp == NULL) | ||
- | { | ||
- | printf(" | ||
- | return -1; | ||
- | } | ||
- | //Get the length of the file | ||
- | fseek(fp, | ||
- | xmlFilelength = ftell(fp); //Get position | ||
- | fseek(fp, | ||
- | |||
- | //Allocate text buffer | ||
- | xmlBuf = realloc(xmlBuf, | ||
- | if (xmlBuf == NULL) { | ||
- | fprintf(stderr, | ||
- | return -1; | ||
- | } | ||
- | memset(xmlBuf, | ||
- | len = fread(xmlBuf, | ||
- | fclose(fp); | ||
- | |||
- | //Start parsing the XML file | ||
- | if (XML_Parse(parser, | ||
- | fprintf(stderr, | ||
- | (int)XML_GetCurrentLineNumber(parser), | ||
- | XML_ErrorString(XML_GetErrorCode(parser))); | ||
- | return -1; | ||
- | } | ||
- | XML_ParserFree(parser); | ||
- | free(xmlBuf); | ||
- | |||
- | //Print error, if no XML tag found | ||
- | if (xmlParse.found <= 0) { | ||
- | printf(" | ||
- | return -1; | ||
- | } | ||
- | |||
- | //Start crossbow thread after init | ||
- | if (xmlParse.enable) hakocanRunning = initHakocan(); | ||
- | |||
- | |||
- | | ||
- | } | ||
- | |||
- | ///Handle XML Start tags | ||
- | void XMLCALL | ||
- | hakocanStartTag(void *data, const char *el, const char **attr) | ||
- | { | ||
- | int i; | ||
- | parseInfo *info = (parseInfo *) data; | ||
- | info-> | ||
- | |||
- | //Check for the right 1., 2. and 3. level tags | ||
- | if (!info-> | ||
- | if (((info-> | ||
- | ((info-> | ||
- | | ||
- | info-> | ||
- | return; | ||
- | } else if (info-> | ||
- | } else return; | ||
- | |||
- | //Branch to parse the elements of the XML file. | ||
- | if (!strcmp(" | ||
- | for(i = 0; attr[i]; i+=2) if ((strcmp(" | ||
- | info-> | ||
- | } | ||
- | if (!info-> | ||
- | printf(" | ||
- | info-> | ||
- | } | ||
- | } else if (strcmp(" | ||
- | //Check for the correct depth for this tag | ||
- | if(info-> | ||
- | printf(" | ||
- | } | ||
- | for(i = 0; attr[i]; i+=2) { | ||
- | if (strcmp(" | ||
- | if (strcmp(" | ||
- | } | ||
- | printf(" | ||
- | } | ||
- | |||
- | } | ||
- | |||
- | ///Handle XML End tags | ||
- | void XMLCALL | ||
- | hakocanEndTag(void *data, const char *el) | ||
- | { | ||
- | parseInfo *info = (parseInfo *) data; | ||
- | info-> | ||
- | |||
- | if (info-> | ||
- | } | ||
- | </ | ||
- | <sxh c; title: | ||
- | /** /file canmsg.h | ||
- | * canmsg.h - common kernel-space and user-space CAN message structure | ||
- | * Linux CAN-bus device driver. | ||
- | * Written by Pavel Pisa - OCERA team member | ||
- | * email: | ||
- | * This software is released under the GPL-License. | ||
- | * Version lincan-0.3 | ||
- | */ | ||
- | #ifndef _CANMSG_T_H | ||
- | #define _CANMSG_T_H | ||
- | |||
- | #ifdef __KERNEL__ | ||
- | |||
- | #include < | ||
- | #include < | ||
- | |||
- | #else /* __KERNEL__ */ | ||
- | |||
- | #include < | ||
- | #include < | ||
- | |||
- | #endif /* __KERNEL__ */ | ||
- | |||
- | #ifdef __cplusplus | ||
- | extern " | ||
- | #endif | ||
- | |||
- | /* | ||
- | * CAN_MSG_VERSION_2 enables new canmsg_t layout compatible with | ||
- | * can4linux project from http:// | ||
- | | ||
- | */ | ||
- | #define CAN_MSG_VERSION_2 | ||
- | |||
- | /* Number of data bytes in one CAN message */ | ||
- | #define CAN_MSG_LENGTH 8 | ||
- | |||
- | #ifdef CAN_MSG_VERSION_2 | ||
- | |||
- | typedef struct timeval canmsg_tstamp_t ; | ||
- | |||
- | typedef unsigned long canmsg_id_t; | ||
- | |||
- | /** | ||
- | * struct canmsg_t - structure representing CAN message | ||
- | * @flags: | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | * @cob: communication object number (not used) | ||
- | * @id: ID of CAN message | ||
- | * @timestamp: not used | ||
- | * @length: length of used data | ||
- | * @data: | ||
- | * | ||
- | * Header: canmsg.h | ||
- | */ | ||
- | struct canmsg_t { | ||
- | int | ||
- | int cob; | ||
- | canmsg_id_t | ||
- | canmsg_tstamp_t timestamp; | ||
- | unsigned short length; | ||
- | unsigned char | ||
- | }; | ||
- | |||
- | #else / | ||
- | #ifndef PACKED | ||
- | #define PACKED __attribute__((packed)) | ||
- | #endif | ||
- | /* Old, deprecated version of canmsg_t structure */ | ||
- | struct canmsg_t { | ||
- | short flags; | ||
- | int cob; | ||
- | canmsg_id_t id; | ||
- | unsigned long timestamp; | ||
- | unsigned int length; | ||
- | unsigned char data[CAN_MSG_LENGTH]; | ||
- | } PACKED; | ||
- | #endif / | ||
- | |||
- | typedef struct canmsg_t canmsg_t; | ||
- | |||
- | /** | ||
- | * struct canfilt_t - structure for acceptance filter setup | ||
- | * @flags: | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | * @queid: | ||
- | | ||
- | * @cob: communication object number (not used) | ||
- | * @id: | ||
- | * @mask: | ||
- | | ||
- | * | ||
- | * Header: canmsg.h | ||
- | */ | ||
- | struct canfilt_t { | ||
- | int flags; | ||
- | int queid; | ||
- | int cob; | ||
- | canmsg_id_t id; | ||
- | canmsg_id_t mask; | ||
- | }; | ||
- | |||
- | typedef struct canfilt_t canfilt_t; | ||
- | |||
- | /* Definitions to use for canmsg_t and canfilt_t flags */ | ||
- | #define MSG_RTR | ||
- | #define MSG_OVR | ||
- | #define MSG_EXT | ||
- | #define MSG_LOCAL (1<< | ||
- | /* If you change above lines, check canque_filtid2internal function */ | ||
- | |||
- | /* Additional definitions used for canfilt_t only */ | ||
- | #define MSG_FILT_MASK_SHIFT | ||
- | #define MSG_RTR_MASK | ||
- | #define MSG_EXT_MASK | ||
- | #define MSG_LOCAL_MASK (MSG_LOCAL<< | ||
- | #define MSG_PROCESSLOCAL (MSG_OVR<< | ||
- | |||
- | /* Can message ID mask */ | ||
- | #define MSG_ID_MASK ((1l<< | ||
- | |||
- | #ifdef __cplusplus | ||
- | } /* extern " | ||
- | #endif | ||
- | |||
- | #endif / | ||
- | </ |