nshell/src/main.c

219 lines
5.6 KiB
C
Raw Normal View History

2021-09-12 20:34:21 +02:00
#include <printf.h>
#include <setjmp.h>
#include <unistd.h>
2021-09-09 23:43:50 +02:00
2021-09-08 22:16:40 +02:00
#include <gint/cpu.h>
2021-09-02 19:07:14 +02:00
#include <gint/display.h>
2021-09-02 19:41:13 +02:00
#include <gint/drivers/r61524.h>
2021-09-01 18:25:59 +02:00
#include <gint/gint.h>
2021-08-31 15:52:53 +02:00
#include <gint/keyboard.h>
2021-09-10 00:48:53 +02:00
#include <gint/kmalloc.h>
2021-09-08 22:16:40 +02:00
#include <gint/mpu/power.h>
2021-08-31 15:52:53 +02:00
#include <gint/timer.h>
2021-09-02 19:07:14 +02:00
#include "battery.h"
2021-09-12 20:34:21 +02:00
#include "job.h"
2021-08-31 15:52:53 +02:00
#include "term.h"
2021-09-01 11:04:31 +02:00
#include "ui.h"
2021-09-19 20:52:05 +02:00
#include "vfs/vfs.h"
2021-09-12 20:34:21 +02:00
#include "wren_utils.h"
2021-09-10 00:48:53 +02:00
2021-09-10 20:27:06 +02:00
static int tick_ctr = 0;
static int shift_state = 0;
static int alpha_state = 0;
static int off_state = 0;
static volatile int must_redraw;
2021-09-12 20:34:21 +02:00
static int timer_redraw;
2021-09-10 20:27:06 +02:00
static int callback_redraw(void) {
must_redraw = 1;
return TIMER_CONTINUE;
}
2021-09-12 20:34:21 +02:00
volatile int must_yield;
jmp_buf sched_ctxbuf;
static int timer_sched;
static int callback_sched(void) {
must_yield = 1;
return TIMER_CONTINUE;
}
2021-09-10 20:27:06 +02:00
static void check_keyevents(void) {
static uint16_t backlight_save;
key_event_t kev = pollevent();
if (kev.type != KEYEV_DOWN)
return;
if (off_state) {
if (kev.key != KEY_ACON)
return;
off_state = 0;
// reset backlight
r61524_set(0x5a1, backlight_save & 0x00ff);
timer_start(timer_redraw);
}
2021-09-10 23:12:01 +02:00
term_kprintf("key event: key=0x%x mod=%d shift=%d alpha=%d", kev.key, kev.mod, kev.shift, kev.alpha);
2021-09-10 20:27:06 +02:00
if (kev.key == KEY_SHIFT)
shift_state = !shift_state;
2021-08-31 15:52:53 +02:00
2021-09-10 20:27:06 +02:00
if (kev.key == KEY_ALPHA)
alpha_state = !alpha_state;
if (kev.key == KEY_ACON && shift_state) {
timer_pause(timer_redraw);
off_state = 1;
// save, then turn backlight level off:
// force to display something
dclear(C_WHITE);
dupdate();
// store the backlight pwm
backlight_save = r61524_get(0x5a1) & 0x00ff;
// force vram clear
dclear(C_BLACK);
dupdate();
dclear(C_BLACK);
dupdate();
// force backlight pwm to 0
r61524_set(0x5a1, 0);
shift_state = 0;
alpha_state = 0;
return;
}
if (kev.key == KEY_MENU && !shift_state && !alpha_state) {
// TODO: print pause menu
gint_osmenu();
}
}
2021-09-18 12:25:58 +02:00
__attribute__((noreturn)) static void halt(void) {
2021-09-17 20:40:31 +02:00
term_kprint("SYSTEM HALTED");
set_statusbar(tick_ctr, shift_state, alpha_state, get_battery_voltage());
set_menubar();
dclear(C_BLACK);
tgrid_display();
dupdate();
while (1) {
getkey();
}
}
2021-09-12 20:34:21 +02:00
int main(int isappli, int optnum) {
term_kprintf("main(%d, %d)", isappli, optnum);
2021-09-19 20:52:05 +02:00
vfs_init();
halt();
2021-09-12 20:34:21 +02:00
timer_sched = timer_configure(TIMER_ANY, 10 * 1000, GINT_CALL(callback_sched)); // 100 Hz <=> 10 ms
2021-09-09 23:43:50 +02:00
2021-09-10 20:27:06 +02:00
timer_redraw = timer_configure(TIMER_ANY, 31250, GINT_CALL(callback_redraw)); // 32 Hz
timer_start(timer_redraw);
2021-09-01 14:24:10 +02:00
2021-09-12 20:34:21 +02:00
// start a few jobs
2021-09-13 23:17:06 +02:00
job_start("test_job_1", "System.print(\"inner start\")\n"
"var i = 0\n"
"while (i < 30000) {\n"
" if ((i % 500) == 0) {\n"
" System.write(\"vm 1: i=%(i)\\n\")\n"
" }\n"
" i = i + 1\n"
"}\n"
"System.print(\"inner end\")\n");
job_start("test_job_2", "System.print(\"inner start\")\n"
"var i = 0\n"
"while (i < 30000) {\n"
" if ((i % 500) == 0) {\n"
" System.write(\"vm 2: i=%(i)\\n\")\n"
" }\n"
" i = i + 1\n"
"}\n"
"System.print(\"inner end\")\n");
2021-09-12 20:34:21 +02:00
2021-09-15 18:59:59 +02:00
job_start("test_job_3", "System.print(\"inner start\")\n"
"var i = 0\n"
"while (i < 30000) {\n"
" if ((i % 500) == 0) {\n"
" System.write(\"vm 3: i=%(i)\\n\")\n"
" }\n"
" i = i + 1\n"
"}\n"
"System.print(\"inner end\")\n");
2021-08-31 15:52:53 +02:00
while (1) {
2021-09-12 20:34:21 +02:00
// system routine
2021-09-10 20:27:06 +02:00
check_keyevents();
if (off_state) {
sleep();
continue;
}
2021-09-02 19:04:01 +02:00
2021-09-12 20:34:21 +02:00
tick_ctr++;
2021-09-10 20:27:06 +02:00
if (must_redraw) {
2021-09-12 21:18:01 +02:00
set_statusbar(tick_ctr, shift_state, alpha_state, get_battery_voltage());
2021-09-01 14:28:01 +02:00
set_menubar();
2021-09-02 19:04:01 +02:00
2021-09-10 20:27:06 +02:00
dclear(C_BLACK);
2021-09-01 14:28:01 +02:00
tgrid_display();
2021-09-10 20:27:06 +02:00
dupdate();
2021-09-01 14:24:10 +02:00
2021-09-10 20:27:06 +02:00
must_redraw = 0;
2021-09-01 14:24:10 +02:00
}
2021-09-10 20:27:06 +02:00
2021-09-12 20:34:21 +02:00
// scheduler routine
next_job();
if (current_job_id < 0) {
term_kprint("all jobs ended");
break;
}
// first, backup current scheduler context
const int ret = setjmp(sched_ctxbuf);
2021-09-17 20:40:31 +02:00
switch (ret) {
case 0:
2021-09-12 20:34:21 +02:00
// resume job
timer_start(timer_sched);
must_yield = 0;
job_resume(current_job_id);
2021-09-17 20:40:31 +02:00
break;
case 1:
// term_kprintf("job(%d) yield", current_job_id);
2021-09-18 12:26:36 +02:00
// pause timer during sheduler operations, we restart it before resuming a job
timer_pause(timer_sched);
// force garbage collect after each cycle
2021-09-15 18:59:59 +02:00
job_GC(current_job_id);
2021-09-12 20:34:21 +02:00
continue;
2021-09-17 20:40:31 +02:00
break;
case 2:
2021-09-12 20:34:21 +02:00
term_kprintf("job(%d) exit", current_job_id);
job_free(current_job_id);
2021-09-17 20:40:31 +02:00
break;
default:
2021-09-12 20:34:21 +02:00
__builtin_unreachable();
term_kprint("SHOULD NOT BE REACHED!!!");
2021-09-17 20:40:31 +02:00
halt();
2021-09-12 20:34:21 +02:00
}
2021-08-31 15:52:53 +02:00
}
2021-09-17 20:40:31 +02:00
halt();
2021-09-12 20:34:21 +02:00
2021-08-31 15:52:53 +02:00
return 1;
}