Use delta delays for baremetal application

Baremetal application uses systick to poll the Ethos-U PMU block for
profiling data. Instead of using a periodical timer, the timer is
now reset at the end of every poll. This will reduce the risk of
"systick deadlock" where the timing for handling the systick is longer
than the time of the periodic tick.

Change-Id: Ie812fab151b33d10bdf1cb4c5fb3e4fcbd5f1b05
diff --git a/applications/baremetal/main.cpp b/applications/baremetal/main.cpp
index 6ed7cbe..d27e4a4 100644
--- a/applications/baremetal/main.cpp
+++ b/applications/baremetal/main.cpp
@@ -78,7 +78,7 @@
                                                   ethosu_pmu_event_type(ETHOSU_PMU_EVENT_2),
                                                   ethosu_pmu_event_type(ETHOSU_PMU_EVENT_3)};
 
-const uint32_t delayMs = SystemCoreClock / 1000ul;
+const uint32_t delay = 250ul;
 struct ethosu_driver *ethosuDrv;
 EthosUMonitor ethosuMonitor(EthosUMonitor::Backend::EVENT_RECORDER);
 } // namespace
@@ -86,15 +86,19 @@
 extern "C" {
 
 void SysTick_Handler(void) {
+    // Disable systick, preventing new systick interrupt to fire while we call the Ethos-U monitor
+    SysTick->CTRL = 0;
+
     ethosuMonitor.monitorSample(ethosuDrv);
+
+    // Restart the systick timer
+    SysTick_Config(delay);
 }
 
 void ethosu_inference_begin(struct ethosu_driver *drv, void *) {
     ethosuDrv = drv;
     ethosuMonitor.configure(drv, pmuEventConfig);
-
-    // Enable polling
-    SysTick_Config(delayMs);
+    SysTick_Config(delay);
 }
 
 void ethosu_inference_end(struct ethosu_driver *drv, void *) {
@@ -121,6 +125,7 @@
     bool failed = inferenceProcess.runJob(job);
     printf("Status of executed job: ");
     printf(failed ? "Failed\n" : "Success\n");
+    printf("Performance monitor merge count %zu\n", ethosuMonitor.getMergeCount());
 
     return failed;
 }