Advertisement
Guest User

Untitled

a guest
Sep 2nd, 2015
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.34 KB | None | 0 0
  1. #!/usr/bin/env python
  2. """
  3. General CAN functions using Kvaser canlib
  4. """
  5. from __future__ import print_function
  6.  
  7. import logging
  8. from sys import exit
  9.  
  10. # kvaser canlib
  11. from canlib import *
  12.  
  13.  
  14. def setup(port_id, bitrate=canBITRATE_250K):
  15. """Setup kvaser CAN given port_id which may be device channel or serial number"""
  16. cl = canlib()
  17. channels = cl.getNumberOfChannels()
  18.  
  19. logging.info("Kvaser canlib version: %s, %d channels available" %
  20. (cl.getVersion(), channels))
  21.  
  22. chans = {}
  23. for ch in range(0, channels):
  24. try:
  25. info = (ch,
  26. int(cl.getChannelData_Serial(ch)),
  27. cl.getChannelData_Name(ch),
  28. cl.getChannelData_EAN(ch))
  29.  
  30. chans[ch] = info # key on channel number
  31. if info[1] >= channels:
  32. chans[info[1]] = info # key on serial number
  33. except (canError) as ex:
  34. print(ex)
  35.  
  36. try:
  37. ch = chans[port_id][0]
  38. except KeyError:
  39. print('A valid port number is required for --port option:')
  40. for k in chans.items():
  41. print('%d: %s' % k)
  42. print()
  43. exit()
  44.  
  45. chan = cl.openChannel(ch, canOPEN_ACCEPT_VIRTUAL | canOPEN_REQUIRE_EXTENDED)
  46. chan.ioCtl_set_timer_scale(100) # microseconds per tick
  47. chan.timer_scale = 100
  48. chan.setBusOutputControl(canDRIVER_NORMAL)
  49. chan.setBusParams(bitrate)
  50. chan.busOn()
  51.  
  52. return chan, cl
  53.  
  54.  
  55. error_flags = (canMSG_ERROR_FRAME | canMSG_NERR |
  56. canMSGERR_HW_OVERRUN | canMSGERR_SW_OVERRUN)
  57.  
  58.  
  59. def flags_str(flags):
  60. fl = []
  61. if flags & canMSG_RTR: # 1 Message is a remote request
  62. fl.append('RTR|')
  63. if flags & canMSG_STD: #2 Message has a standard (11-bit) identifier
  64. fl.append('STD')
  65. if flags & canMSG_EXT: #4 Message has a extended (29-bit) identifier
  66. fl.append('EXT')
  67. if flags & canMSG_WAKEUP: #8 Message is a WAKEUP message (SWC hardware.)
  68. fl.append('WAKE')
  69. if flags & canMSG_ERROR_FRAME: #32 Message represents an error frame.
  70. fl.append('ERR')
  71.  
  72. #The following flags can be returned from canRead() et al, but cannot be passed to canWrite():
  73. if flags & canMSG_NERR: # 16 NERR was active during the message (TJA1054 etc. hardware. See Note 4 below.)/tr>
  74. fl.append('NERR')
  75. if flags & canMSG_TXACK : # 64 Message is a TX ACK (meaning that the message was really sent)/tr>
  76. fl.append('TXACK')
  77. if flags & canMSG_TXRQ: # 128 Message is a TX REQ (meaning that the message was transferred to the CAN controller)/tr>
  78. fl.append('TXRQ')
  79. if flags & canMSGERR_HW_OVERRUN: # 512 Hardware buffer overrun.
  80. fl.append('HWOVR')
  81. if flags & canMSGERR_SW_OVERRUN: # 1024 Software buffer overrun.
  82. fl.append('SWOVR')
  83.  
  84. return '|'.join(fl)
  85.  
  86.  
  87. def add_options(p):
  88. '''Add CAN related options to an optparse instance'''
  89. p.add_option('-b', '--bus', type='int', default=1,
  90. help='CAN bus index 1 or 2. Default=%default')
  91. p.add_option('-p', '--port', type='int', default=0,
  92. help='CAN channel #, typically 0 or 1, or device serial')
  93. p.add_option('-F', '--fake', action='store_true',
  94. help='Send packets direct to localhost MQTT broker instead of serial port')
  95.  
  96.  
  97. if __name__ == '__main__':
  98. from collections import defaultdict
  99. from optparse import OptionParser
  100. import random
  101. import time
  102.  
  103. def parse_options():
  104. p = OptionParser()
  105.  
  106. add_options(p)
  107. p.add_option('-l', '--loglevel', type='int', default=3,
  108. help='Logging level. Default=%default')
  109. opts, args = p.parse_args()
  110.  
  111. level = {1: logging.ERROR, 2: logging.WARNING, 3: logging.INFO,
  112. 4: logging.DEBUG}.get(opts.loglevel, logging.DEBUG)
  113. opts.loglevel = level
  114.  
  115. return opts, args
  116.  
  117.  
  118. opts, args = parse_options()
  119. logging.basicConfig(level=opts.loglevel)
  120.  
  121. busname = 'CAN-%d' % opts.bus
  122.  
  123. ch, lib = setup(opts.port)
  124.  
  125. num_messages = 100
  126. if args[0].startswith('w'): #
  127. max_std = 2047
  128. logging.info('Generating %d packets to %s (port#%d)' % (num_messages, ch.getChannelData_Name(), opts.port))
  129. sent = []
  130. for i in range(num_messages):
  131. msg = []
  132. for m in range(random.randint(1, 8)):
  133. msg.append(random.randint(0, 255))
  134. id = random.randint(0, max_std)
  135. sent.append(id)
  136. print(id, msg)
  137. ch.write(id, msg)
  138. print(sent)
  139. else:
  140. msgs_received = defaultdict(list)
  141. logging.info('Receiving %d packets from %s (port#%d)' % (num_messages, ch.getChannelData_Name(), opts.port))
  142. for i in range(num_messages):
  143. try:
  144. msg = ch.read(5000) # Ohhh, timeout seems to be in milliseconds, should be float seconds!
  145. except canNoMsg as e:
  146. logging.warning('No messages received for 5 seconds')
  147. continue
  148. except Exception as e:
  149. logging.error(str(e))
  150. continue
  151.  
  152. # print("%d rx id: %08X msg: %s" % (i, id, [x for x in msg]))
  153. msgs_received[msg[0]].append(msg)
  154.  
  155. ml = msgs_received.items()
  156. ml.sort()
  157. for k, v in ml:
  158. print('Rx ID: %08X' % k)
  159. for msg in v:
  160. print("dlc: %08X msg: %s" % (msg[2], [x for x in msg[1]]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement