Simulator cleanup

This commit is contained in:
Phil Hord 2013-11-08 22:32:40 -05:00 committed by Markus Hitter
parent c5871d0303
commit 3ff7e86728
4 changed files with 30 additions and 14 deletions

View File

@ -4,8 +4,15 @@
#ifdef SIMULATOR #ifdef SIMULATOR
#define CLI_SEI_BUG_MEMORY_BARRIER() #define CLI_SEI_BUG_MEMORY_BARRIER()
#define MEMORY_BARRIER() #define MEMORY_BARRIER()
#define ATOMIC_START
#define ATOMIC_END #define ATOMIC_START { \
uint8_t save_reg = sim_interrupts; \
cli();
#define ATOMIC_END MEMORY_BARRIER(); \
if (save_reg) sei(); \
}
#else #else
#include <util/atomic.h> #include <util/atomic.h>
#include <avr/version.h> #include <avr/version.h>

View File

@ -139,6 +139,7 @@ extern uint16_t TCCR1A, TCCR1B;
enum { CS10 = 1 , OCIE1B = 3 }; enum { CS10 = 1 , OCIE1B = 3 };
#define TCNT1 (sim_tick_counter()) #define TCNT1 (sim_tick_counter())
void cli(void);
void sei(void); void sei(void);
#ifdef USE_WATCHDOG #ifdef USE_WATCHDOG
@ -155,9 +156,7 @@ void sim_timer_init(void);
void sim_timer_stop(void); void sim_timer_stop(void);
void sim_setTimer(void); void sim_setTimer(void);
uint16_t sim_tick_counter(void); uint16_t sim_tick_counter(void);
uint64_t sim_runtime_ns(void); ///< Simulated run-time in nanoseconds
inline void cli(void);
inline void cli() { }
#define DIO0_PIN "proof of life" #define DIO0_PIN "proof of life"

View File

@ -126,6 +126,10 @@ void sei(void) {
sim_interrupts = true; sim_interrupts = true;
} }
void cli(void) {
sim_interrupts = false;
}
/* -- PIN I/O ------------------------------------------------------------ */ /* -- PIN I/O ------------------------------------------------------------ */

View File

@ -23,7 +23,7 @@ enum {
static volatile uint8_t timer_reason; // Who scheduled this timer static volatile uint8_t timer_reason; // Who scheduled this timer
static uint64_t now_us(void) { static uint64_t now_ns(void) {
struct timespec tv; struct timespec tv;
int n = clock_gettime(CLOCK_MONOTONIC, &tv); int n = clock_gettime(CLOCK_MONOTONIC, &tv);
@ -33,9 +33,12 @@ static uint64_t now_us(void) {
uint64_t nsec = tv.tv_sec; uint64_t nsec = tv.tv_sec;
nsec *= 1000 * 1000 * 1000; nsec *= 1000 * 1000 * 1000;
nsec += tv.tv_nsec; nsec += tv.tv_nsec;
return nsec;
}
static uint64_t now_us(void) {
// nanoseconds to microseconds // nanoseconds to microseconds
return nsec / 1000; return now_ns() / 1000;
} }
uint16_t sim_tick_counter(void) { uint16_t sim_tick_counter(void) {
@ -47,7 +50,7 @@ extern uint8_t clock_counter_10ms, clock_counter_250ms, clock_counter_1s;
static uint64_t begin; static uint64_t begin;
static uint64_t then; static uint64_t then;
void sim_timer_init(void) { void sim_timer_init(void) {
then = begin = now_us(); then = begin = now_ns();
sim_info("timer_init"); sim_info("timer_init");
timer_initialised = true; timer_initialised = true;
@ -59,6 +62,10 @@ void sim_timer_stop(void) {
timer_reason = 0; // Cancel pending timer; timer_reason = 0; // Cancel pending timer;
} }
uint64_t sim_runtime_ns(void) {
return (now_ns() - begin) / TIME_SLOW_FACTOR;
}
static void timer1_isr(int cause, siginfo_t *HowCome, void *ucontext) { static void timer1_isr(int cause, siginfo_t *HowCome, void *ucontext) {
if ( ! sim_interrupts) { if ( ! sim_interrupts) {
// Interrupts disabled. Schedule another callback in 10us. // Interrupts disabled. Schedule another callback in 10us.
@ -66,17 +73,17 @@ static void timer1_isr(int cause, siginfo_t *HowCome, void *ucontext) {
return; return;
} }
sim_interrupts = false; cli();
#ifdef SIM_DEBUG #ifdef SIM_DEBUG
uint64_t now = now_us(); uint64_t now = now_ns();
static unsigned int cc_1s = 0, prev_1s = 0; static unsigned int cc_1s = 0, prev_1s = 0;
if ( ! clock_counter_1s && prev_1s) ++cc_1s; if ( ! clock_counter_1s && prev_1s) ++cc_1s;
prev_1s = clock_counter_1s; prev_1s = clock_counter_1s;
//uint16_t now = sim_tick_counter(); //uint16_t now = sim_tick_counter();
uint64_t real = now-begin; uint64_t real = (now-begin) / 1000;
uint64_t avr = cc_1s * 4 + clock_counter_1s; uint64_t avr = cc_1s * 4 + clock_counter_1s;
avr *= 250; avr *= 250;
avr += clock_counter_250ms * 10; avr += clock_counter_250ms * 10;
@ -86,7 +93,7 @@ static void timer1_isr(int cause, siginfo_t *HowCome, void *ucontext) {
real / 1000000 , (real % 1000000)/1000 , real % 1000 , real / 1000000 , (real % 1000000)/1000 , real % 1000 ,
avr / 1000000 , (avr % 1000000)/1000 , avr % 1000 , avr / 1000000 , (avr % 1000000)/1000 , avr % 1000 ,
real / (avr?avr:1) ); real / (avr?avr:1) );
printf("test: 10ms=%u 250ms=%u 1s=%u total=%lu actual=%lu\n", printf("test: 10ms=%u 250ms=%u 1s=%u total=%luns actual=%luns\n",
clock_counter_10ms, clock_counter_250ms, clock_counter_1s, clock_counter_10ms, clock_counter_250ms, clock_counter_1s,
now - begin , now - then); now - begin , now - then);
//printf(" timer1_isr tick_time=%04X now=%04X delta=%u total=%u\n", //printf(" timer1_isr tick_time=%04X now=%04X delta=%u total=%u\n",
@ -98,13 +105,12 @@ static void timer1_isr(int cause, siginfo_t *HowCome, void *ucontext) {
if (timer_reason & TIMER_OCR1B) TIMER1_COMPB_vect(); if (timer_reason & TIMER_OCR1B) TIMER1_COMPB_vect();
timer_reason = 0; timer_reason = 0;
sim_interrupts = true; sei();
// Setup next timer // Setup next timer
sim_setTimer(); sim_setTimer();
} }
// TODO: Remove 'delay' value and use AVR regs instead
void sim_setTimer() { void sim_setTimer() {
// Set callbacks for COMPA and COMPB timers // Set callbacks for COMPA and COMPB timers
uint32_t nextA = 0, nextB = 0; uint32_t nextA = 0, nextB = 0;