diff --git a/examples/nxhello/Makefile b/examples/nxhello/Makefile index 85fe2cb0f..6acda7e42 100644 --- a/examples/nxhello/Makefile +++ b/examples/nxhello/Makefile @@ -1,7 +1,7 @@ ############################################################################ # apps/examples/nxhello/Makefile # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without diff --git a/examples/nxhello/nxhello.h b/examples/nxhello/nxhello.h index 1fd16d9e4..f55a63bf9 100644 --- a/examples/nxhello/nxhello.h +++ b/examples/nxhello/nxhello.h @@ -127,6 +127,7 @@ #ifndef CONFIG_EXAMPLES_NXHELLO_NOTIFYSIGNO # define CONFIG_EXAMPLES_NXHELLO_NOTIFYSIGNO 4 #endif + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/examples/nxhello/nxhello_main.c b/examples/nxhello/nxhello_main.c index a0783d8fa..688f403bc 100644 --- a/examples/nxhello/nxhello_main.c +++ b/examples/nxhello/nxhello_main.c @@ -79,7 +79,7 @@ struct nxhello_data_s g_nxhello = 0, /* xres */ 0, /* yres */ false, /* havpos */ - SEM_INITIALIZER(0), /* sem */ + SEM_INITIALIZER(0), /* eventsem */ NXEXIT_SUCCESS /* exit code */ }; diff --git a/examples/nximage/Kconfig b/examples/nximage/Kconfig index 70dca248f..b011a9a16 100644 --- a/examples/nximage/Kconfig +++ b/examples/nximage/Kconfig @@ -6,24 +6,28 @@ config EXAMPLES_NXIMAGE bool "NX graphics image example" default n + depends on NX_MULTIUSER + select LIB_BOARDCTL ---help--- Enable the X graphics image example if EXAMPLES_NXIMAGE -config EXAMPLES_NXIMAGE_VPLANE - int "Video Plane" - default 0 +config EXAMPLES_NXIMAGE_PROGNAME + string "NX Image Program name" + default "nxhello" + depends on BUILD_KERNEL ---help--- - The plane to select from the framebuffer driver for use in the test. - Default: 0 + This is the name of the program that will be use when the NSH ELF + program is installed. -config EXAMPLES_NXIMAGE_DEVNO - int "Video Device Number" - default 0 - ---help--- - The LCD device to select from the LCD driver for use in the test: - Default: 0 +config EXAMPLES_NXIMAGE_PRIORITY + int "NX Image task priority" + default 100 + +config EXAMPLES_NXIMAGE_STACKSIZE + int "NX Image stack size" + default 2048 config EXAMPLES_NXIMAGE_BPP int "Bits-Per-Pixel" @@ -87,4 +91,36 @@ config EXAMPLES_NXIMAGE_YSCALE2p0 ---help--- Increase image scale by 200% of its original size. +comment "NX Server Options" + +config EXAMPLES_NXIMAGE_LISTENER_STACKSIZE + int "NX Server/Listener Stack Size" + default 2048 + ---help--- + The stacksize to use when creating the NX server. Default 2048 + +config EXAMPLES_NXIMAGE_CLIENTPRIO + int "Client Priority" + default 100 + ---help--- + The client priority. Default: 100 + +config EXAMPLES_NXIMAGE_SERVERPRIO + int "Server Priority" + default 120 + ---help--- + The server priority. Default: 120 + +config EXAMPLES_NXIMAGE_LISTENERPRIO + int "Listener Priority" + default 80 + ---help--- + The priority of the event listener thread. Default 80. + +config EXAMPLES_NXIMAGE_NOTIFYSIGNO + int "Notify Signal Number" + default 4 + ---help--- + The signal number to use with nx_eventnotify(). Default: 4 + endif diff --git a/examples/nximage/Makefile b/examples/nximage/Makefile index 8f1aaf998..bb35c2294 100644 --- a/examples/nximage/Makefile +++ b/examples/nximage/Makefile @@ -1,7 +1,7 @@ ############################################################################ # apps/examples/nximage/Makefile # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -38,16 +38,19 @@ # NuttX NX Graphics Example. ASRCS = -CSRCS = nximage_bkgd.c nximage_bitmap.c +CSRCS = nximage_bkgd.c nximage_bitmap.c nximage_listener.c MAINSRC = nximage_main.c -CONFIG_XYZ_PROGNAME ?= nximage$(EXEEXT) -PROGNAME = $(CONFIG_XYZ_PROGNAME) +CONFIG_EXAMPLES_NXIMAGE_PROGNAME ?= nxhello$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_NXIMAGE_PROGNAME) # NXIMAGE built-in application info +CONFIG_EXAMPLES_NXIMAGE_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_EXAMPLES_NXIMAGE_STACKSIZE ?= 2048 + APPNAME = nximage -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = 2048 +PRIORITY = $(CONFIG_EXAMPLES_NXIMAGE_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_NXIMAGE_STACKSIZE) include $(APPDIR)/Application.mk diff --git a/examples/nximage/nximage.h b/examples/nximage/nximage.h index ac23240ad..9752daf99 100644 --- a/examples/nximage/nximage.h +++ b/examples/nximage/nximage.h @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nximage/nximage.h * - * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -59,10 +59,6 @@ # error "NX is not enabled (CONFIG_NX)" #endif -#ifndef CONFIG_EXAMPLES_NXIMAGE_VPLANE -# define CONFIG_EXAMPLES_NXIMAGE_VPLANE 0 -#endif - #ifndef CONFIG_EXAMPLES_NXIMAGE_BPP # define CONFIG_EXAMPLES_NXIMAGE_BPP 16 #endif @@ -107,6 +103,36 @@ # define CONFIG_EXAMPLES_NXIMAGE_YSCALE1p0 1 #endif +/* Multi-user NX support */ + +#ifdef CONFIG_DISABLE_MQUEUE +# error "The multi-threaded example requires MQ support (CONFIG_DISABLE_MQUEUE=n)" +#endif +#ifdef CONFIG_DISABLE_SIGNALS +# error "This example requires signal support (CONFIG_DISABLE_SIGNALS=n)" +#endif +#ifdef CONFIG_DISABLE_PTHREAD +# error "This example requires pthread support (CONFIG_DISABLE_PTHREAD=n)" +#endif +#ifndef CONFIG_NX_BLOCKING +# error "This example depends on CONFIG_NX_BLOCKING" +#endif +#ifndef CONFIG_EXAMPLES_NXIMAGE_LISTENER_STACKSIZE +# define CONFIG_EXAMPLES_NXIMAGE_LISTENER_STACKSIZE 2048 +#endif +#ifndef CONFIG_EXAMPLES_NXIMAGE_LISTENERPRIO +# define CONFIG_EXAMPLES_NXIMAGE_LISTENERPRIO 100 +#endif +#ifndef CONFIG_EXAMPLES_NXIMAGE_CLIENTPRIO +# define CONFIG_EXAMPLES_NXIMAGE_CLIENTPRIO 100 +#endif +#ifndef CONFIG_EXAMPLES_NXIMAGE_SERVERPRIO +# define CONFIG_EXAMPLES_NXIMAGE_SERVERPRIO 120 +#endif +#ifndef CONFIG_EXAMPLES_NXIMAGE_NOTIFYSIGNO +# define CONFIG_EXAMPLES_NXIMAGE_NOTIFYSIGNO 4 +#endif + /* Image Information ********************************************************/ #define IMAGE_HEIGHT 160 /* Number of rows in the raw image */ @@ -139,12 +165,7 @@ enum exitcode_e { NXEXIT_SUCCESS = 0, - NXEXIT_EXTINITIALIZE, - NXEXIT_FBINITIALIZE, - NXEXIT_FBGETVPLANE, - NXEXIT_LCDINITIALIZE, - NXEXIT_LCDGETDEV, - NXEXIT_NXOPEN, + NXEXIT_INIT, NXEXIT_NXREQUESTBKGD, NXEXIT_NXSETBGCOLOR }; @@ -155,6 +176,7 @@ struct nximage_data_s NXHANDLE hnx; NXHANDLE hbkgd; + bool connected; /* The screen resolution */ @@ -162,7 +184,7 @@ struct nximage_data_s nxgl_coord_t yres; volatile bool havepos; - sem_t sem; + sem_t eventsem; volatile int code; }; @@ -182,6 +204,10 @@ extern const struct nx_callback_s g_nximagecb; * Public Function Prototypes ****************************************************************************/ +/* NX server/listener thread */ + +FAR void *nximage_listener(FAR void *arg); + /* Background window interfaces */ void nximage_image(NXWINDOW hwnd); diff --git a/examples/nximage/nximage_bkgd.c b/examples/nximage/nximage_bkgd.c index 50f2f76b1..be119d052 100644 --- a/examples/nximage/nximage_bkgd.c +++ b/examples/nximage/nximage_bkgd.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nximage/nximage_bkgd.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -112,7 +112,7 @@ * Private Types ****************************************************************************/ -struct nximage_run_t +struct nximage_run_s { nxgl_mxpixel_t run[SCALED_WIDTH]; }; @@ -143,7 +143,7 @@ static void nximage_kbdin(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, /* Read one or two rows, output one tow or three rows */ -static struct nximage_run_t g_runs[NINPUT_ROWS]; +static struct nximage_run_s g_runs[NINPUT_ROWS]; /**************************************************************************** * Public Data @@ -216,7 +216,7 @@ static void nximage_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, g_nximage.yres = bounds->pt2.y + 1; g_nximage.havepos = true; - sem_post(&g_nximage.sem); + sem_post(&g_nximage.eventsem); ginfo("Have xres=%d yres=%d\n", g_nximage.xres, g_nximage.yres); } } diff --git a/examples/nximage/nximage_listener.c b/examples/nximage/nximage_listener.c new file mode 100644 index 000000000..e0936340d --- /dev/null +++ b/examples/nximage/nximage_listener.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * examples/nxterm/nximage_listener.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include "nximage.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nximage_listener + ****************************************************************************/ + +FAR void *nximage_listener(FAR void *arg) +{ + int ret; + + /* Process events forever */ + + for (;;) + { + /* Handle the next event. If we were configured blocking, then + * we will stay right here until the next event is received. Since + * we have dedicated a while thread to servicing events, it would + * be most natural to also select CONFIG_NX_BLOCKING -- if not, the + * following would be a tight infinite loop (unless we added addition + * logic with nx_eventnotify and sigwait to pace it). + */ + + ret = nx_eventhandler(g_nximage.hnx); + if (ret < 0) + { + /* An error occurred... assume that we have lost connection with + * the server. + */ + + printf("nximage_listener: Lost server connection: %d\n", errno); + exit(EXIT_FAILURE); + } + + /* If we received a message, we must be connected */ + + if (!g_nximage.connected) + { + g_nximage.connected = true; + sem_post(&g_nximage.eventsem); + printf("nximage_listener: Connected\n"); + } + } +} diff --git a/examples/nximage/nximage_main.c b/examples/nximage/nximage_main.c index b3eee368c..008b88965 100644 --- a/examples/nximage/nximage_main.c +++ b/examples/nximage/nximage_main.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nximage/nximage_main.c * - * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2015-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -56,13 +56,8 @@ #include #include -#ifdef CONFIG_NX_LCDDRIVER -# include -#else -# include -# ifdef CONFIG_VNCSERVER -# include -# endif +#ifdef CONFIG_VNCSERVER +# include #endif #include @@ -71,48 +66,20 @@ #include "nximage.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Configuration ************************************************************/ -/* If not specified, assume that the hardware supports one video plane */ - -#ifndef CONFIG_EXAMPLES_NXIMAGE_VPLANE -# define CONFIG_EXAMPLES_NXIMAGE_VPLANE 0 -#endif - -/* If not specified, assume that the hardware supports one LCD device */ - -#ifndef CONFIG_EXAMPLES_NXIMAGE_DEVNO -# define CONFIG_EXAMPLES_NXIMAGE_DEVNO 0 -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Data ****************************************************************************/ struct nximage_data_s g_nximage = { - NULL, /* hnx */ - NULL, /* hbkgd */ - 0, /* xres */ - 0, /* yres */ - false, /* havpos */ - { 0 }, /* sem */ - NXEXIT_SUCCESS /* exit code */ + NULL, /* hnx */ + NULL, /* hbkgd */ + false, /* connected */ + 0, /* xres */ + 0, /* yres */ + false, /* havpos */ + SEM_INITIALIZER(0), /* eventsem */ + NXEXIT_SUCCESS /* exit code */ }; /**************************************************************************** @@ -130,106 +97,80 @@ struct nximage_data_s g_nximage = static inline int nximage_initialize(void) { - FAR NX_DRIVERTYPE *dev; + struct sched_param param; + pthread_t thread; int ret; -#if defined(CONFIG_EXAMPLES_NXIMAGE_EXTERNINIT) - struct boardioc_graphics_s devinfo; + /* Set the client task priority */ - /* Use external graphics driver initialization */ - - printf("nximage_initialize: Initializing external graphics device\n"); - - devinfo.devno = CONFIG_EXAMPLES_NXIMAGE_DEVNO; - devinfo.dev = NULL; - - ret = boardctl(BOARDIOC_GRAPHICS_SETUP, (uintptr_t)&devinfo); + param.sched_priority = CONFIG_EXAMPLES_NXIMAGE_CLIENTPRIO; + ret = sched_setparam(0, ¶m); if (ret < 0) { - printf("nximage_initialize: boardctl failed, devno=%d: %d\n", - CONFIG_EXAMPLES_NXIMAGE_DEVNO, errno); - g_nximage.code = NXEXIT_EXTINITIALIZE; + printf("nximage_initialize: sched_setparam failed: %d\n" , ret); return ERROR; } - dev = devinfo.dev; + /* Start the NX server kernel thread */ -#elif defined(CONFIG_NX_LCDDRIVER) - /* Initialize the LCD device */ - - printf("nximage_initialize: Initializing LCD\n"); - ret = board_lcd_initialize(); + ret = boardctl(BOARDIOC_NX_START, 0); if (ret < 0) { - printf("nximage_initialize: board_lcd_initialize failed: %d\n", -ret); - g_nximage.code = NXEXIT_LCDINITIALIZE; + printf("nximage_initialize: Failed to start the NX server: %d\n", errno); return ERROR; } - /* Get the device instance */ + /* Connect to the server */ - dev = board_lcd_getdev(CONFIG_EXAMPLES_NXIMAGE_DEVNO); - if (!dev) + g_nximage.hnx = nx_connect(); + if (g_nximage.hnx) { - printf("nximage_initialize: board_lcd_getdev failed, devno=%d\n", - CONFIG_EXAMPLES_NXIMAGE_DEVNO); - g_nximage.code = NXEXIT_LCDGETDEV; - return ERROR; - } - - /* Turn the LCD on at 75% power */ - - (void)dev->setpower(dev, ((3*CONFIG_LCD_MAXPOWER + 3)/4)); -#else - /* Initialize the frame buffer device */ - - printf("nximage_initialize: Initializing framebuffer\n"); - - ret = up_fbinitialize(0); - if (ret < 0) - { - printf("nximage_initialize: up_fbinitialize failed: %d\n", -ret); - - g_nximage.code = NXEXIT_FBINITIALIZE; - return ERROR; - } - - dev = up_fbgetvplane(0, CONFIG_EXAMPLES_NXIMAGE_VPLANE); - if (!dev) - { - printf("nximage_initialize: up_fbgetvplane failed, vplane=%d\n", - CONFIG_EXAMPLES_NXIMAGE_VPLANE); - - g_nximage.code = NXEXIT_FBGETVPLANE; - return ERROR; - } -#endif - - /* Then open NX */ - - printf("nximage_initialize: Open NX\n"); - g_nximage.hnx = nx_open(dev); - if (!g_nximage.hnx) - { - printf("nximage_initialize: nx_open failed: %d\n", errno); - - g_nximage.code = NXEXIT_NXOPEN; - return ERROR; - } + pthread_attr_t attr; #ifdef CONFIG_VNCSERVER - /* Setup the VNC server to support keyboard/mouse inputs */ + /* Setup the VNC server to support keyboard/mouse inputs */ - ret = vnc_default_fbinitialize(0, g_nximage.hnx); - if (ret < 0) + ret = vnc_default_fbinitialize(0, g_nximage.hnx); + if (ret < 0) + { + printf("vnc_default_fbinitialize failed: %d\n", ret); + nx_disconnect(g_nximage.hnx); + return ERROR; + } +#endif + /* Start a separate thread to listen for server events. This is probably + * the least efficient way to do this, but it makes this example flow more + * smoothly. + */ + + (void)pthread_attr_init(&attr); + param.sched_priority = CONFIG_EXAMPLES_NXIMAGE_LISTENERPRIO; + (void)pthread_attr_setschedparam(&attr, ¶m); + (void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NXIMAGE_LISTENER_STACKSIZE); + + ret = pthread_create(&thread, &attr, nximage_listener, NULL); + if (ret != 0) + { + printf("nximage_initialize: pthread_create failed: %d\n", ret); + return ERROR; + } + + /* Don't return until we are connected to the server */ + + while (!g_nximage.connected) + { + /* Wait for the listener thread to wake us up when we really + * are connected. + */ + + (void)sem_wait(&g_nximage.eventsem); + } + } + else { - printf("vnc_default_fbinitialize failed: %d\n", ret); - - g_nximage.code = NXEXIT_FBINITIALIZE; - nx_close(g_nximage.hnx); + printf("nximage_initialize: nx_connect failed: %d\n", errno); return ERROR; } -#endif return OK; } @@ -262,7 +203,7 @@ int nximage_main(int argc, char *argv[]) if (!g_nximage.hnx || ret < 0) { printf("nximage_main: Failed to get NX handle: %d\n", errno); - g_nximage.code = NXEXIT_NXOPEN; + g_nximage.code = NXEXIT_INIT; goto errout; } @@ -295,7 +236,7 @@ int nximage_main(int argc, char *argv[]) while (!g_nximage.havepos) { - (void)sem_wait(&g_nximage.sem); + (void)sem_wait(&g_nximage.eventsem); } printf("nximage_main: Screen resolution (%d,%d)\n", g_nximage.xres, g_nximage.yres); @@ -311,8 +252,9 @@ int nximage_main(int argc, char *argv[]) /* Close NX */ errout_with_nx: - printf("nximage_main: Close NX\n"); - nx_close(g_nximage.hnx); + printf("nximage_main: Disconnect from the server\n"); + nx_disconnect(g_nximage.hnx); + errout: return g_nximage.code; }