main class which provides canopen API functions and manages all nodes. More...
#include <rlcanopen.h>
Public Member Functions | |
| rlCanOpen () | |
| rlCanOpen (char *_inifilename) | |
| ~rlCanOpen () | |
| int | getBoardCount () |
| returns the number of available boards | |
| int | getActiveBoard () |
| returns the number of currently active board | |
| bool | showNodeConfiguration (int _boardnr, int _nodeid) |
| prints out the configuration of a specific node | |
| bool | showNodeConfiguration () |
| prints out the configuration off all available nodes from all boards | |
| int | sdo_read (int _boardnr, int _nodeid, int _objectindex, int _subindex, rlCanOpenTypes &_sdo_data) |
| read a certain object from the object dictionary of a node | |
| int | sdo_write (int _boardnr, int _nodeid, int _objectindex, int _subindex, rlCanOpenTypes &_sdo_data) |
| write data into a certain object from the object dictionary of a node | |
| int | pdo_receive (int _boardnr, int _nodeid, int _pdonr, int _mappingnr, rlCanOpenTypes &_pdo_data) |
| using the pdo_receive function you can receive a mapped object within PDO | |
| int | pdo_receive (int _boardnr, int _nodeid, int _pdonr, rlCanOpenTypes &_pdo_data) |
| using the pdo_receive function you can receive a PDO (Process Data Object) | |
| int | pdo_transmit (int _boardnr, int _nodeid, int _pdonr, int _mappingnr, rlCanOpenTypes &_pdo_data) |
| transmit a mapped object within a PDO to a specific node | |
| int | pdo_transmit (int _boardnr, int _nodeid, int _pdonr, rlCanOpenTypes &_pdo_data) |
| transmit a 8 Byte PDO to a specific node | |
| int | getNodeIndex (int _boardnr, int _nodeid, int &_index) |
| this function returns the listindex of a desired node | |
| int | getObjectType (int _boardnr, int _nodeid, int _objectindex, int _subindex) |
| returns daemontype number of a specific object | |
| int | getNodeState (int _boardnr, int _nodeid, rlCanOpenTypes &_data) |
| use this function to get information about a specific node | |
| int | restartBoard (int _boardnr, int _restarttype) |
| using this function you are able to restart a CanOpenMaster board | |
| int | sendNMTCommand (int _boardnr, int _nodeid, unsigned char _cmd) |
| send a NMT Command to one or all nodes (of one board) | |
| bool | is_twisted_type (int _canopentype) |
Private Member Functions | |
| bool | getNodeConfiguration (int _nodeID) |
| int | getPdoID (int _boardnr, int _nodeid, int _objektindex, int _direction) |
| return PdoId of mapped object. | |
| void | read_inifile (const char *_filename) |
| read properties of inifile | |
| bool | ini () |
| initialize nodes and create nodelist | |
| void | delmsg () |
| clear message struct by setting all elements to zero | |
| bool | iniboards () |
| Read informations about installed devices. | |
| short | setBoardActive (int _boardnr) |
| sets a desired CanOpenMaster active, so that it can be used | |
| int | refreshMappingList (int _boardnr, int _nodeid, int _pdoID, int _pdoDirection) |
| int | createNodes () |
| Search for nodes in all boards and append it into the nodelist. | |
| int | createMappingObjects (int _boardid, int _nodeid, int _pdoDirection) |
| this function writes the mapping objects for each pdo of a node | |
Private Attributes | |
| int | activeboard |
| the currently active board | |
| char | err_out_buf [255] |
| this string buffer is usually written with sprintf before sent to stdout | |
| short | sRet |
| return value for hilscher specific message functions | |
| FILE * | err_fp |
| Pointer to error logfile. | |
| QString | logFileName |
| name of logfile stdout is redirected to | |
| RCS_MESSAGETELEGRAM_10 | message |
| hilscher specific message structur which will be sent to the master card | |
| QPtrVector< rlCanNode > | nodelist |
| this list contains all nodes from all boards | |
| int | boardcount |
| the current count of CanOpenMaster cards | |
| unsigned char | messagenr |
| message counter | |
| bool | enableLogging |
main class which provides canopen API functions and manages all nodes.
This class contains a canopen specific API which accesses the canopen bus through the bus-independ Hilscher device API. It reads the configuration which has to be written previously to the device by SyCon. Based on this configuration data it searches node corresponding EDS files to create object directories. These help to enshure type security and cast warnings when users try to write incorrect data types to can nodes.
Definition at line 55 of file rlcanopen.h.
| rlCanOpen::rlCanOpen | ( | ) |
Definition at line 40 of file rlcanopen.cpp.
00041 { 00042 rlDebugPrintf("Constructer nodes class\n"); 00043 read_inifile("./canopen.ini"); 00044 if (enableLogging){ 00045 FILE* fp; 00046 fp = freopen (logFileName.ascii(),"w",stdout); // redirekt stdout to textfile 00047 00048 /* enable linebuffering in order to write every line to the file immediately */ 00049 setvbuf ( fp , NULL , _IOFBF , 1024 ); 00050 } 00051 ini(); 00052 }
| rlCanOpen::rlCanOpen | ( | char * | _inifilename | ) |
Definition at line 29 of file rlcanopen.cpp.
00030 { 00031 rlDebugPrintf("Constructer nodes class\n"); 00032 read_inifile(_inifilename); 00033 if (enableLogging){ 00034 freopen (logFileName.ascii(),"w",stdout); // redirekt stdout to textfile 00035 } 00036 ini(); 00037 }
| rlCanOpen::~rlCanOpen | ( | ) |
Definition at line 54 of file rlcanopen.cpp.
00055 { 00056 rlDebugPrintf("destruktor rlCanOpen\n"); 00057 for (int i=0;i<boardcount;i++) 00058 DevExitBoard(i); 00059 00060 #ifdef RLWIN32 00061 DevCloseDriver(0); 00062 #else 00063 DevCloseDriver(); 00064 #endif 00065 if (enableLogging) 00066 fclose (stdout); 00067 00068 }
| int rlCanOpen::createMappingObjects | ( | int | _boardid, | |
| int | _nodeid, | |||
| int | _pdoDirection | |||
| ) | [private] |
this function writes the mapping objects for each pdo of a node
creates the mappings for each pdo
Definition at line 137 of file rlcanopen.cpp.
00138 { 00139 int pdomax = 0; 00140 if (_pdoDirection == DIRECTION_RECEIVE) 00141 pdomax = nodelist[nodelist.size()-1]->getReceivePdoCount(); 00142 else if(_pdoDirection == DIRECTION_TRANSMIT) 00143 pdomax = nodelist[nodelist.size()-1]->getTransmitPdoCount(); 00144 00145 for (int j = 1;j<=pdomax;j++) //each receive/transmit pdo 00146 if(refreshMappingList(_boardid,_nodeid,j,_pdoDirection)==0) return 0; 00147 return 1; 00148 00149 }
| int rlCanOpen::createNodes | ( | ) | [private] |
Search for nodes in all boards and append it into the nodelist.
this function checks the bus for available nodes and creates a corresponding nodelist
Definition at line 103 of file rlcanopen.cpp.
00104 { 00105 int nodeid; 00106 for (int boardid = 0;boardid<boardcount;boardid++) 00107 { 00108 setBoardActive(boardid); 00109 for(nodeid = 0; nodeid <= MAX_NODES; nodeid++) // from node 0..127 00110 if (getNodeConfiguration(nodeid)) // writes received node-configuration 00111 // into class-global message-struct 00112 { 00113 // new node found. insert it into the nodelist 00114 nodelist.resize( nodelist.size() + 1 ); 00115 00116 // append the new node in the list 00117 nodelist.insert( nodelist.size()-1, 00118 new rlCanNode(boardid,nodeid,message)); 00119 00120 //append Mapping data 00121 if (nodelist[nodelist.size()-1]->hasMapping()){ 00122 if(!createMappingObjects(boardid,nodeid,DIRECTION_TRANSMIT))return 0; 00123 if(!createMappingObjects(boardid,nodeid,DIRECTION_RECEIVE))return 0; 00124 } 00125 else 00126 { 00127 rlDebugPrintf("WARNING: no Mapping available on node %d.", nodeid); 00128 rlDebugPrintf("Probably EDS file couldn't be found in EDS directory.\n"); 00129 } 00130 } 00131 } 00132 return 1; 00133 }
| void rlCanOpen::delmsg | ( | ) | [private] |
clear message struct by setting all elements to zero
this function resets all elements of global message struct to zero
Definition at line 859 of file rlcanopen.cpp.
00859 { 00860 message.rx =0; 00861 message.tx =0; 00862 message.ln =0; 00863 message.nr =0; 00864 message.a =0; 00865 message.f =0; 00866 message.b =0; 00867 message.e =0; 00868 message.device_adr =0; 00869 message.data_area =0; 00870 message.data_adr =0; 00871 message.data_idx =0; 00872 message.data_cnt =0; 00873 message.data_type =0; 00874 message.function =0; 00875 00876 for (int i = 0; i < MAX_SDO_BUFFERSIZE; i++) 00877 message.d[i] = 0; 00878 00879 }
| int rlCanOpen::getActiveBoard | ( | ) |
returns the number of currently active board
returns the currently active board
Definition at line 296 of file rlcanopen.cpp.
00297 { 00298 return activeboard; 00299 }
| int rlCanOpen::getBoardCount | ( | ) |
returns the number of available boards
returns the current count of available CanOpenMaster cards
Definition at line 211 of file rlcanopen.cpp.
00212 { 00213 return boardcount; 00214 }
| bool rlCanOpen::getNodeConfiguration | ( | int | _nodeID | ) | [private] |
This function reads out the configuration of a specific node using special Hilscher commands (CMDCODE_GET_CONFIGURATION). If the master board isn't configurated by SyCon it is not possibly to use this function with success. It returns false if the node is not available
Device Number
Pointer to user buffer
Timeout
Definition at line 217 of file rlcanopen.cpp.
00218 { 00219 //build message 00220 message.rx = CAN_TASK; 00221 message.tx = USER_AT_HOST; 00222 message.ln = 8; 00223 message.nr =messagenr++; 00224 message.a =0; 00225 message.f =0; 00226 message.b =CMDCODE_GET_CONFIGURATION; 00227 message.e =0x00; //fragmentation 00228 message.device_adr =_nodeID; 00229 message.data_area =0; 00230 message.data_adr =0; 00231 message.data_idx =0; 00232 message.data_cnt =0; 00233 message.data_type =0; 00234 message.function =0; 00235 00236 //put configuration request 00237 DevPutMessage(0, (MSG_STRUC *)&message,5000L) ; 00238 00239 //receive answer message 00240 sRet = DevGetMessage ( 0, 00241 sizeof(message), 00242 (MSG_STRUC *)&message, 00243 2000L ); 00244 00245 unsigned char msgnrlocal = messagenr -1; 00246 00247 // receive correct answer 00248 if((message.a == RESPONSE_CODE_GET_CONFIGURATION) && (message.nr == msgnrlocal)) 00249 if (message.f == ERRCODE_NOERROR) // node active, no error 00250 if(message.e == 0x00) //configuration fits in the message 00251 { 00252 sprintf(err_out_buf, "Board %d node %d is active. No problems found\n", 00253 getActiveBoard(), _nodeID); 00254 00255 rlDebugPrintf(err_out_buf); 00256 return 1; 00257 } 00258 else 00259 { 00260 sprintf(err_out_buf, "Board %d node %d is active. \n", 00261 getActiveBoard(), _nodeID); 00262 00263 rlDebugPrintf(err_out_buf); 00264 rlDebugPrintf("Configuration data does not fit in one message,\n"); 00265 rlDebugPrintf("so the current node does not include the complete data\n"); 00266 rlDebugPrintf(" - multiplex configration data is not yet implemented!!! -\n"); 00267 return 1; 00268 } 00269 else return 0; 00270 else 00271 { 00272 sprintf(err_out_buf, "---->message.a=%d, message.nr=%d unsere msg nr: %d\n", 00273 message.a, message.nr, msgnrlocal); 00274 00275 rlDebugPrintf(err_out_buf); 00276 sprintf(err_out_buf, "%s\n", "Communication ERROR!!!"); 00277 rlDebugPrintf(err_out_buf); 00278 return 0; 00279 } 00280 }
| int rlCanOpen::getNodeIndex | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int & | _index | |||
| ) |
this function returns the listindex of a desired node
Because the nodes of all boards are stored in one list, the listindex is not equal to the nodeID(1-127). Use this function to get the listindex of a desired node
Definition at line 882 of file rlcanopen.cpp.
| int rlCanOpen::getNodeState | ( | int | _boardnr, | |
| int | _nodeid, | |||
| rlCanOpenTypes & | _data | |||
| ) |
use this function to get information about a specific node
Use this function to get information about a specific node. The nodestate, nodeerror and a nodestateFlag will be written to the rlCanOpenTypes. Read the rlCanOpenTypes.h header to get further information about these variables. Hilscher specific function (so no CanOpoen services) are used to receive the information
Definition at line 1045 of file rlcanopen.cpp.
01046 { 01047 01048 setBoardActive(_boardnr); 01049 01050 COM_ND_DIAGNOSTICS * diag; 01051 diag = (COM_ND_DIAGNOSTICS*) &message.d[0]; 01052 01053 message.rx = CAN_TASK ;//receiver = user at HOST 01054 message.tx = USER_AT_HOST ;// transmitter = USR_INTF-Task 01055 message.ln = 8 ;//length of message 01056 message.nr = messagenr++ ;//number of the message 01057 message.a = 0 ;//no answer 01058 message.f = 0 ;//error, status 01059 message.b = CMDCODE_Node_Diag;//command = COM_Node_Diag 01060 message.e =0 ;//extension 01061 message.device_adr = _nodeid ;//k Rem_Adr 01062 message.data_area = 0 ;// data area, unused 01063 message.data_adr = 0 ;//data address, unused 01064 message.data_idx = 0 ;//data index, unused 01065 message.data_cnt = 0 ;//data count, unused 01066 message.data_type = 5 ;// data type byte string 01067 message.function = 1 ;//function read 01068 01069 01070 if ( (sRet = DevPutMessage(_boardnr, (MSG_STRUC *)&message, 5000L)) 01071 == DRV_NO_ERROR ) 01072 { 01073 while( (sRet = DevGetMessage(_boardnr, sizeof(message), 01074 (MSG_STRUC *)&message, 0)) 01075 == DRV_DEV_GET_NO_MESSAGE ) 01076 { 01077 continue; 01078 } 01079 if ( sRet == DRV_NO_ERROR ) 01080 { 01081 rlDebugPrintf("message successfully received\n"); 01082 // continue; 01083 } 01084 else 01085 { 01086 rlDebugPrintf("Error Message (f = %d))\n",message.f); 01087 rlDebugPrintf("\nDevGetMessage(%d, sizeof(message), &message, 500): %d\n", 01088 _boardnr, (int)sRet); 01089 01090 return 0; 01091 } 01092 } 01093 else 01094 { 01095 rlDebugPrintf("\nDevPutMessage(%d, &message, 5000): %d\n",_boardnr, (int)sRet); 01096 return 0; 01097 } 01098 _data.set_nodestateFlags( diag->bNodeStatus_1.bNodeNoResponse, 01099 diag->bNodeStatus_1.bEmcyBuffOverflow, 01100 diag->bNodeStatus_1.bPrmFault, 01101 diag->bNodeStatus_1.bGuardActive, 01102 diag->bNodeStatus_1.bDeactivated ); 01103 01104 _data.set_nodestate(diag->bNodeState); 01105 _data.set_nodeerror(diag->bActualError); 01106 01107 _data.set_DaemonType(rlCanOpenTypes::RL_NODESTATE); 01108 01109 return 1; 01110 }
| int rlCanOpen::getObjectType | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _objectindex, | |||
| int | _subindex | |||
| ) |
returns daemontype number of a specific object
returns daemontype number of an object. The type is retrieved from the node's objectdir. When no objectdir exists (e.g. because of a missing EDS file) or when the requested object does not exist, this function will return 0xFF (the corresponding value to rlCanOpenTypes::RL_NOTYPE)
Definition at line 897 of file rlcanopen.cpp.
00901 { 00902 int nodeindex; 00903 if (getNodeIndex(_boardnr, _nodeid, nodeindex)){ 00904 if (nodelist[nodeindex]->hasMapping()) 00905 return nodelist[nodeindex]->objecttype(_objectindex, _subindex); 00906 else 00907 return rlCanOpenTypes::RL_BUFFER; 00908 } 00909 else{ 00910 return rlCanOpenTypes::RL_NOTYPE; 00911 } 00912 }
| int rlCanOpen::getPdoID | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _objektindex, | |||
| int | _direction | |||
| ) | [private] |
return PdoId of mapped object.
this function iterates through the recieve/tramsmit pdo lists and returns the ID number of the pdo that fits the given objektindex. The PdoId identifies the send/receive PDO on the given node
Definition at line 1015 of file rlcanopen.cpp.
01018 { 01019 int pdomax=0; 01020 int nodeindex=0; 01021 int madress=0; 01022 // get index of node in nodelist depending on boardid and nodeid 01023 // index is stored in nodeindex variable 01024 getNodeIndex(_boardnr, _nodeid, nodeindex); 01025 01026 // get number of elements in particular PDO list 01027 if (_direction == DIRECTION_RECEIVE) 01028 pdomax = nodelist[nodeindex]->getReceivePdoCount(); 01029 if (_direction == DIRECTION_TRANSMIT) 01030 pdomax = nodelist[nodeindex]->getTransmitPdoCount(); 01031 01032 /* iterate through every element of particular list until mapping 01033 object adress matches given objectindex */ 01034 for (int j=1;j<=pdomax;j++) 01035 { 01036 01037 madress = nodelist[nodeindex]->pdoList[_direction][j-1]->mappingOvAdress; 01038 if (madress == _objektindex) 01039 return j; 01040 } 01041 return 0; 01042 }
| bool rlCanOpen::ini | ( | ) | [private] |
initialize nodes and create nodelist
Definition at line 71 of file rlcanopen.cpp.
00072 { 00073 messagenr = 0; 00074 nodelist.setAutoDelete(true); 00075 00076 time_t rawtime; 00077 struct tm * timeinfo; 00078 time ( &rawtime ); 00079 timeinfo = localtime ( &rawtime ); 00080 00081 sprintf(err_out_buf, "\nnew session startet: %s\n", asctime(timeinfo)); 00082 rlDebugPrintf(err_out_buf); 00083 00084 if (iniboards()){ 00085 rlDebugPrintf("at least one board initialize!\n"); 00086 } 00087 else 00088 { 00089 rlDebugPrintf("no board available or no board could be initialized correctly!\n"); 00090 rlDebugPrintf("Programm -> Close\n"); 00091 exit(0); 00092 } 00093 00094 // search for active nodes and create them 00095 00096 createNodes(); 00097 00098 00099 return 1; 00100 }
| bool rlCanOpen::iniboards | ( | ) | [private] |
Read informations about installed devices.
Definition at line 154 of file rlcanopen.cpp.
00155 { 00156 00157 int currentboardcount=0; 00158 00159 BOARD_INFO tBoardInfo; 00160 00161 #ifdef RLWIN32 00162 if ( (sRet = DevOpenDriver(0)) == DRV_NO_ERROR) 00163 #else 00164 if ( (sRet = DevOpenDriver()) == DRV_NO_ERROR) 00165 #endif 00166 { 00167 // Driver successfully opend, read board information 00168 #ifdef RLWIN32 00169 if ( (sRet = DevGetBoardInfo( 0, sizeof(tBoardInfo), &tBoardInfo)) != DRV_NO_ERROR) 00170 #else 00171 if ( (sRet = DevGetBoardInfo( &tBoardInfo)) != DRV_NO_ERROR) 00172 #endif 00173 { 00174 // Function error 00175 rlDebugPrintf( "DevGetBoardInfo RetWert = %5d \n", sRet ); 00176 } else 00177 { 00178 // Information successfully read, save for further use 00179 // Check out which boards are available 00180 for ( int usIdx = 0; usIdx < MAX_DEV_BOARDS; usIdx++) 00181 { 00182 if ( tBoardInfo.tBoard[usIdx].usAvailable == TRUE) { 00183 // Board is configured, try to init the board 00184 sRet = DevInitBoard( 00185 #ifdef RLWIN32 00186 tBoardInfo.tBoard[usIdx].usBoardNumber, NULL); 00187 #else 00188 tBoardInfo.tBoard[usIdx].usBoard); 00189 #endif 00190 if ( sRet != DRV_NO_ERROR) { 00191 // Function error 00192 rlDebugPrintf( "DevInitBoard RetWert = %5d \n", sRet ); 00193 } else { 00194 // DEVICE is available and ready............ 00195 currentboardcount++; 00196 } 00197 } 00198 } 00199 } 00200 } 00201 boardcount = currentboardcount; 00202 00203 if (currentboardcount!=0) 00204 return 1; 00205 else 00206 return 0; 00207 }
| bool rlCanOpen::is_twisted_type | ( | int | _canopentype | ) |
Definition at line 1226 of file rlcanopen.cpp.
01227 { 01228 switch (_canopentype){ 01229 01230 case rlCanOpenTypes::INTEGER24_t :return true; 01231 case rlCanOpenTypes::INTEGER40_t :return true; 01232 case rlCanOpenTypes::INTEGER48_t :return true; 01233 case rlCanOpenTypes::INTEGER56_t :return true; 01234 case rlCanOpenTypes::UNSIGNED24_t:return true; 01235 case rlCanOpenTypes::UNSIGNED40_t:return true; 01236 case rlCanOpenTypes::UNSIGNED48_t:return true; 01237 case rlCanOpenTypes::UNSIGNED56_t:return true; 01238 default :return false; 01239 }; 01240 01241 }
| int rlCanOpen::pdo_receive | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _pdonr, | |||
| rlCanOpenTypes & | _pdo_data | |||
| ) |
using the pdo_receive function you can receive a PDO (Process Data Object)
using the pdo_receive function you can receive a PDO (Process Data Object), which is send from the specific node to the canOpen master card. The data will be written to the rlCanOpenTypes class. This function doesn't use mapping. So the whole 8Byte PDO data, will be received. To read out use the rlCanOpenTypes::get_buffer({0-7}) function
Definition at line 637 of file rlcanopen.cpp.
00641 { 00642 00643 int nodeindex; 00644 if (getNodeIndex(_boardnr,_nodeid,nodeindex)== 0) 00645 { 00646 sprintf(err_out_buf, "ERROR: specified node does not exist! PDO \ 00647 receive failed! BoardId: %d NodeId: %d PDO \ 00648 ID: %d\n", _boardnr, _nodeid, _pdonr); 00649 rlDebugPrintf(err_out_buf); 00650 00651 //cout<<"ERROR: specified node does not exist!\n"; 00652 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_NODEID); 00653 return 0; 00654 } 00655 00656 if (nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT].size() < (unsigned int) _pdonr){ 00657 sprintf(err_out_buf, "ERROR: specified PDO ID does not exist! \ 00658 PDO receive failed! BoardId: %d NodeId: \ 00659 %d PDO ID: %d\n", _boardnr, _nodeid, _pdonr); 00660 rlDebugPrintf(err_out_buf); 00661 00662 //cout<<"PDO ID does not exists!\n"; 00663 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_PDOID); 00664 return 0; 00665 } 00666 00667 int pdosize = nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT][_pdonr-1]->bPDOSize; 00668 00669 int pdooffset = nodelist[nodeindex]-> 00670 pdoList[DIRECTION_TRANSMIT][_pdonr-1]->usPDOAddress; 00671 00672 //cout<<"\nsize ="<<pdosize<<" offset = "<<pdooffset; 00673 00674 if ( (sRet = DevExchangeIO( _boardnr, // Board NO 00675 0, //offset send data 00676 0, //Length of the send IO data 00677 NULL, //Pointer to the user send data buffer 00678 pdooffset, //Byte offset in the receive IO data area 00679 pdosize, //Length of the receive IO data 00680 &_pdo_data.pdobuffer[0],//Pointer to the user read data buffer 00681 100L) //timeout in milliseconds 00682 ) == DRV_NO_ERROR) 00683 { 00684 _pdo_data.pdobuf2buf(); 00685 //rlDebugPrintf("PDO recieve successfull!\n"); 00686 _pdo_data.set_rlmsgerr(ERRCODE_NOERROR); 00687 return 1; 00688 00689 } 00690 sprintf(err_out_buf, "ERROR: PDO receive failed! \ 00691 BoardId: %d NodeId: %d PDO \ 00692 ID: %d\n", _boardnr, _nodeid, _pdonr); 00693 rlDebugPrintf(err_out_buf); 00694 00695 //rlDebugPrintf("ERROR: PDO RECEIVE FAILED\n"); 00696 _pdo_data.set_rlmsgerr(ERRCODE_PDORCV_FAIL); 00697 return 0; 00698 }
| int rlCanOpen::pdo_receive | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _pdonr, | |||
| int | _mappingnr, | |||
| rlCanOpenTypes & | _pdo_data | |||
| ) |
using the pdo_receive function you can receive a mapped object within PDO
using the pdo_receive function you can receive a PDO (Process Data Object), which is send from the specific node to the device. The enquired object will be written to the rlCanOpenTypes class. The mapping is only available if mapping is configurated during the node creation of the rlcanopen constructer. Therefore a eds file (electronic data sheet) is needed. Use the cannode::hasMapping() function to check if mapping is available. To read out the correct value from this class use one of the get_TYPE() {e.g. get_int() } functions you can assert the type in the class using rlCanOpenTypes::get_DaemonType();
Definition at line 544 of file rlcanopen.cpp.
00549 { 00550 00551 int nodeindex; 00552 unsigned char buffer[8]; 00553 00554 if (getNodeIndex(_boardnr,_nodeid,nodeindex)== 0) 00555 { 00556 rlDebugPrintf("ERROR: specified node does not exist! PDO receive failed!"); 00557 rlDebugPrintf("BoardId: %d NodeId: %d PDO ID: %d Mappingnr: %d\n", 00558 _boardnr, _nodeid, _pdonr, _mappingnr); 00559 00560 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_NODEID); 00561 return 0; 00562 } 00563 if (nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT].size() < (unsigned int) _pdonr){ 00564 rlDebugPrintf("ERROR: specified PDO ID does not exist! PDO receive failed!"); 00565 rlDebugPrintf("BoardId: %d NodeId: %d PDO ID: %d Mappingnr: %d\n", 00566 _boardnr, _nodeid, _pdonr, _mappingnr); 00567 00568 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_PDOID); 00569 return 0; 00570 } 00571 else if (nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT][_pdonr -1]->mappingList.size() 00572 < (unsigned int) _mappingnr){ 00573 rlDebugPrintf("ERROR: specified Mappingnr does not exist! PDO receive failed!"); 00574 rlDebugPrintf("BoardId: %d NodeId: %d PDO ID: %d Mappingnr: %d\n", 00575 _boardnr, _nodeid, _pdonr, _mappingnr); 00576 00577 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_MAPID); 00578 return 0; 00579 } 00580 00581 // PDO No.1 has the index 0 !!! 00582 int pdosize = nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT][_pdonr-1]->bPDOSize; 00583 int pdooffset = nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT][_pdonr-1]->usPDOAddress; 00584 00585 //cout<<"size ="<<pdosize<<" offset = "<<pdooffset<<"\n"; 00586 00587 if ( (sRet = DevExchangeIO( _boardnr, // Board NO 00588 0, //offset send data 00589 0, //Length of the send IO data 00590 NULL, //Pointer to the user send data buffer 00591 pdooffset, //Byte offset in the receive IO data area 00592 pdosize, //Length of the receive IO data 00593 &buffer[0], //Pointer to the user read data buffer 00594 100L) //timeout in milliseconds 00595 ) == DRV_NO_ERROR) 00596 { 00597 00598 int length_in_byte = nodelist[nodeindex]-> 00599 pdoList[DIRECTION_TRANSMIT][_pdonr-1]->mappingList[_mappingnr-1]->length/8; 00600 00601 int position_in_byte = nodelist[nodeindex]-> 00602 pdoList[DIRECTION_TRANSMIT][_pdonr-1]->mappingList[_mappingnr-1]->position/8; 00603 00604 _pdo_data.clearBuffer(); 00605 00606 for(int i = position_in_byte; i< length_in_byte+position_in_byte;i++) 00607 { 00608 _pdo_data.set_buffer(i-position_in_byte,buffer[i]); 00609 } 00610 00611 _pdo_data.set_DaemonType( nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT][_pdonr-1]-> 00612 mappingList[_mappingnr-1]->etype); 00613 00614 00615 _pdo_data.set_rlmsgerr(ERRCODE_NOERROR); 00616 00617 00618 // if CanOpen-Type is a twistet integer (etc. 52Bit ) the value will be converted 00619 int canopentype = nodelist[nodeindex]->pdoList[DIRECTION_TRANSMIT][_pdonr-1]-> 00620 mappingList[_mappingnr-1]->canopentype; 00621 00622 if (is_twisted_type(canopentype)) 00623 _pdo_data.translate_CanOpenType(canopentype); 00624 00625 return 1; 00626 } 00627 rlDebugPrintf("ERROR: PDO receive failed!"); 00628 rlDebugPrintf("BoardId: %d NodeId: %d PDO ID: %d Mappingnr: %d\n", 00629 _boardnr, _nodeid, _pdonr, _mappingnr); 00630 00631 _pdo_data.set_rlmsgerr(ERRCODE_PDORCV_FAIL); 00632 00633 return 0; 00634 }
| int rlCanOpen::pdo_transmit | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _pdonr, | |||
| rlCanOpenTypes & | _pdo_data | |||
| ) |
transmit a 8 Byte PDO to a specific node
Using the pdo_transmit function you can transmit a PDO (Process Data Object) to a specific node. The desired data must be written to the rlCanOpenTypes class. This function does not support mapping. So the whole 8byte PDO data, will be send to write to the rlCanOpenTypes use the rlCanOpenTypes::set_buffer({0-7}) function
Definition at line 806 of file rlcanopen.cpp.
00810 { 00811 int nodeindex; 00812 _pdo_data.buf2pdobuf(); 00813 00814 if (getNodeIndex(_boardnr,_nodeid,nodeindex)== 0) 00815 { 00816 sprintf(err_out_buf, "ERROR: specified node does not exist! PDO transmit\ 00817 failed! BoardId: %d NodeId: %d PDO ID: %d \n", 00818 _boardnr, _nodeid, _pdonr); 00819 00820 rlDebugPrintf(err_out_buf); 00821 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_NODEID); 00822 return 0; 00823 } 00824 if (nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE].size() < (unsigned int) _pdonr){ 00825 sprintf(err_out_buf, "ERROR: specified PDO ID does not exist! PDO \ 00826 transmit failed! BoardId: %d NodeId: %d PDO \ 00827 ID: %d \n", _boardnr, _nodeid, _pdonr); 00828 rlDebugPrintf(err_out_buf); 00829 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_PDOID); 00830 return 0; 00831 } 00832 00833 int pdosize = nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr-1]->bPDOSize; 00834 int pdooffset = nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr-1]->usPDOAddress; 00835 00836 if ( (sRet = DevExchangeIO( _boardnr, // Board NO 00837 pdooffset, //offset send data 00838 pdosize, //Length of the send IO data 00839 &_pdo_data.pdobuffer[0],//Pointer to the user send data buffer 00840 0, //Byte offset in the receive IO data area 00841 0, //Length of the receive IO data 00842 NULL, //Pointer to the user read data buffer 00843 100L) //timeout in milliseconds 00844 ) == DRV_NO_ERROR) 00845 { 00846 _pdo_data.set_rlmsgerr(ERRCODE_NOERROR); 00847 return 1; 00848 } 00849 sprintf(err_out_buf, "ERROR: PDO transmit failed! BoardId: %d NodeId: %d \ 00850 PDO ID: %d \n", _boardnr, _nodeid, _pdonr); 00851 rlDebugPrintf(err_out_buf); 00852 00853 _pdo_data.set_rlmsgerr(ERRCODE_PDOSND_FAIL); 00854 return 0; 00855 }
| int rlCanOpen::pdo_transmit | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _pdonr, | |||
| int | _mappingnr, | |||
| rlCanOpenTypes & | _pdo_data | |||
| ) |
transmit a mapped object within a PDO to a specific node
Using the pdo_transmit function you can transmit a PDO (Process Data Object) to a specific node. The desired data must be written to the rlCanOpenTypes class. The mapping is only available if mapping is configurated during the node creation of the rlcanopen constructer. Therefore an eds file (electronic data sheet) is needed. Use the cannode::hasMapping() function to check if mapping is available
Definition at line 703 of file rlcanopen.cpp.
00708 { 00709 int nodeindex; 00710 if (getNodeIndex(_boardnr,_nodeid,nodeindex)== 0) 00711 { 00712 sprintf(err_out_buf, "ERROR: specified node does not exist! PDO transmit \ 00713 failed! BoardId: %d NodeId: %d PDO ID: %d Mappingnr:\ 00714 %d\n", _boardnr, _nodeid, _pdonr, _mappingnr); 00715 rlDebugPrintf(err_out_buf); 00716 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_NODEID); 00717 return 0; 00718 } 00719 if (nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE].size() < (unsigned int) _pdonr){ 00720 sprintf(err_out_buf, "ERROR: specified PDO ID does not exist! PDO transmit\ 00721 failed! BoardId: %d NodeId: %d PDO ID: %d Mappingnr:\ 00722 %d\n", _boardnr, _nodeid, _pdonr, _mappingnr); 00723 rlDebugPrintf(err_out_buf); 00724 00725 //cout<<"PDO ID does not exists!\n"; 00726 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_PDOID); 00727 return 0; 00728 } 00729 else if (nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr -1]->mappingList.size() 00730 < (unsigned int) _mappingnr){ 00731 sprintf(err_out_buf, "ERROR: specified mappingnr does not exist! PDO \ 00732 transmit failed! BoardId: %d NodeId: %d PDO \ 00733 ID: %d Mappingnr: %d\n", 00734 _boardnr, _nodeid, _pdonr, _mappingnr); 00735 rlDebugPrintf(err_out_buf); 00736 00737 //cout<<"mapping ID does not exists!\n"; 00738 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_MAPID); 00739 return 0; 00740 } 00741 00742 // PDO No.1 has the index 0 !!! 00743 int pdosize = nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr-1]->bPDOSize; 00744 int pdooffset = nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr-1]->usPDOAddress; 00745 00746 int length_in_byte = nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr-1]-> 00747 mappingList[_mappingnr-1]->length/8; 00748 00749 int position_in_byte = nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr-1]-> 00750 mappingList[_mappingnr-1]->position/8; 00751 00752 if (_pdo_data.get_DaemonType() != (nodelist[nodeindex]-> 00753 pdoList[DIRECTION_RECEIVE][_pdonr-1]->mappingList[_mappingnr-1]->etype)) 00754 { 00755 00756 sprintf(err_out_buf, "ERROR: invalid type! Expected type: %d Your Type:\ 00757 %d! PDO transmit failed! BoardId: %d NodeId: %d \ 00758 PDO ID: %d Mappingnr: %d\n", 00759 nodelist[nodeindex]->pdoList[DIRECTION_RECEIVE][_pdonr-1]-> 00760 mappingList[_mappingnr-1]->etype, 00761 _pdo_data.get_DaemonType(), _boardnr, _nodeid, _pdonr, _mappingnr); 00762 00763 00764 rlDebugPrintf(err_out_buf); 00765 _pdo_data.get_DaemonType(); 00766 _pdo_data.set_rlmsgerr(ERRCODE_INVALID_RLTYPE); 00767 return 0; 00768 } 00769 00770 _pdo_data.buf2pdobuf(); 00771 00772 // no conversion necessary. correct length in mapping list 00773 00774 pdooffset = pdooffset + position_in_byte; 00775 pdosize = length_in_byte; 00776 00777 00778 00779 //cout<<"size ="<<pdosize<<" offset = "<<pdooffset<<"\n"; 00780 00781 if ( (sRet = DevExchangeIO( _boardnr, // Board NO 00782 pdooffset, //offset send data 00783 pdosize, //Length of the send IO data 00784 &_pdo_data.pdobuffer[0],//Pointer to the user send data buffer 00785 0, //Byte offset in the receive IO data area 00786 0, //Length of the receive IO data 00787 NULL, //Pointer to the user read data buffer 00788 100L) //timeout in milliseconds 00789 ) == DRV_NO_ERROR) 00790 { 00791 _pdo_data.set_rlmsgerr(0); 00792 //rlDebugPrintf("PDO transmit successful! \n"); 00793 return 1; 00794 } 00795 sprintf(err_out_buf, "ERROR: PDO transmit failed! BoardId: %d NodeId: %d \ 00796 PDO ID: %d Mappingnr: %d\n", 00797 _boardnr, _nodeid, _pdonr, _mappingnr); 00798 rlDebugPrintf(err_out_buf); 00799 00800 _pdo_data.set_rlmsgerr(ERRCODE_PDOSND_FAIL); 00801 return 0; 00802 }
| void rlCanOpen::read_inifile | ( | const char * | _filename | ) | [private] |
read properties of inifile
read properties of inifile. EDS path, logfile location and user-specific options are set on startup
Definition at line 1189 of file rlcanopen.cpp.
01189 { 01190 rlIniFile ini; 01191 QString buffer; 01192 if (ini.read(_filename)!=-1){ 01193 rlDebugPrintf("used inifile: %s\n", _filename); 01194 01195 // read EDS directory location 01196 buffer=QString(ini.text("DIRECTORIES","EdsDir")); 01197 buffer.remove((char) ACSII_CODE_CARRIAGE_RETURN); 01198 rlDebugPrintf("EdsDir: %s\n", buffer.ascii()); 01199 // store EDS directory location in environmet variable 01200 #ifdef RLWIN32 01201 SetEnvironmentVariable("EdsDir", buffer.ascii()); 01202 #else 01203 setenv("EdsDir", buffer.ascii(), 1); 01204 #endif 01205 01206 // read Logfilename 01207 logFileName=QString(ini.text("DIRECTORIES","LogFileName")); 01208 logFileName.remove((char) ACSII_CODE_CARRIAGE_RETURN); 01209 rlDebugPrintf("Log Filename: %s\n", logFileName.ascii()); 01210 01211 // read loggin-option 01212 buffer=QString(ini.text("OPTIONS","enableLoggin")); 01213 if (buffer.contains("yes", false)==1) 01214 enableLogging=true; 01215 else 01216 enableLogging=false; 01217 } 01218 else 01219 { 01220 logFileName= "./outfile.txt"; 01221 rlDebugPrintf("ERROR: INIFILE NOT FOUND\n"); 01222 } 01223 }
| int rlCanOpen::refreshMappingList | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _pdoID, | |||
| int | _pdoDirection | |||
| ) | [private] |
if the user changes the mapping of a node using SDO functions, the internal mapping list should be changed
Definition at line 917 of file rlcanopen.cpp.
00921 { 00922 //rlDebugPrintf("refresh mappinglist1\n"); 00923 int nodeindex; 00924 int madress=0; 00925 00926 00927 madress = nodelist[nodelist.size()-1]-> 00928 pdoList[_pdoDirection][_pdoID -1]->mappingOvAdress; 00929 00930 if (getNodeIndex(_boardnr,_nodeid,nodeindex)== false) 00931 { 00932 sprintf(err_out_buf, "ERROR: specified node does not exist! refresh \ 00933 mapping list failed! BoardId: %d NodeId: %d \ 00934 PDO ID: %d \n", _boardnr, _nodeid, _pdoID); 00935 rlDebugPrintf(err_out_buf); 00936 return 0; 00937 } 00938 00939 00940 if(nodelist[nodeindex]->pdoList[_pdoDirection].size() < (unsigned int) _pdoID) 00941 { 00942 sprintf(err_out_buf, "ERROR: PDO does not exist! refresh \ 00943 mapping list failed! BoardId: %d NodeId: %d \ 00944 PDO ID: %d \n", _boardnr, _nodeid, _pdoID); 00945 rlDebugPrintf(err_out_buf); 00946 return 0; 00947 } 00948 00949 //append Mapping data 00950 rlCanOpenTypes sdobuffer; 00951 int mappingcount; 00952 rlCanMapping * mappingobject; 00953 00954 //get mapping count 00955 if (sdo_read(_boardnr,_nodeid,madress,0,sdobuffer) == 0){ 00956 sprintf(err_out_buf, "ERROR: read sdo data! refresh mapping list failed! \ 00957 BoardId: %d NodeId: %d PDO ID: %d \n", 00958 _boardnr, _nodeid, _pdoID); 00959 rlDebugPrintf(err_out_buf); 00960 } 00961 00962 mappingcount = sdobuffer.get_uchar(); 00963 00964 sprintf(err_out_buf, "Current mappingcount: %d\n", mappingcount); 00965 rlDebugPrintf(err_out_buf); 00966 00967 nodelist[nodeindex]->pdoList[_pdoDirection][_pdoID-1]-> 00968 mappingList.resize(mappingcount); 00969 00970 int currentposition = 0; 00971 for (int mcount = 1; mcount <= mappingcount;mcount++) //each mappingobject 00972 { 00973 mappingobject = new rlCanMapping; //create new mappingobject in memory 00974 mappingobject->mappingId = mcount; 00975 00976 00977 if (sdo_read(_boardnr,_nodeid,madress,mcount,sdobuffer) == 0){ 00978 sprintf(err_out_buf, "ERROR: read sdo data! refresh mapping list failed! \ 00979 BoardId: %d NodeId: %d PDO ID: %d \n", 00980 _boardnr, _nodeid, _pdoID); 00981 rlDebugPrintf(err_out_buf); 00982 //cout<<"Error during create Mappinglist!\n"; 00983 } 00984 00985 //get length of mapping object 00986 int mlength = sdobuffer.get_buffer(0); 00987 mappingobject->length = mlength; 00988 00989 //calculate the mapping position 00990 if (mcount>1) 00991 mappingobject->position = currentposition; 00992 else 00993 mappingobject->position = 0; 00994 currentposition+=mlength; 00995 00996 // get the ov adress of the current mapped object 00997 int mi = (int) (sdobuffer.get_buffer(3)*pow(256,1) 00998 + sdobuffer.get_buffer(2)); 00999 01000 unsigned char msi = sdobuffer.get_buffer(1); 01001 01002 rlCanOpenTypes temptype; 01003 mappingobject->etype = temptype.canOpenType2DeamonType 01004 (nodelist[nodelist.size()-1]->objecttype(mi, msi)); 01005 01006 // insert the mappingobject to mappinglist 01007 nodelist[nodeindex]->pdoList[_pdoDirection][_pdoID-1]-> 01008 mappingList.insert(mcount-1,mappingobject); 01009 01010 } 01011 return 1; 01012 }
| int rlCanOpen::restartBoard | ( | int | _boardnr, | |
| int | _restarttype | |||
| ) |
using this function you are able to restart a CanOpenMaster board
Using this function you are able to restart a CanOpenMaster board (device). There are 3 possibly kinds of restarting the master: coldstart, warmstart, bootstart. The corresponding 'defines' are declared in canopenstructs.h Hilscher specific function (so no CanOpoen services) are used to execute this command
Definition at line 1114 of file rlcanopen.cpp.
01115 { 01116 //COLDSTART 2 01117 //WARMSTART 3 01118 //BOOTSTART 4 01119 01120 if ( (sRet = DevReset(_boardnr, _restarttype, 5000L) != DRV_NO_ERROR )) 01121 { 01122 rlDebugPrintf("restart failed!\n"); 01123 rlDebugPrintf("DevReset(%d, Restart, 5000): %d\n", _boardnr, sRet); 01124 return 0; 01125 } 01126 01127 rlDebugPrintf("restart successfully\n"); 01128 return 1; 01129 }
| int rlCanOpen::sdo_read | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _objectindex, | |||
| int | _subindex, | |||
| rlCanOpenTypes & | _sdo_data | |||
| ) |
read a certain object from the object dictionary of a node
using the sdo_read function you can read a certain object from the object dictionary of a node. For this the SDO (Service Data Object) service will be used. The enquired object will be written to the rlCanOpenTypes class. To read out the correct value from this class use one of the get_TYPE() {e.g. get_int() } functions. You can assert the type in the class using rlCanOpenTypes::get_DaemonType(); if sdo_read failures the current error can be read out using rlCanOpenTypes::get_rlmsgerr()
Definition at line 332 of file rlcanopen.cpp.
00337 { 00338 int datalength; 00339 int canopentype; 00340 int nodeindex; 00341 00342 if (getNodeIndex(_boardnr,_nodeid,nodeindex)== 0) 00343 { 00344 rlDebugPrintf("ERROR: specified node does not exist! SDO write failed!"); 00345 rlDebugPrintf("BoardId: %d NodeId: %d Objektindex: %d Subindex: %d\n", 00346 _boardnr, _nodeid, _objectindex, _subindex); 00347 00348 _sdo_data.set_rlmsgerr(ERRCODE_INVALID_NODEID); 00349 return 0; 00350 } 00351 00352 00353 delmsg(); 00354 setBoardActive(_boardnr); 00355 00356 message.rx = CAN_TASK; 00357 message.tx = USER_AT_HOST; 00358 message.ln = 8; 00359 message.nr = messagenr++; 00360 message.a = 0; 00361 message.f = 0; 00362 message.b = CMDCODE_SDO_UPDOWNLOAD; 00363 message.e = 0; 00364 message.device_adr = _nodeid; 00365 message.data_area = 0; 00366 message.data_adr = _objectindex; 00367 message.data_idx = _subindex; 00368 message.data_cnt = 0; 00369 message.data_type = 0; 00370 message.function = TASK_TFC_READ; 00371 00372 if(DevPutMessage(0, (MSG_STRUC *)&message,5000L) != DRV_NO_ERROR) return 0; 00373 00374 delmsg(); 00375 // receive the answer 00376 00377 sRet = DevGetMessage( getActiveBoard(), // Device Number 00378 sizeof(message), 00379 (MSG_STRUC *)&message, // Pointer to user buffer 00380 2000L ); // Timeout 00381 unsigned char msgnrlocal; 00382 msgnrlocal = messagenr - 1; 00383 00384 // receive correct answer 00385 if((message.a == CMDCODE_SDO_UPDOWNLOAD)&&(message.nr == msgnrlocal)){ 00386 _sdo_data.set_rlmsgerr(message.f); 00387 if (message.f == ERRCODE_NOERROR) // node active, no error 00388 { 00389 canopentype=getObjectType(_boardnr, _nodeid, _objectindex, _subindex); 00390 if (canopentype!=rlCanOpenTypes::RL_NOTYPE){ 00391 _sdo_data.set_CanOpenType(canopentype); 00392 datalength = _sdo_data.getLength(); 00393 } 00394 else 00395 { 00396 _sdo_data.set_DaemonType(rlCanOpenTypes::RL_BUFFER); 00397 datalength = MAX_SDO_BUFFERSIZE; 00398 } 00399 _sdo_data.clearBuffer(); 00400 for(int i = 0; i < datalength; i++) 00401 _sdo_data.set_buffer(i, message.d[i]); 00402 00403 // if CanOpen-Type is a twistet integer (etc. 52Bit ) the value will be converted 00404 if ((is_twisted_type(canopentype)) && (nodelist[nodeindex]->hasMapping())) 00405 _sdo_data.translate_CanOpenType(canopentype); 00406 00407 return 1; 00408 } 00409 else 00410 { 00411 rlDebugPrintf("message.f = %d message.f = %x Hex \n", message.f, message.f); 00412 } 00413 } 00414 else 00415 { 00416 rlDebugPrintf("message.a = %d message.nr = %d vergleich mit: %d\n", 00417 message.a, message.nr, msgnrlocal); 00418 00419 _sdo_data.set_rlmsgerr(-1); 00420 } 00421 rlDebugPrintf("ERROR during read SDO message!"); 00422 rlDebugPrintf("BoardId: %d NodeId: %d Obj: %x Sub: %x\n", 00423 _boardnr, _nodeid, _objectindex, _subindex); 00424 00425 00426 return 0; 00427 }
| int rlCanOpen::sdo_write | ( | int | _boardnr, | |
| int | _nodeid, | |||
| int | _objectindex, | |||
| int | _subindex, | |||
| rlCanOpenTypes & | _sdo_data | |||
| ) |
write data into a certain object from the object dictionary of a node
using the sdo_write function you can write to a certain object from the object dictionary of a node. For this the SDO (Service Data Object) Service will be used. The relevant data must be written into the rlCanOpenTypes class before. To write the data into the rlCanOpenTypes class use one of the datatype depending functions like rlCanOpenTypes::set_int(int _value); if sdo_write failures the current error can be read out using rlCanOpenTypes::get_rlmsgerr()
Definition at line 431 of file rlcanopen.cpp.
00436 { 00437 int length; 00438 int pdoid; 00439 length = _sdo_data.getLength(); 00440 int nodeindex; 00441 if (getNodeIndex(_boardnr,_nodeid,nodeindex)== 0) 00442 { 00443 rlDebugPrintf("ERROR: specified node does not exist! SDO write failed!"); 00444 rlDebugPrintf("BoardId: %d NodeId: %d Objektindex: %d Subindex: %d\n", 00445 _boardnr, _nodeid, _objectindex, _subindex); 00446 00447 _sdo_data.set_rlmsgerr(ERRCODE_INVALID_NODEID); 00448 return 0; 00449 } 00450 00451 // if CanOpen-Type is a twistet integer (etc. 52Bit ) the datalength must be adjusted 00452 int canopentype = getObjectType(_boardnr, _nodeid, _objectindex, _subindex); 00453 00454 if ((is_twisted_type(canopentype)) && (nodelist[nodeindex]->hasMapping())) 00455 length = _sdo_data.get_CanOpenTypeLength(canopentype); 00456 00457 for(int i = 0;i<length;i++) 00458 message.d[i] = _sdo_data.get_buffer(i); 00459 00460 00461 setBoardActive(_boardnr); 00462 00463 message.rx = CAN_TASK; 00464 message.tx = USER_AT_HOST; 00465 message.ln = 8+ length; 00466 message.nr = messagenr++; 00467 message.a = 0; 00468 message.f = 0; 00469 message.b = CMDCODE_SDO_UPDOWNLOAD; 00470 message.e = 0; 00471 message.device_adr = _nodeid; 00472 message.data_area = 0; 00473 message.data_adr = _objectindex; 00474 message.data_idx = _subindex; 00475 message.data_cnt = length; 00476 message.data_type = 0; 00477 message.function = TASK_TFC_WRITE; 00478 00479 if(DevPutMessage(0, (MSG_STRUC *)&message,5000L) != DRV_NO_ERROR) return 0; 00480 00481 00482 // receive the answer 00483 00484 sRet = DevGetMessage ( _boardnr, // Device Number 00485 sizeof(message), 00486 (MSG_STRUC *)&message, // Pointer to user buffer 00487 2000L ); // Timeout 00488 00489 unsigned char msgnrlocal = messagenr - 1; 00490 00491 // receive correct answer 00492 if((message.a == CMDCODE_SDO_UPDOWNLOAD)&&(message.nr == msgnrlocal)){ 00493 _sdo_data.set_rlmsgerr(message.f); 00494 if (message.f == ERRCODE_NOERROR) // node active, no error 00495 { 00496 //check if the mapping has changed 00497 if( (_objectindex >= TRANSMIT_PDO_MAPPING_STARTADRESS) && 00498 (_objectindex <= TRANSMIT_PDO_MAPPING_MAXADRESS) && 00499 (nodelist[nodeindex]->hasMapping()) ) 00500 { 00501 rlDebugPrintf("Mapping has changed: boardid %d, nodeid %d, objectindex %x\n", 00502 _boardnr, _nodeid, _objectindex); 00503 00504 pdoid = getPdoID(_boardnr, _nodeid, _objectindex, DIRECTION_TRANSMIT); 00505 refreshMappingList(_boardnr,_nodeid,pdoid,DIRECTION_TRANSMIT); 00506 } 00507 else if ( (_objectindex >= RECEIVE_PDO_MAPPING_STARTADRESS) && 00508 (_objectindex <= RECEIVE_PDO_MAPPING_MAXADRESS) && 00509 (nodelist[nodeindex]->hasMapping()) ) 00510 { 00511 rlDebugPrintf("Mapping has changed: boardid %d, nodeid %d, objectindex %x\n", 00512 _boardnr, _nodeid, _objectindex); 00513 pdoid = getPdoID(_boardnr, _nodeid, _objectindex, DIRECTION_RECEIVE); 00514 refreshMappingList(_boardnr,_nodeid,pdoid,DIRECTION_RECEIVE); 00515 } 00516 return 1; 00517 } 00518 else 00519 { 00520 sprintf(err_out_buf, "message.f = %d message.f = %x Hex \n", 00521 message.f, message.f); 00522 00523 rlDebugPrintf(err_out_buf); 00524 _sdo_data.set_rlmsgerr(message.f); 00525 } 00526 } 00527 else 00528 { 00529 _sdo_data.set_rlmsgerr(-1); 00530 sprintf(err_out_buf, "message.a = %d message.nr = %d vergleich mit: %d\n", 00531 message.a, message.nr, msgnrlocal); 00532 00533 rlDebugPrintf(err_out_buf); 00534 } 00535 rlDebugPrintf("ERROR during read SDO message!"); 00536 rlDebugPrintf("BoardId: %d NodeId: %d Obj: %x Sub: %x\n", 00537 _boardnr, _nodeid, _objectindex, _subindex); 00538 00539 rlDebugPrintf(err_out_buf); 00540 return 0; 00541 }
| int rlCanOpen::sendNMTCommand | ( | int | _boardnr, | |
| int | _nodeid, | |||
| unsigned char | _cmd | |||
| ) |
send a NMT Command to one or all nodes (of one board)
Using this function you can send a NMT Command to one or all nodes (of one board). NMT (Network Management) is a CanOpen service. Because of the device there are constrictions for the user. You can only execute the follow NMT commands: START_REMOTE_NODE, STOP_REMOTE_NODE, ENTER_PREOPERATIONAL, RESET_NODE, RESET_COMMUNICATION The corresponding 'defines' are declared in canopenstructs.h
Definition at line 1132 of file rlcanopen.cpp.
01133 { 01134 MSG_STRUC message; 01135 setBoardActive(_boardnr); 01136 01137 message.rx = CAN_TASK ;//receiver = user at HOST 01138 message.tx = USER_AT_HOST ;// transmitter = USR_INTF-Task 01139 message.ln = 2 ;//length of message 01140 message.nr = messagenr++ ;//number of the message 01141 message.a = 0 ;//no answer 01142 message.f = 0 ;//error, status 01143 message.b = CMD_NMT_Module_Protocol;//command = COM_Node_Diag 01144 message.e = 0 ;//extension 01145 01146 // NMT Command specifier 01147 //1 Start Remote Node 01148 //2 Stop Remote Node 01149 //128 Enter Pre-Operational 01150 //129 Reset Node 01151 //130 Reset Communication 01152 message.data[0] = _cmd ;//NMT Command specifier 01153 message.data[1] = _nodeid ;//NodeID 01154 01155 if ( (sRet = DevPutMessage(_boardnr, (MSG_STRUC *)&message, 5000L)) 01156 == DRV_NO_ERROR ) 01157 { 01158 while( (sRet = DevGetMessage(_boardnr, sizeof(message), 01159 (MSG_STRUC *)&message, 0)) 01160 == DRV_DEV_GET_NO_MESSAGE ) 01161 { 01162 continue; 01163 } 01164 if ( sRet == DRV_NO_ERROR ) 01165 { 01166 rlDebugPrintf("NMT message successfully received\n"); 01167 // continue; 01168 } 01169 else 01170 { 01171 rlDebugPrintf("Error Message (f = %d))\n",message.f); 01172 rlDebugPrintf("\nDevGetMessage(%d, sizeof(message), &message, 500): %d\n", 01173 _boardnr, (int)sRet); 01174 01175 return 0; 01176 } 01177 } 01178 else 01179 { 01180 rlDebugPrintf("\nDevPutMessage(NMT)(%d, &message, 5000): %d\n",_boardnr, (int)sRet); 01181 return 0; 01182 } /* if ( (sRet = DevPutMessage(...)) == DRV_NO_ERROR ) else */ 01183 01184 return 1; 01185 }
| short rlCanOpen::setBoardActive | ( | int | _boardnr | ) | [private] |
sets a desired CanOpenMaster active, so that it can be used
Definition at line 285 of file rlcanopen.cpp.
00286 { 00287 00288 if ( (sRet = DevSetHostState( _boardnr, HOST_READY, 0L) == DRV_NO_ERROR) ) 00289 activeboard = _boardnr; 00290 00291 return sRet; 00292 }
| bool rlCanOpen::showNodeConfiguration | ( | ) |
prints out the configuration off all available nodes from all boards
Definition at line 320 of file rlcanopen.cpp.
| bool rlCanOpen::showNodeConfiguration | ( | int | _boardnr, | |
| int | _nodeid | |||
| ) |
prints out the configuration of a specific node
Definition at line 303 of file rlcanopen.cpp.
int rlCanOpen::activeboard [private] |
the currently active board
Definition at line 219 of file rlcanopen.h.
int rlCanOpen::boardcount [private] |
the current count of CanOpenMaster cards
Definition at line 253 of file rlcanopen.h.
bool rlCanOpen::enableLogging [private] |
this indicator is true when stdout is redirected to file. it is set in the ini-file
Definition at line 281 of file rlcanopen.h.
FILE* rlCanOpen::err_fp [private] |
Pointer to error logfile.
Definition at line 241 of file rlcanopen.h.
char rlCanOpen::err_out_buf[255] [private] |
this string buffer is usually written with sprintf before sent to stdout
Definition at line 235 of file rlcanopen.h.
QString rlCanOpen::logFileName [private] |
name of logfile stdout is redirected to
Definition at line 244 of file rlcanopen.h.
RCS_MESSAGETELEGRAM_10 rlCanOpen::message [private] |
hilscher specific message structur which will be sent to the master card
Definition at line 247 of file rlcanopen.h.
unsigned char rlCanOpen::messagenr [private] |
message counter
Definition at line 256 of file rlcanopen.h.
QPtrVector<rlCanNode> rlCanOpen::nodelist [private] |
this list contains all nodes from all boards
Definition at line 250 of file rlcanopen.h.
short rlCanOpen::sRet [private] |
return value for hilscher specific message functions
Definition at line 238 of file rlcanopen.h.
1.6.3