demo: make the GUI preemptive-safe.
authorarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 19 Mar 2010 14:30:08 +0000 (14:30 +0000)
committerarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 19 Mar 2010 14:30:08 +0000 (14:30 +0000)
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
bertos/drv/kbd.c
bertos/drv/wdt.h
bertos/emul/emul.cpp
bertos/kern/idle.c
examples/demo/demo.c

index 6c9686491dfec74372af2cac12987d176fb8200f..4d78a3c37ae5d2d8866cd76efbb10de67589a757 100644 (file)
        #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 */
index 3d1eca4537dc2a256301f9178fe2c5aaa47e8e0e..3334deb216f280df623f8c48aef2fc8790ad904b 100644 (file)
@@ -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 */
index bafb8fb8cc4495dbef19ba74f66c65f9016a0816..89752bf7ac6a04625d390d64cd9cc3987ab1058b 100644 (file)
        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
index 6327a5bf0ca454e161b26c0de74e7cbbdbe60e9c..7e1da2ed9a8d2b01b3691ccf61a64d243b0552cc 100644 (file)
@@ -101,6 +101,5 @@ extern "C" void emul_idle()
 {
        // We process GUI events when the application is idle.
        emul->emulApp->processEvents();
-       usleep(1000);
 }
 
index 7ba8d617d34a4177860e77876774a5ccb33d6bf8..592d17b16401e2ca4e6699c3b0cdefb549124173 100644 (file)
@@ -64,7 +64,7 @@ static NORETURN void idle(void)
 {
        for (;;)
        {
-               PAUSE;
+               CPU_IDLE;
                proc_switch();
        }
 }
index b5b2ca0467903e08de90d9d02d7b26a53303ce24..e3c334c574cd84ac0331e346b6e2e91ed6f502cc 100644 (file)
 #include <icons/logo.h>
 
 /**
- * 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;