mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-02-06 15:11:52 +08:00
127 lines
3.4 KiB
Python
127 lines
3.4 KiB
Python
#!/usr/bin/python2
|
|
|
|
# run openocd (0.9.0) with :
|
|
# $ openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg &> /dev/null &
|
|
# then run
|
|
# $ python2 sampler.py path_to_myelf_with_symbols
|
|
# ctrl-c to stop sampling.
|
|
# To terminate the openocd session, enter command "fg" then do ctrl-c.
|
|
|
|
import sys
|
|
import time
|
|
import telnetlib
|
|
import subprocess
|
|
from bisect import bisect_right
|
|
import operator
|
|
|
|
class OpenOCDCMSampler(object):
|
|
|
|
def __init__(self, host='localhost', port=4444):
|
|
|
|
self.net = telnetlib.Telnet(host, port)
|
|
self.net.read_very_eager()
|
|
|
|
self.table = []
|
|
self.indexes = set()
|
|
|
|
def __del__(self):
|
|
self.net.write(b'exit\r\n')
|
|
self.net.read_until(b'exit\r\n', 1)
|
|
self.net.close()
|
|
|
|
def getpc(self):
|
|
|
|
self.net.write(b'mrw 0xE000101C\r\n')
|
|
res = self.net.read_until(b'\r\n\r> ', 1)
|
|
|
|
if res:
|
|
prefix = res[0:16]
|
|
num = res[16:-5]
|
|
res = res[-15:0]
|
|
|
|
if prefix == b'mrw 0xE000101C\r\n':
|
|
return int(num)
|
|
|
|
return 0
|
|
|
|
|
|
def initSymbols(self, elf, readelf='arm-none-eabi-readelf'):
|
|
proc = subprocess.Popen([readelf, '-s', elf], stdout=subprocess.PIPE)
|
|
for line in proc.stdout.readlines():
|
|
field = line.split()
|
|
# for i,txt in enumerate(field):
|
|
# print("{}, {}".format(i, txt))
|
|
try:
|
|
if field[3] == b'FUNC':
|
|
addr = int(field[1], 16) - 1 # For some reason readelf dumps the func addr off by 1
|
|
func = field[7]
|
|
size = int(field[2])
|
|
if addr not in self.indexes:
|
|
self.table.append((addr, func, size))
|
|
self.indexes.add(addr)
|
|
except IndexError:
|
|
pass
|
|
|
|
self.table.sort()
|
|
self.addrs = [ x for (x, y, z) in self.table ]
|
|
|
|
|
|
def func(self, pc):
|
|
|
|
if pc == 0 or pc == 0xFFFFFFFF:
|
|
return ('', 0)
|
|
|
|
i = bisect_right(self.addrs, pc)
|
|
if i:
|
|
addr, symb, size = self.table[i-1]
|
|
if pc >= addr and pc <= addr + size:
|
|
return (symb, addr)
|
|
|
|
return ('', 0)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
sampler = OpenOCDCMSampler('localhost', 4444)
|
|
sampler.initSymbols(sys.argv[1])
|
|
|
|
total = 0
|
|
countmap = { }
|
|
pcmap = { }
|
|
start = time.time()
|
|
|
|
try:
|
|
while True:
|
|
pc = sampler.getpc()
|
|
|
|
if pc in pcmap:
|
|
pcmap[pc] += 1
|
|
else:
|
|
pcmap[pc] = 1
|
|
|
|
func, addr = sampler.func(pc)
|
|
|
|
if not addr:
|
|
continue
|
|
|
|
if func in countmap:
|
|
countmap[func] += 1
|
|
total += 1
|
|
else:
|
|
countmap[func] = 1
|
|
total += 1
|
|
|
|
cur = time.time()
|
|
if cur - start > 1.0:
|
|
tmp = sorted(countmap.items(), key=operator.itemgetter(1)) #, reverse=True)
|
|
for k, v in tmp:
|
|
print('{:05.2f}% {}'.format((v * 100.) / total, k))
|
|
# print('{:06.2f} clocks : {}'.format((v * 10500) / total, k))
|
|
start = cur
|
|
print('{} Samples'.format(total))
|
|
print('')
|
|
|
|
except KeyboardInterrupt:
|
|
pcmap = sorted(pcmap.items(), key=operator.itemgetter(1), reverse=True)
|
|
pcmap = [(hex(addr), count) for addr, count in pcmap]
|