Last active
June 8, 2023 15:33
-
-
Save ynsta/7df418cb27b908391f86 to your computer and use it in GitHub Desktop.
Statistic profiling on stm32f4 with openocd by dwt_pcsr sampling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python2 | |
# run openocd (0.9.0) with : | |
# $ openocd -f stlink-v2-1.cfg -f stm32f4x.cfg &> /dev/null" | |
# then run | |
# $ python2 sampler.py path_to_myelf_with_symbols | |
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('exit\r\n') | |
self.net.read_until('exit\r\n', 1) | |
self.net.close() | |
def getpc(self): | |
self.net.write('mrw 0xE000101C\r\n') | |
res = self.net.read_until('\r\n\r> ', 1) | |
if res: | |
prefix = res[0:16] | |
num = res[16:-5] | |
res = res[-15:0] | |
if prefix == 'mrw 0xE000101C\r\n': | |
return int(num) | |
return 0 | |
def initSymbols(self, elf, readelf='readelf'): | |
proc = subprocess.Popen([readelf, '-s', elf], stdout=subprocess.PIPE) | |
for line in iter(proc.stdout.readline, ''): | |
field = line.split() | |
try: | |
if field[3] == 'FUNC': | |
addr = int(field[1], 16) | |
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 = { } | |
start = time.time() | |
try: | |
while True: | |
func, addr = sampler.func((sampler.getpc())) | |
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) | |
start = cur | |
print '' | |
except KeyboardInterrupt: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's an improved version! https://github.com/lijon/cortex-profiler