diff options
author | Paul Selkirk <paul@psgd.org> | 2017-09-07 18:17:12 -0400 |
---|---|---|
committer | Paul Selkirk <paul@psgd.org> | 2017-09-07 18:20:55 -0400 |
commit | 72227852729ed3125af58cff3f593340b3247fed (patch) | |
tree | 234d45ae587ce51bfbbce6d8c059a121a44bf1e6 /libraries/libprof | |
parent | 2e1f88062c7ec6cd12688ce7522e802bbf09bba1 (diff) | |
parent | 5ff8c9512db48d128cf07904f68eb5139bebf952 (diff) |
Rebase branch 'profiling' from master
Diffstat (limited to 'libraries/libprof')
-rw-r--r-- | libraries/libprof/README.txt | 2 | ||||
-rw-r--r-- | libraries/libprof/profil.c | 17 |
2 files changed, 11 insertions, 8 deletions
diff --git a/libraries/libprof/README.txt b/libraries/libprof/README.txt index 1fe378c..f0b8ee8 100644 --- a/libraries/libprof/README.txt +++ b/libraries/libprof/README.txt @@ -52,7 +52,7 @@ In the OpenOCD console, enable semihosting: In another window, start the debugger: - $ sw/stm32/bin/debug projects/hsm/hsm + $ ../../bin/debug hsm In the CLI, type `profile start`, then start the unit test or whatever will be exercising the hsm. Afterwards, in the CLI, type `profile stop`. diff --git a/libraries/libprof/profil.c b/libraries/libprof/profil.c index 0654879..b0d8d55 100644 --- a/libraries/libprof/profil.c +++ b/libraries/libprof/profil.c @@ -25,27 +25,30 @@ static struct profinfo prof = { PROFILE_NOT_INIT, 0, 0, 0, 0 }; -extern void set_SysTick_hook(void (*hook)(void)); - /* sample the current program counter */ -static void SysTick_hook(void) { - size_t pc = (size_t)((uint32_t *)__get_MSP())[8]; - if (pc >= prof.lowpc && pc < prof.highpc) { +void profil_callback(void) { + if (prof.state == PROFILE_ON) { + /* The interrupt mechanism pushes xPSR, PC, LR, R12, and R3-R0 onto the + * stack, so PC is the 6th word from the top at that point. However, the + * normal function entry code pushes registers as well, so the stack + * offset right now depends on the call tree that got us here. + */ + size_t pc = (size_t)((uint32_t *)__get_MSP())[6 + 6]; + if (pc >= prof.lowpc && pc < prof.highpc) { size_t idx = PROFIDX (pc, prof.lowpc, prof.scale); prof.counter[idx]++; + } } } /* Stop profiling to the profiling buffer pointed to by p. */ static int profile_off (struct profinfo *p) { - set_SysTick_hook(NULL); p->state = PROFILE_OFF; return 0; } /* Create a timer thread and pass it a pointer P to the profiling buffer. */ static int profile_on (struct profinfo *p) { - set_SysTick_hook(SysTick_hook); p->state = PROFILE_ON; return 0; /* ok */ } |