CanPeakSysUSB.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 //#define __DEBUG__
19 
21 #include <stdlib.h>
22 #include <cerrno>
23 #include <cstring>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 //-----------------------------------------------
30 CANPeakSysUSB::CANPeakSysUSB(const char* device, int baudrate)
31 {
32  m_bInitialized = false;
33 
34  p_cDevice = device;
35  m_iBaudrateVal = baudrate;
36 }
37 
38 CANPeakSysUSB::CANPeakSysUSB(const char* cIniFile)
39 {
40  m_bInitialized = false;
41 
42  // read IniFile
43  m_IniFile.SetFileName(cIniFile, "CanPeakSysUSB.cpp");
44 
45  init();
46 }
47 
48 //-----------------------------------------------
50 {
51  if (m_bInitialized)
52  {
53  CAN_Close(m_handle);
54  }
55 }
56 
57 //-----------------------------------------------
59 {
60  bool ret = true;
61 
62  // init() - part
63  m_handle = LINUX_CAN_Open(p_cDevice, O_RDWR);
64 
65  if (! m_handle)
66  {
67  std::cout << "Cannot open CAN on USB: " << strerror(errno) << std::endl;
68  ret = false;
69  }
70  else
71  {
72  ret = initCAN();
73  }
74 
75  return ret;
76 }
77 
78 //-----------------------------------------------
80 {
81  std::string sCanDevice;
82 
83  if( m_IniFile.GetKeyString( "TypeCan", "DevicePath", &sCanDevice, false) != 0) {
84  sCanDevice = "/dev/pcan32";
85  } else std::cout << "CAN-device path read from ini-File: " << sCanDevice << std::endl;
86 
87  //m_handle = LINUX_CAN_Open("/dev/pcan32", O_RDWR | O_NONBLOCK);
88  m_handle = LINUX_CAN_Open(sCanDevice.c_str(), O_RDWR);
89 
90  if (! m_handle)
91  {
92  // Fatal error
93  std::cout << "Cannot open CAN on USB: " << strerror(errno) << std::endl;
94  sleep(3);
95  exit(0);
96  }
97 
98  m_iBaudrateVal = 0;
99  m_IniFile.GetKeyInt( "CanCtrl", "BaudrateVal", &m_iBaudrateVal, true);
100 
101  initCAN();
102 }
103 
104 //-------------------------------------------
105 bool CANPeakSysUSB::transmitMsg(CanMsg CMsg, bool bBlocking)
106 {
107  TPCANMsg TPCMsg;
108  bool bRet = true;
109 
110  if (m_bInitialized == false) return false;
111 
112  // copy CMsg to TPCmsg
113  TPCMsg.LEN = CMsg.getLength();
114  TPCMsg.ID = CMsg.getID();
115  TPCMsg.MSGTYPE = CMsg.getType();
116  for(int i=0; i<8; i++)
117  TPCMsg.DATA[i] = CMsg.getAt(i);
118 
119  //TODO Hier stürtzt die Base ab.. verwende libpcan.h pcan.h um Fehler auszulesen, diagnostizieren, ausgeben und CAN_INIT erneut aufzurufen = neustart can-hardware.
120 
121  int iRet;
122  //iRet = CAN_Write(m_handle, &TPCMsg);
123  iRet = LINUX_CAN_Write_Timeout(m_handle, &TPCMsg, 25); //Timeout in micrsoseconds
124 
125  if(iRet != CAN_ERR_OK) {
126 #ifdef __DEBUG__
127  std::cout << "CANPeakSysUSB::transmitMsg An error occured while sending..." << iRet << std::endl;
129 #endif
130  bRet = false;
131  }
132 
133 #ifdef __DEBUG__
134  //is this necessary? try iRet==CAN_Status(m_handle) ?
135  iRet = CAN_Status(m_handle);
136 
137  if(iRet < 0)
138  {
139  std::cout << "CANPeakSysUSB::transmitMsg, system error: " << iRet << std::endl;
140  bRet = false;
141  } else if((iRet & CAN_ERR_BUSOFF) != 0) {
142  std::cout << "CANPeakSysUSB::transmitMsg, BUSOFF detected" << std::endl;
143  //Try to restart CAN-Device
144  std::cout << "Trying to re-init Hardware..." << std::endl;
145  bRet = initCAN();
146 
147  } else if((iRet & CAN_ERR_ANYBUSERR) != 0) {
148  std::cout << "CANPeakSysUSB::transmitMsg, ANYBUSERR" << std::endl;
149 
150  } else if( (iRet & (~CAN_ERR_QRCVEMPTY)) != 0) {
151  std::cout << "CANPeakSysUSB::transmitMsg, CAN_STATUS: " << iRet << std::endl;
152  bRet = false;
153  }
154 #endif
155 
156  return bRet;
157 }
158 
159 //-------------------------------------------
161 {
162  TPCANRdMsg TPCMsg;
163  TPCMsg.Msg.LEN = 8;
164  TPCMsg.Msg.MSGTYPE = 0;
165  TPCMsg.Msg.ID = 0;
166 
167  int iRet = CAN_ERR_OK;
168 
169  bool bRet = false;
170 
171  if (m_bInitialized == false) return false;
172 
173  iRet = LINUX_CAN_Read_Timeout(m_handle, &TPCMsg, 0);
174 
175  if (iRet == CAN_ERR_OK)
176  {
177  pCMsg->setID(TPCMsg.Msg.ID);
178  pCMsg->setLength(TPCMsg.Msg.LEN);
179  pCMsg->set(TPCMsg.Msg.DATA[0], TPCMsg.Msg.DATA[1], TPCMsg.Msg.DATA[2], TPCMsg.Msg.DATA[3],
180  TPCMsg.Msg.DATA[4], TPCMsg.Msg.DATA[5], TPCMsg.Msg.DATA[6], TPCMsg.Msg.DATA[7]);
181  bRet = true;
182  }
183  else if( (iRet & (~CAN_ERR_QRCVEMPTY)) != 0) //no"empty-queue"-status
184  {
185  std::cout << "CANPeakSysUSB::receiveMsg, CAN_STATUS: " << iRet << std::endl;
186  pCMsg->set(0, 0, 0, 0, 0, 0, 0, 0);
187  }
188 
189  //catch status messages, these could be further processed in overlying software to identify and handle CAN errors
190  if( TPCMsg.Msg.MSGTYPE == MSGTYPE_STATUS ) {
191  std::cout << "CANPeakSysUSB::receiveMsg, status message catched:\nData is (CAN_ERROR_...) " << TPCMsg.Msg.DATA[3] << std::endl;
192  pCMsg->set(0, 0, 0, 0, 0, 0, 0, 0);
193  }
194 
195  return bRet;
196 }
197 
198 //-------------------------------------------
199 bool CANPeakSysUSB::receiveMsgRetry(CanMsg* pCMsg, int iNrOfRetry)
200 {
201  int i, iRet;
202 
203  TPCANRdMsg TPCMsg;
204  TPCMsg.Msg.LEN = 8;
205  TPCMsg.Msg.MSGTYPE = 0;
206  TPCMsg.Msg.ID = 0;
207 
208  if (m_bInitialized == false) return false;
209 
210  // wait until msg in buffer
211  bool bRet = true;
212  iRet = CAN_ERR_OK;
213  i=0;
214  do
215  {
216  iRet = LINUX_CAN_Read_Timeout(m_handle, &TPCMsg, 0);
217 
218  if(iRet == CAN_ERR_OK)
219  break;
220 
221  i++;
222  usleep(10000);
223  }
224  while(i < iNrOfRetry);
225 
226  // eval return value
227  if(iRet != CAN_ERR_OK)
228  {
229  std::cout << "CANPeakSysUSB::receiveMsgRetry, errorcode= " << nGetLastError() << std::endl;
230  pCMsg->set(0, 0, 0, 0, 0, 0, 0, 0);
231  bRet = false;
232  }
233  else
234  {
235  pCMsg->setID(TPCMsg.Msg.ID);
236  pCMsg->setLength(TPCMsg.Msg.LEN);
237  pCMsg->set(TPCMsg.Msg.DATA[0], TPCMsg.Msg.DATA[1], TPCMsg.Msg.DATA[2], TPCMsg.Msg.DATA[3],
238  TPCMsg.Msg.DATA[4], TPCMsg.Msg.DATA[5], TPCMsg.Msg.DATA[6], TPCMsg.Msg.DATA[7]);
239  }
240 
241  return bRet;
242 }
243 
244 //-------------------------------------------
245 bool CANPeakSysUSB::receiveMsgTimeout(CanMsg* pCMsg, int nMicroSecTimeout)
246 {
247  int iRet = CAN_ERR_OK;
248 
249  TPCANRdMsg TPCMsg;
250  TPCMsg.Msg.LEN = 8;
251  TPCMsg.Msg.MSGTYPE = 0;
252  TPCMsg.Msg.ID = 0;
253 
254  if (m_bInitialized == false) return false;
255 
256  bool bRet = true;
257 
258  iRet = LINUX_CAN_Read_Timeout(m_handle, &TPCMsg, nMicroSecTimeout);
259 
260  // eval return value
261  if(iRet != CAN_ERR_OK)
262  {
263  std::cout << "CANPeakSysUSB::receiveMsgTimeout, errorcode= " << nGetLastError() << std::endl;
264  pCMsg->set(0, 0, 0, 0, 0, 0, 0, 0);
265  bRet = false;
266  }
267  else
268  {
269  pCMsg->setID(TPCMsg.Msg.ID);
270  pCMsg->setLength(TPCMsg.Msg.LEN);
271  pCMsg->set(TPCMsg.Msg.DATA[0], TPCMsg.Msg.DATA[1], TPCMsg.Msg.DATA[2], TPCMsg.Msg.DATA[3],
272  TPCMsg.Msg.DATA[4], TPCMsg.Msg.DATA[5], TPCMsg.Msg.DATA[6], TPCMsg.Msg.DATA[7]);
273  }
274 
275  return bRet;
276 }
277 
279  int ret = CAN_ERR_OK;
280  bool bRet = true;
281 
282  switch(m_iBaudrateVal)
283  {
284  case CANITFBAUD_1M:
285  ret = CAN_Init(m_handle, CAN_BAUD_1M, CAN_INIT_TYPE_ST);
286  break;
287  case CANITFBAUD_500K:
288  ret = CAN_Init(m_handle, CAN_BAUD_500K, CAN_INIT_TYPE_ST);
289  break;
290  case CANITFBAUD_250K:
291  ret = CAN_Init(m_handle, CAN_BAUD_250K, CAN_INIT_TYPE_ST);
292  break;
293  case CANITFBAUD_125K:
294  ret = CAN_Init(m_handle, CAN_BAUD_125K, CAN_INIT_TYPE_ST);
295  break;
296  case CANITFBAUD_50K:
297  ret = CAN_Init(m_handle, CAN_BAUD_50K, CAN_INIT_TYPE_ST);
298  break;
299  case CANITFBAUD_20K:
300  ret = CAN_Init(m_handle, CAN_BAUD_20K, CAN_INIT_TYPE_ST);
301  break;
302  case CANITFBAUD_10K:
303  ret = CAN_Init(m_handle, CAN_BAUD_10K, CAN_INIT_TYPE_ST);
304  break;
305  }
306 
307  if(ret)
308  {
309  std::cout << "CANPeakSysUSB::CANPeakSysUSB(), error in init" << std::endl;
310  m_bInitialized = false;
311  bRet = false;
312  }
313  else
314  {
315  std::cout << "CANPeakSysUSB::CanpeakSys(), init ok" << std::endl;
316  m_bInitialized = true;
317  bRet = true;
318  }
319 
320  return bRet;
321 }
322 
324  TPDIAG diag;
325 
326  LINUX_CAN_Statistics(m_handle, &diag);
327 
328  std::cout << "*************************\n"
329  << "*** Detailed status output of CANPeakSys\n"
330  << "*************************"
331  << "\nIRQ-Level: " << diag.wIrqLevel
332  << "\nNo reads: " << diag.dwReadCounter
333  << "\nNo writes: " << diag.dwWriteCounter
334  << "\nNo interrupts: " << diag.dwIRQcounter
335  << "\nNo errors: " << diag.dwErrorCounter
336  << "\nError flag: " << diag.wErrorFlag
337  << "\nLast error: " << diag.nLastError
338  << std::endl;
339 }
bool receiveMsg(CanMsg *pCMsg)
void setLength(int len)
Definition: CanMsg.h:182
#define CANITFBAUD_500K
Definition: CanItf.h:33
#define CANITFBAUD_50K
Definition: CanItf.h:36
void outputDetailedStatus()
int getID()
Definition: CanMsg.h:153
IniFile m_IniFile
Definition: CanPeakSysUSB.h:47
Definition: CanMsg.h:28
#define CANITFBAUD_1M
Definition: CanItf.h:32
CANPeakSysUSB(const char *device, int baudrate)
#define CANITFBAUD_250K
Definition: CanItf.h:34
int GetKeyInt(const char *pSect, const char *pKey, int *pValue, bool bWarnIfNotfound=true)
bool receiveMsgRetry(CanMsg *pCMsg, int iNrOfRetry)
int getType()
Definition: CanMsg.h:192
void setID(int id)
Definition: CanMsg.h:163
int SetFileName(std::string fileName, std::string strIniFileUsedBy="", bool bCreate=false)
#define CANITFBAUD_20K
Definition: CanItf.h:37
const char * p_cDevice
Definition: CanPeakSysUSB.h:49
bool receiveMsgTimeout(CanMsg *pCMsg, int nMicroSeconds)
void set(BYTE Data0=0, BYTE Data1=0, BYTE Data2=0, BYTE Data3=0, BYTE Data4=0, BYTE Data5=0, BYTE Data6=0, BYTE Data7=0)
Definition: CanMsg.h:60
int GetKeyString(const char *pSect, const char *pKey, std::string *pStrToRead, bool bWarnIfNotfound=true)
#define CANITFBAUD_10K
Definition: CanItf.h:38
bool transmitMsg(CanMsg CMsg, bool bBlocking=true)
int getLength()
Definition: CanMsg.h:173
#define CANITFBAUD_125K
Definition: CanItf.h:35
int getAt(int iNr)
Definition: CanMsg.h:99


cob_generic_can
Author(s): Christian Connette
autogenerated on Wed Apr 7 2021 02:11:52