From 31347cddceafb4e9775d9f51b268091409adee72 Mon Sep 17 00:00:00 2001 From: arighi Date: Fri, 19 Mar 2010 14:30:08 +0000 Subject: [PATCH] demo: make the GUI preemptive-safe. Protect all the GUI operations, setting them as atomic, in order to make them work correctly also with the preemptible kernel. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3248 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/cpu/frame.h | 4 +- bertos/drv/kbd.c | 4 +- bertos/drv/wdt.h | 6 +- bertos/emul/emul.cpp | 1 - bertos/kern/idle.c | 2 +- examples/demo/demo.c | 143 +++++++++++++++++++++++-------------------- 6 files changed, 80 insertions(+), 80 deletions(-) diff --git a/bertos/cpu/frame.h b/bertos/cpu/frame.h index 6c968649..4d78a3c3 100644 --- a/bertos/cpu/frame.h +++ b/bertos/cpu/frame.h @@ -212,9 +212,9 @@ #if defined(ARCH_QT) && (ARCH & ARCH_QT) /* This emulator hook should yield the CPU to the host. */ EXTERN_C_BEGIN - void emul_idle(void); + void refresh(void); EXTERN_C_END - #define CPU_IDLE emul_idle() + #define CPU_IDLE refresh() #else /* !ARCH_EMUL */ #define CPU_IDLE do { /* nothing */ } while (0) #endif /* !ARCH_EMUL */ diff --git a/bertos/drv/kbd.c b/bertos/drv/kbd.c index 3d1eca45..3334deb2 100644 --- a/bertos/drv/kbd.c +++ b/bertos/drv/kbd.c @@ -178,9 +178,7 @@ keymask_t kbd_peek(void) keymask_t key = 0; #if CONFIG_KBD_SCHED - /* Let other tasks run for a while */ - extern void schedule(void); - schedule(); + timer_delay(1); #endif /* Extract an event from the keyboard buffer */ diff --git a/bertos/drv/wdt.h b/bertos/drv/wdt.h index bafb8fb8..89752bf7 100644 --- a/bertos/drv/wdt.h +++ b/bertos/drv/wdt.h @@ -77,11 +77,7 @@ INLINE void wdt_reset(void) { #if CONFIG_WATCHDOG - #if OS_QT - // Let Qt handle events - ASSERT(qApp); - qApp->processEvents(); - #elif OS_POSIX + #if OS_POSIX static struct timeval tv = { 0, 0 }; select(0, NULL, NULL, NULL, &tv); #endif diff --git a/bertos/emul/emul.cpp b/bertos/emul/emul.cpp index 6327a5bf..7e1da2ed 100644 --- a/bertos/emul/emul.cpp +++ b/bertos/emul/emul.cpp @@ -101,6 +101,5 @@ extern "C" void emul_idle() { // We process GUI events when the application is idle. emul->emulApp->processEvents(); - usleep(1000); } diff --git a/bertos/kern/idle.c b/bertos/kern/idle.c index 7ba8d617..592d17b1 100644 --- a/bertos/kern/idle.c +++ b/bertos/kern/idle.c @@ -64,7 +64,7 @@ static NORETURN void idle(void) { for (;;) { - PAUSE; + CPU_IDLE; proc_switch(); } } diff --git a/examples/demo/demo.c b/examples/demo/demo.c index b5b2ca04..e3c334c5 100644 --- a/examples/demo/demo.c +++ b/examples/demo/demo.c @@ -59,15 +59,14 @@ #include /** - * Draw a pentacle in the provided bitmap. - * - * This is invoked by the keyboard polling routine, as a poor man's surrogate - * of true task switching. + * Refresh the GUI. */ -void schedule(void) +void refresh(void) { - lcd_blitBitmap(&lcd_bitmap); - emul_idle(); + PROC_ATOMIC( + lcd_blitBitmap(&lcd_bitmap); + emul_idle(); + ); } /** @@ -86,21 +85,28 @@ static void magic(struct Bitmap *bitmap, coord_t x, coord_t y) static void hello_world(Bitmap *bm) { extern const Font font_ncenB18; - const Font *old_font = bm->font; + const Font *old_font; + + PROC_ATOMIC( + old_font = bm->font; + + gfx_bitmapClear(bm); - gfx_bitmapClear(bm); + /* Set big font */ + gfx_setFont(bm, &font_ncenB18); - /* Set big font */ - gfx_setFont(bm, &font_ncenB18); + text_xprintf(bm, 1, 0, STYLEF_BOLD | TEXT_FILL | TEXT_CENTER, + "Hello, world!"); - text_xprintf(bm, 1, 0, STYLEF_BOLD | TEXT_FILL | TEXT_CENTER, - "Hello, world!"); + lcd_blitBitmap(bm); + ); - lcd_blitBitmap(bm); timer_delay(1000); - /* Restore old font */ - gfx_setFont(bm, old_font); + PROC_ATOMIC( + /* Restore old font */ + gfx_setFont(bm, old_font); + ); } /** @@ -131,13 +137,14 @@ static void bouncing_logo(Bitmap *bm) } /* Update graphics */ - gfx_bitmapClear(bm); - gfx_blitImage(bm, - (bm->width - bertos_logo.width) / 2, - h / SPEED_SCALE, - &bertos_logo); - lcd_blitBitmap(bm); - + PROC_ATOMIC( + gfx_bitmapClear(bm); + gfx_blitImage(bm, + (bm->width - bertos_logo.width) / 2, + h / SPEED_SCALE, + &bertos_logo); + lcd_blitBitmap(bm); + ); timer_delay(10); } } @@ -174,51 +181,51 @@ void win_demo(Bitmap *bm) for(;;) { - /* Background animation */ - bm = root_win.bitmap; - gfx_bitmapClear(bm); -// gfx_setClipRect(bm, 0, 0, bm->width, bm->height); -// gfx_rectDraw(bm, 10, 10, bm->width-10, bm->height-10); -// gfx_setClipRect(bm, 11, 11, bm->width-11, bm->height-11); - magic(bm, x, y); - x += xdir; - y += ydir; - if (x >= bm->width) xdir = -1; - if (x <= -50) xdir = +1; - if (y >= bm->height) ydir = -1; - if (y <= -50) ydir = +1; - - /* Large window animation */ - bm = large_win.bitmap; - gfx_bitmapClear(bm); - for (i = 0; i < bm->height / 2; i += 2) - gfx_rectDraw(bm, 0 + i, 0 + i, bm->width - i, bm->height - i); - - - /* Small window animation */ - bm = small_win.bitmap; - gfx_bitmapClear(bm); - gfx_rectDraw(bm, 0, 0, bm->width, bm->height); - gfx_line(bm, 0, 0, bm->width, bm->height); - gfx_line(bm, bm->width, 0, 0, bm->height); - - /* Move windows around */ - win_move(&large_win, large_win.geom.xmin + xdir_large, large_top); - if (large_win.geom.xmin < -20) xdir_large = +1; - if (large_win.geom.xmin > RECT_WIDTH(&root_win.geom) - 5) xdir_large = -1; - - win_move(&small_win, small_left, small_win.geom.ymin + ydir_small); - if (small_win.geom.ymin < -20) ydir_small = +1; - if (small_win.geom.ymin > RECT_HEIGHT(&root_win.geom) - 5) ydir_small = -1; - - ++raise_counter; - if (raise_counter % 997 == 0) - win_raise(&small_win); - else if (raise_counter % 731 == 0) - win_raise(&large_win); - - win_compose(&root_win); - + PROC_ATOMIC( + /* Background animation */ + bm = root_win.bitmap; + gfx_bitmapClear(bm); + // gfx_setClipRect(bm, 0, 0, bm->width, bm->height); + // gfx_rectDraw(bm, 10, 10, bm->width-10, bm->height-10); + // gfx_setClipRect(bm, 11, 11, bm->width-11, bm->height-11); + magic(bm, x, y); + x += xdir; + y += ydir; + if (x >= bm->width) xdir = -1; + if (x <= -50) xdir = +1; + if (y >= bm->height) ydir = -1; + if (y <= -50) ydir = +1; + + /* Large window animation */ + bm = large_win.bitmap; + gfx_bitmapClear(bm); + for (i = 0; i < bm->height / 2; i += 2) + gfx_rectDraw(bm, 0 + i, 0 + i, bm->width - i, bm->height - i); + + /* Small window animation */ + bm = small_win.bitmap; + gfx_bitmapClear(bm); + gfx_rectDraw(bm, 0, 0, bm->width, bm->height); + gfx_line(bm, 0, 0, bm->width, bm->height); + gfx_line(bm, bm->width, 0, 0, bm->height); + + /* Move windows around */ + win_move(&large_win, large_win.geom.xmin + xdir_large, large_top); + if (large_win.geom.xmin < -20) xdir_large = +1; + if (large_win.geom.xmin > RECT_WIDTH(&root_win.geom) - 5) xdir_large = -1; + + win_move(&small_win, small_left, small_win.geom.ymin + ydir_small); + if (small_win.geom.ymin < -20) ydir_small = +1; + if (small_win.geom.ymin > RECT_HEIGHT(&root_win.geom) - 5) ydir_small = -1; + + ++raise_counter; + if (raise_counter % 997 == 0) + win_raise(&small_win); + else if (raise_counter % 731 == 0) + win_raise(&large_win); + + win_compose(&root_win); + ); /* Also does LCD refresh, etc. */ if (kbd_peek()) break; -- 2.25.1