Advertisement
Guest User

Untitled

a guest
Jun 14th, 2021
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.00 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3. from uio.utils import fix_ctypes_struct
  4. from uio.ti.icss import Icss
  5. import ctypes
  6. from ctypes import c_uint32 as u32, c_uint16 as u16, c_int32 as int32
  7. from time import sleep
  8. from sys import exit
  9.  
  10. pruss = Icss( "/dev/uio/pruss/module" )
  11. pruss.initialize()
  12. ddr = pruss.ddr
  13.  
  14. core_1 = pruss.core1
  15. core_1.load( 'fw-c/stream.out' )
  16.  
  17.  
  18. core_0 = pruss.core0
  19. core_0.load( 'fw/decoder.bin' )
  20.  
  21. class Message( ctypes.Structure ):
  22. _fields_ = [
  23. ( 'id', u32 ),
  24. ('position', u32),
  25. ]
  26.  
  27. # used to communicate ddr layout to C program
  28. class DDRLayout( ctypes.Structure ):
  29. _fields_ = [
  30. ( 'msgbuf', u32 ),
  31. ( 'num_msgs', u16 ),
  32. ( 'msg_size', u16 ),
  33. ]
  34.  
  35. # volatile variables in pruss shared memory
  36. class SharedVars( ctypes.Structure ):
  37. _fields_ = [
  38. ( 'abort_file', u32 ),
  39. ( 'abort_line', u32 ),
  40.  
  41. ( 'ridx', u16 ),
  42. ]
  43.  
  44. # if you don't want the ringbuffer at the start of the ddr region, specify offset here
  45. MSGBUF_OFFSET = 0
  46.  
  47. # you can use a fixed ringbuffer size:
  48. #NUM_MSGS = 1024
  49. # or you can scale the ringbuffer to fit the size of the ddr region:
  50. NUM_MSGS = ( ddr.size - MSGBUF_OFFSET - ctypes.sizeof( u16 ) ) // ctypes.sizeof( Message )
  51. NUM_MSGS = min( NUM_MSGS, 65535 ) # make sure number of messages fits in u16
  52.  
  53. # map shared memory variables
  54. ddr_layout = core_1.map( DDRLayout, 0x10000 )
  55. shmem = core_1.map( SharedVars, 0x10100 )
  56. msgbuf = ddr.map( Message * NUM_MSGS, MSGBUF_OFFSET )
  57. ddr_widx = ddr.map( u16, MSGBUF_OFFSET + ctypes.sizeof( msgbuf ) )
  58.  
  59. # inform pru about layout of shared ddr memory region
  60. ddr_layout.msgbuf = ddr.address + MSGBUF_OFFSET
  61. ddr_layout.num_msgs = NUM_MSGS
  62. ddr_layout.msg_size = ctypes.sizeof( Message )
  63.  
  64. # local copies of read-pointer and write-pointer
  65. ridx = 0
  66. widx = 0
  67. id_value = 0
  68. position_value = 0
  69.  
  70. # initialize pointers in shared memory
  71. shmem.ridx = ridx
  72. ddr_widx.value = widx
  73.  
  74. # ready, set, go!
  75. core_0.run()
  76. core_1.run()
  77.  
  78. def check_core():
  79. if not core_1.halted:
  80. return
  81.  
  82. if core.state.crashed:
  83. msg = f'core crashed at pc={core_1.pc}'
  84. elif shmem.abort_file == 0:
  85. msg = f'core halted at pc={core_1.pc}'
  86. else:
  87. # FIXME figure out better way to read C-string from PRU memory
  88. abort_file = core.read( ctypes.c_char * 32, shmem.abort_file ).value
  89. abort_file = abort_file.decode("ascii")
  90. msg = f'core aborted at pc={core.pc} ({abort_file}:{shmem.abort_line})'
  91.  
  92. # dump some potentially interesting information:
  93. msg += f'\n ridx = {ridx}'
  94. msg += f'\n shmem.ridx = {shmem.ridx}'
  95. msg += f'\n ddr_widx = {ddr_widx.value}'
  96.  
  97. exit( msg )
  98.  
  99. lastid = 0
  100.  
  101. def recv_messages():
  102. global ridx, widx, lastid
  103.  
  104. # read updated write-pointer
  105. widx = ddr_widx.value
  106. assert widx < NUM_MSGS # sanity-check
  107.  
  108.  
  109. position = 0
  110. # process messages
  111. while ridx != widx:
  112. # note: it may be faster to copy a batch of messages from shared memory
  113. # instead of directly accessing individual messages and their fields.
  114. msg = msgbuf[ ridx ]
  115. # sanity-check that message id increments monotonically
  116. lastid = ( lastid + 1 ) & 0xffffffff
  117. assert msg.id == lastid
  118.  
  119. position = msg.position
  120. # consume message and update read pointer
  121. del msg # direct access to message forbidden beyond this point
  122. ridx += 1
  123. if ridx == NUM_MSGS:
  124. ridx = 0
  125. shmem.ridx = ridx
  126.  
  127. # update user interface
  128. # print( f'\rid={id_value} position={position_value} ', end='', flush=True )
  129. print( f'\ridx=0x{ridx:04x} id=0x{lastid:08x} position={position}', end='', flush=True )
  130.  
  131.  
  132. try:
  133. while True:
  134. recv_messages()
  135. check_core()
  136. sleep( 0.01 )
  137.  
  138. except KeyboardInterrupt:
  139. pass
  140.  
  141. finally:
  142. print( '', flush=True )
  143. core_0.halt()
  144. core_1.halt()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement