Skip to content

Commit

Permalink
Run scheduler at realtime
Browse files Browse the repository at this point in the history
  • Loading branch information
pipe01 committed Dec 15, 2024
1 parent e90adae commit 32c69a0
Show file tree
Hide file tree
Showing 9 changed files with 26 additions and 38 deletions.
7 changes: 1 addition & 6 deletions frontend/desktop/emulator/emulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,12 +414,7 @@ func (e *Emulator) perfLoop() {
rtc.update(interval)
}

var instCounter uint64
if e.currentRunMode == RunModeLoop {
instCounter = uint64(C.inst_counter)
} else {
instCounter = uint64(C.scheduler_get_counter(e.sched))
}
instCounter := uint64(C.nrf52832_get_cycle_counter(e.nrf52))

e.instPerSecond = (1e6 * (instCounter - lastCounter)) / uint64(interval.Microseconds())
lastCounter = instCounter
Expand Down
2 changes: 1 addition & 1 deletion frontend/desktop/emulator/pinetime.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package emulator

const BaseFrequencyHZ = 18_000_000
const BaseFrequencyHZ = 64_000_000

const (
PinCharging = 12
Expand Down
2 changes: 1 addition & 1 deletion include/nrf52832.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ typedef struct NRF52832_inst_t NRF52832_t;

NRF52832_t *nrf52832_new(const program_t *flash, size_t sram_size);
void nrf52832_reset(NRF52832_t *);
void nrf52832_step(NRF52832_t *);
int nrf52832_step(NRF52832_t *);

cpu_t *nrf52832_get_cpu(NRF52832_t *);
bus_spi_t *nrf52832_get_spi(NRF52832_t *);
Expand Down
2 changes: 1 addition & 1 deletion include/pinetime.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ typedef struct pinetime_t pinetime_t;
pinetime_t *pinetime_new(const program_t *program);
void pinetime_free(pinetime_t *);
void pinetime_reset(pinetime_t *);
void pinetime_step(pinetime_t *);
int pinetime_step(pinetime_t *);

NRF52832_t *pinetime_get_nrf52832(pinetime_t *);
st7789_t *pinetime_get_st7789(pinetime_t *);
Expand Down
1 change: 0 additions & 1 deletion include/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@ typedef struct scheduler_t scheduler_t;
scheduler_t *scheduler_new(scheduler_cb_t cb, void *userdata, size_t target_hz);
void scheduler_run(scheduler_t *);
void scheduler_stop(scheduler_t *);
uint64_t scheduler_get_counter(scheduler_t *);
void scheduler_set_frequency(scheduler_t *, size_t target_hz);
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ set(WASM_EXPORTS
pinetime_new pinetime_step pinetime_loop pinetime_reset
pinetime_get_st7789 st7789_read_screen_rgba st7789_is_sleeping st7789_get_write_count st7789_is_sleeping
pinetime_get_cst816s cst816s_do_touch cst816s_release_touch
pinetime_get_nrf52832 nrf52832_get_sram_size nrf52832_get_pins pins_set pins_clear
pinetime_get_nrf52832 nrf52832_get_sram_size nrf52832_get_pins pins_set pins_clear pins_read_all
pinetime_get_spinorflash spinorflash_get_buffer spinorflash_get_buffer_size
nrf52832_get_cpu cpu_is_sleeping cpu_mem
program_new program_load_binary program_load_elf program_write_variable
Expand Down
4 changes: 3 additions & 1 deletion src/nrf52832.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void nrf52832_reset(NRF52832_t *nrf52832)
cpu_reset(nrf52832->cpu);
}

void nrf52832_step(NRF52832_t *nrf52832)
int nrf52832_step(NRF52832_t *nrf52832)
{
current_ppi = nrf52832->ppi;

Expand All @@ -184,6 +184,8 @@ void nrf52832_step(NRF52832_t *nrf52832)
nrf52832->cycle_counter += cycles;

ticker_hftick(nrf52832->ticker, cycles);

return cycles;
}

cpu_t *nrf52832_get_cpu(NRF52832_t *chip)
Expand Down
4 changes: 2 additions & 2 deletions src/pinetime.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ void pinetime_reset(pinetime_t *pt)
nrf52832_reset(pt->nrf);
}

void pinetime_step(pinetime_t *pt)
int pinetime_step(pinetime_t *pt)
{
nrf52832_step(pt->nrf);
return nrf52832_step(pt->nrf);
}

NRF52832_t *pinetime_get_nrf52832(pinetime_t *pt)
Expand Down
40 changes: 16 additions & 24 deletions src/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>

#include "ie_time.h"

#define SCHEDULER_HZ 50
#define US_PER_ITERATION 100000

struct scheduler_t
{
Expand All @@ -18,9 +19,7 @@ struct scheduler_t

bool stop;

size_t iteration_count, should_take_ns;

uint64_t counter;
size_t cycles_per_iteration;
};

scheduler_t *scheduler_new(scheduler_cb_t cb, void *userdata, size_t target_hz)
Expand All @@ -29,38 +28,37 @@ scheduler_t *scheduler_new(scheduler_cb_t cb, void *userdata, size_t target_hz)
scheduler->cb = cb;
scheduler->userdata = userdata;
scheduler->stop = false;

scheduler_set_frequency(scheduler, target_hz);

return scheduler;
}

void scheduler_run(scheduler_t *sched)
{
struct timespec ts_rem, ts_req = {0};
struct timespec ts_req = {0};

sched->stop = false;

ssize_t fuel;

while (!sched->stop)
{
// Copy variables here to prevent them from changing during the loop body
size_t iteration_count = sched->iteration_count;
size_t should_take_ns = sched->should_take_ns;
fuel = sched->cycles_per_iteration;

uint64_t start = microseconds_now();
uint64_t start = microseconds_now_real();

for (size_t i = 0; i < iteration_count; i++)
while (fuel > 0)
{
sched->counter += sched->cb(sched->userdata);
fuel -= sched->cb(sched->userdata);
}

size_t end = microseconds_now();
size_t elapsed_ns = (end - start) * 1e3;
uint64_t elapsed_us = microseconds_now_real() - start;

if (elapsed_ns < should_take_ns)
if (elapsed_us < US_PER_ITERATION)
{
ts_req.tv_nsec = should_take_ns - elapsed_ns;
nanosleep(&ts_req, &ts_rem);
ts_req.tv_nsec = (US_PER_ITERATION - elapsed_us) * 1000;
while (nanosleep(&ts_req, &ts_req));
}
}
}
Expand All @@ -70,13 +68,7 @@ void scheduler_stop(scheduler_t *sched)
sched->stop = true;
}

uint64_t scheduler_get_counter(scheduler_t *sched)
{
return sched->counter;
}

void scheduler_set_frequency(scheduler_t *sched, size_t target_hz)
{
sched->iteration_count = target_hz / SCHEDULER_HZ;
sched->should_take_ns = (1e9 * sched->iteration_count) / target_hz;
sched->cycles_per_iteration = (target_hz * US_PER_ITERATION) / 1000000;
}

0 comments on commit 32c69a0

Please sign in to comment.