#include "stdio.h" #include "sys/time.h" #include "errno.h" #include "pthread.h" #include "timer.h" #define BASE_ADDR 0x40001000 #define SIZE 0x4 void milliseconds_sleep(unsigned long mSec){ struct timeval tv; tv.tv_sec=mSec/1000; tv.tv_usec=(mSec%1000)*1000; int err; do{ err=select(0,NULL,NULL,NULL,&tv); }while(err<0 && errno==EINTR); } #define dev_wr(addr) g_map[(addr-BASE_ADDR) >> 2] #define dev_wrb(addr) ((uint8_t *)g_map)[(addr-BASE_ADDR)] #define dev_wrh(addr) ((uint16_t *)g_map)[(addr-BASE_ADDR) >> 1] static uint32_t g_map[1]; static uint32_t read(uint32_t addr) { if (!(addr & 0x3)) { return dev_wr(addr); } else if (!(addr & 0x1)) { return dev_wrh(addr); } else { return dev_wrb(addr); } } static void write(uint32_t addr, uint32_t data) { // printf("print: write data=%x\n", data); if (!(addr & 0x3)) { dev_wr(addr) = data; } else if (!(addr & 0x1)) { dev_wrh(addr) = data; } else { dev_wrb(addr) = data; } } typedef struct { uint32_t ins_count; pthread_mutex_t lock; /* 互斥锁定义 */ } mtimer_t; static mtimer_t g_self; static void run(riscv_t *riscv, const struct device_t* device) { int irq = 0; // printf("timer_run...\n"); pthread_mutex_lock(&g_self.lock); dev_wr(BASE_ADDR) += g_self.ins_count; if (g_self.ins_count) { irq = 1; } g_self.ins_count = 0; pthread_mutex_unlock(&g_self.lock); if (irq) { riscv->mip |= MIP_MTIP; } } static void *timer_thread(void *arg) { while (1) { milliseconds_sleep(1); pthread_mutex_lock(&g_self.lock); g_self.ins_count++; pthread_mutex_unlock(&g_self.lock); } return NULL; } static void init(const struct device_t* device) { pthread_t tid; pthread_mutex_init(&g_self.lock, NULL); dev_wr(BASE_ADDR) = 0x0; pthread_create(&tid, NULL, timer_thread, NULL); } const static device_t g_timer = { .addr = BASE_ADDR, .size = SIZE, .read = read, .write = write, .run = run, .init = init, }; const device_t* timer_dev() { return &g_timer; }