measure cpu load

This commit is contained in:
Andy Killorin 2025-04-03 12:02:50 -04:00
parent 1ec0f63696
commit 808d474ec3
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
2 changed files with 42 additions and 10 deletions

View file

@ -28,7 +28,6 @@ uint32_t gADCSamplingRate; // [Hz] actual ADC sampling rate
// imported globals // imported globals
extern uint32_t gSystemClock; // [Hz] system clock frequency extern uint32_t gSystemClock; // [Hz] system clock frequency
extern volatile uint32_t gTime; // time in hundredths of a second extern volatile uint32_t gTime; // time in hundredths of a second
extern volatile uint8_t drawRequested;
// initialize all button and joystick handling hardware // initialize all button and joystick handling hardware
void ButtonInit(void) void ButtonInit(void)

51
main.c
View file

@ -13,6 +13,7 @@
#include "driverlib/fpu.h" #include "driverlib/fpu.h"
#include "driverlib/sysctl.h" #include "driverlib/sysctl.h"
#include "driverlib/interrupt.h" #include "driverlib/interrupt.h"
#include "driverlib/timer.h"
#include "Crystalfontz128x128_ST7735.h" #include "Crystalfontz128x128_ST7735.h"
#include <stdio.h> #include <stdio.h>
#include "grlib/grlib.h" #include "grlib/grlib.h"
@ -28,7 +29,7 @@
uint32_t gSystemClock; // [Hz] system clock frequency uint32_t gSystemClock; // [Hz] system clock frequency
volatile uint32_t gTime = 0; // time in hundredths of a second volatile uint32_t gTime = 0; // time in hundredths of a second
volatile uint8_t drawRequested = 1; volatile uint8_t refresh = 1;
// assumming square lcd // assumming square lcd
#define HEIGHT LCD_VERTICAL_MAX #define HEIGHT LCD_VERTICAL_MAX
@ -48,6 +49,8 @@ const float gVoltageScale[VOLTAGE_SCALES] = {
0.1, 0.2, 0.5, 1., 2. 0.1, 0.2, 0.5, 1., 2.
}; };
uint32_t cputime_unloaded;
int RisingTrigger(void); int RisingTrigger(void);
// start a pwm test signal // start a pwm test signal
@ -72,6 +75,26 @@ void start_signal() {
PWMGenEnable(PWM0_BASE, PWM_GEN_1); PWMGenEnable(PWM0_BASE, PWM_GEN_1);
} }
uint32_t cpu_load_count(void)
{
uint32_t i = 0;
TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
TimerEnable(TIMER1_BASE, TIMER_A); // start one-shot timer
while (!(TimerIntStatus(TIMER1_BASE, false) & TIMER_TIMA_TIMEOUT))
i++;
return i;
}
void start_cputimer() {
// initialize timer 1 in one-shot mode for polled timing
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerDisable(TIMER1_BASE, TIMER_BOTH);
TimerConfigure(TIMER1_BASE, TIMER_CFG_ONE_SHOT);
TimerLoadSet(TIMER1_BASE, TIMER_A, gSystemClock/100); // 10ms interval
// baseline load
cputime_unloaded = cpu_load_count();
}
int main(void) { int main(void) {
IntMasterDisable(); IntMasterDisable();
@ -93,24 +116,33 @@ int main(void) {
#ifdef DISPLAY_TIME #ifdef DISPLAY_TIME
uint32_t time; // local copy of gTime uint32_t time; // local copy of gTime
char str[50]; // string buffer
#endif // DISPLAY_TIME #endif // DISPLAY_TIME
char str[50]; // string buffer
// full-screen rectangle // full-screen rectangle
tRectangle rectFullScreen = {0, 0, GrContextDpyWidthGet(&sContext)-1, GrContextDpyHeightGet(&sContext)-1}; tRectangle rectFullScreen = {0, 0, GrContextDpyWidthGet(&sContext)-1, GrContextDpyHeightGet(&sContext)-1};
ButtonInit(); ButtonInit();
start_cputimer();
IntMasterEnable(); IntMasterEnable();
uint8_t voltage_scale = 0; uint8_t voltage_scale = 0;
while (true) { while (true) {
// calculate cpu usage
uint32_t cputime_loaded;
cputime_loaded = cpu_load_count();
float usage_percent;
usage_percent = (1.0 - (float) cputime_loaded / (float) cputime_unloaded) * (float) 100.;
// handle buttons // handle buttons
Button button = (Button) 0; Button button = (Button) 0;
while (fifo_get(&button)) { while (fifo_get(&button)) {
switch (button) { switch (button) {
case S2: // draw case S2: // draw
drawRequested = 1; refresh = !refresh;
break; break;
case Up: // next scale case Up: // next scale
voltage_scale = (voltage_scale + 1) % VOLTAGE_SCALES; voltage_scale = (voltage_scale + 1) % VOLTAGE_SCALES;
@ -124,7 +156,6 @@ int main(void) {
GrContextForegroundSet(&sContext, ClrBlack); GrContextForegroundSet(&sContext, ClrBlack);
GrRectFill(&sContext, &rectFullScreen); // fill screen with black GrRectFill(&sContext, &rectFullScreen); // fill screen with black
GrContextForegroundSet(&sContext, ClrBlue); GrContextForegroundSet(&sContext, ClrBlue);
// draw gridlines from the center out // draw gridlines from the center out
@ -138,24 +169,26 @@ int main(void) {
} }
// info
GrContextForegroundSet(&sContext, ClrWheat);
GrStringDraw(&sContext, gVoltageScaleStr[voltage_scale], /*length*/ -1, /*x*/ 0, /*y*/ 0, /*opaque*/ false);
snprintf(str, sizeof(str), "CPU Load %.1f%%", usage_percent);
GrStringDraw(&sContext, str, /*length*/ -1, /*x*/ 0, /*y*/ HEIGHT - 10, /*opaque*/ false);
// display graph // display graph
#define LOCAL_BUF_LEN 128 #define LOCAL_BUF_LEN 128
uint16_t local_adc_buffer[LOCAL_BUF_LEN]; // copy of adc buffer uint16_t local_adc_buffer[LOCAL_BUF_LEN]; // copy of adc buffer
int32_t adc_current_index; int32_t adc_current_index;
int32_t j; int32_t j;
if (drawRequested) { if (refresh) {
int trigger = RisingTrigger(); int trigger = RisingTrigger();
adc_current_index = trigger - (WIDTH / 2); adc_current_index = trigger - (WIDTH / 2);
for (j=0; j<LOCAL_BUF_LEN; j++) { for (j=0; j<LOCAL_BUF_LEN; j++) {
local_adc_buffer[j] = gADCBuffer[ADC_BUFFER_WRAP(adc_current_index + j)]; local_adc_buffer[j] = gADCBuffer[ADC_BUFFER_WRAP(adc_current_index + j)];
} }
drawRequested = 0;
} }
GrContextForegroundSet(&sContext, ClrWheat);
GrStringDraw(&sContext, gVoltageScaleStr[voltage_scale], /*length*/ -1, /*x*/ 0, /*y*/ 0, /*opaque*/ false);
float fVoltsPerDiv = gVoltageScale[voltage_scale]; float fVoltsPerDiv = gVoltageScale[voltage_scale];
float fScale = (VIN_RANGE * PIXELS_PER_DIV)/((1 << ADC_BITS) * fVoltsPerDiv); float fScale = (VIN_RANGE * PIXELS_PER_DIV)/((1 << ADC_BITS) * fVoltsPerDiv);