diff --git a/examples/nxhello/nxhello.h b/examples/nxhello/nxhello.h index f55a63bf9..88c5c2acd 100644 --- a/examples/nxhello/nxhello.h +++ b/examples/nxhello/nxhello.h @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nxhello/nxhello.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 @@ -98,7 +98,7 @@ # endif #endif -/* Multi-user NX support */ +/* NX server support */ #ifdef CONFIG_DISABLE_MQUEUE # error "The multi-threaded example requires MQ support (CONFIG_DISABLE_MQUEUE=n)" diff --git a/examples/nxlines/Kconfig b/examples/nxlines/Kconfig index 03259f3f6..930a036e7 100644 --- a/examples/nxlines/Kconfig +++ b/examples/nxlines/Kconfig @@ -6,22 +6,28 @@ config EXAMPLES_NXLINES bool "NX graphics lines example" default n + depends on NX_MULTIUSER + select LIB_BOARDCTL ---help--- Enable the X graphics lines example if EXAMPLES_NXLINES -config EXAMPLES_NXLINES_VPLANE - int "Graphics Plane" - default 0 +config EXAMPLES_NXLINES_PROGNAME + string "NX lines program name" + default "nxhello" + depends on BUILD_KERNEL ---help--- - The plane to select from the frame-buffer 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_NXLINES_DEVNO - int "Graphics Device Number" - default 0 - ---help--- - The LCD device to select from the LCD driver for use in the test: Default: 0 +config EXAMPLES_NXLINES_PRIORITY + int "NX lines task priority" + default 100 + +config EXAMPLES_NXLINES_STACKSIZE + int "NX lines stack size" + default 2048 config EXAMPLES_NXLINES_DEFAULT_COLORS bool "Use default colors" @@ -80,25 +86,36 @@ config EXAMPLES_NXLINES_BPP Pixels per pixel to use. Valid options include 2, 4, 8, 16, 24, and 32. Default is 16. -config EXAMPLES_NXLINES_EXTERNINIT - bool "External Device Initialization" - default false - depends on LIB_BOARDCTL - select BOARDCTL_GRAPHICS +comment "NX Server Options" + +config EXAMPLES_NXLINES_LISTENER_STACKSIZE + int "NX Server/Listener Stack Size" + default 2048 ---help--- - The driver for the graphics device on this platform requires some unusual - initialization. This is the for, for example, SPI LCD/OLED devices. If - this configuration is selected, then the platform code must provide an LCD - initialization function with a prototype like: + The stacksize to use when creating the NX server. Default 2048 - #ifdef NX_LCDDRIVER - FAR struct lcd_dev_s *board_graphics_setup(unsigned int devno); - #else - FAR struct fb_vtable_s *board_graphics_setup(unsigned int devno); - #endif +config EXAMPLES_NXLINES_CLIENTPRIO + int "Client Priority" + default 100 + ---help--- + The client priority. Default: 100 - and must also define: CONFIG_LIB_BOARDCTL=y and - CONFIG_BOARDCTL_GRAPHICS=y so that the boardctl() interface - will be available in order to access this function. +config EXAMPLES_NXLINES_SERVERPRIO + int "Server Priority" + default 120 + ---help--- + The server priority. Default: 120 + +config EXAMPLES_NXLINES_LISTENERPRIO + int "Listener Priority" + default 80 + ---help--- + The priority of the event listener thread. Default 80. + +config EXAMPLES_NXLINES_NOTIFYSIGNO + int "Notify Signal Number" + default 4 + ---help--- + The signal number to use with nx_eventnotify(). Default: 4 endif diff --git a/examples/nxlines/Makefile b/examples/nxlines/Makefile index c0d8adec7..3da200ee4 100644 --- a/examples/nxlines/Makefile +++ b/examples/nxlines/Makefile @@ -1,7 +1,7 @@ ############################################################################ # apps/examples/nxlines/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 = nxlines_bkgd.c +CSRCS = nxlines_bkgd.c nxlines_listener.c MAINSRC = nxlines_main.c -CONFIG_XYZ_PROGNAME ?= nxlines$(EXEEXT) -PROGNAME = $(CONFIG_XYZ_PROGNAME) +CONFIG_EXAMPLES_NXLINES_PROGNAME ?= nxhello$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_NXLINES_PROGNAME) # NXLINES built-in application info +CONFIG_EXAMPLES_NXLINES_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_EXAMPLES_NXLINES_STACKSIZE ?= 2048 + APPNAME = nxlines -PRIORITY = SCHED_PRIORITY_DEFAULT -STACKSIZE = 2048 +PRIORITY = $(CONFIG_EXAMPLES_NXLINES_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_NXLINES_STACKSIZE) include $(APPDIR)/Application.mk diff --git a/examples/nxlines/nxlines.h b/examples/nxlines/nxlines.h index 78e07e9c9..24e066fe8 100644 --- a/examples/nxlines/nxlines.h +++ b/examples/nxlines/nxlines.h @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nxlines/nxlines.h * - * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -60,10 +60,6 @@ # error "NX is not enabled (CONFIG_NX)" #endif -#ifndef CONFIG_EXAMPLES_NXLINES_VPLANE -# define CONFIG_EXAMPLES_NXLINES_VPLANE 0 -#endif - #ifndef CONFIG_EXAMPLES_NXLINES_BPP # define CONFIG_EXAMPLES_NXLINES_BPP 16 #endif @@ -116,6 +112,36 @@ # endif #endif +/* NX server 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_NXLINES_LISTENER_STACKSIZE +# define CONFIG_EXAMPLES_NXLINES_LISTENER_STACKSIZE 2048 +#endif +#ifndef CONFIG_EXAMPLES_NXLINES_LISTENERPRIO +# define CONFIG_EXAMPLES_NXLINES_LISTENERPRIO 100 +#endif +#ifndef CONFIG_EXAMPLES_NXLINES_CLIENTPRIO +# define CONFIG_EXAMPLES_NXLINES_CLIENTPRIO 100 +#endif +#ifndef CONFIG_EXAMPLES_NXLINES_SERVERPRIO +# define CONFIG_EXAMPLES_NXLINES_SERVERPRIO 120 +#endif +#ifndef CONFIG_EXAMPLES_NXLINES_NOTIFYSIGNO +# define CONFIG_EXAMPLES_NXLINES_NOTIFYSIGNO 4 +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -123,12 +149,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 }; @@ -139,6 +160,7 @@ struct nxlines_data_s NXHANDLE hnx; NXHANDLE hbkgd; + bool connected; /* The screen resolution */ @@ -146,7 +168,7 @@ struct nxlines_data_s nxgl_coord_t yres; volatile bool havepos; - sem_t sem; + sem_t eventsem; volatile int code; }; @@ -166,6 +188,10 @@ extern const struct nx_callback_s g_nxlinescb; * Public Function Prototypes ****************************************************************************/ +/* NX event listener */ + +FAR void *nxlines_listener(FAR void *arg); + /* Background window interfaces */ void nxlines_test(NXWINDOW hwnd); diff --git a/examples/nxlines/nxlines_bkgd.c b/examples/nxlines/nxlines_bkgd.c index fdd1f4fcb..c2cb91cc6 100644 --- a/examples/nxlines/nxlines_bkgd.c +++ b/examples/nxlines/nxlines_bkgd.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nxlines/nxlines_bkgd.c * - * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -161,7 +161,7 @@ static void nxlines_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, g_nxlines.yres = bounds->pt2.y + 1; g_nxlines.havepos = true; - sem_post(&g_nxlines.sem); + sem_post(&g_nxlines.eventsem); ginfo("Have xres=%d yres=%d\n", g_nxlines.xres, g_nxlines.yres); } } diff --git a/examples/nxlines/nxlines_listener.c b/examples/nxlines/nxlines_listener.c new file mode 100644 index 000000000..3e2c96287 --- /dev/null +++ b/examples/nxlines/nxlines_listener.c @@ -0,0 +1,94 @@ +/**************************************************************************** + * examples/nxterm/nxlines_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 "nxlines.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxlines_listener + ****************************************************************************/ + +FAR void *nxlines_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_nxlines.hnx); + if (ret < 0) + { + /* An error occurred... assume that we have lost connection with + * the server. + */ + + printf("nxlines_listener: Lost server connection: %d\n", errno); + exit(EXIT_FAILURE); + } + + /* If we received a message, we must be connected */ + + if (!g_nxlines.connected) + { + g_nxlines.connected = true; + sem_post(&g_nxlines.eventsem); + printf("nxlines_listener: Connected\n"); + } + } +} diff --git a/examples/nxlines/nxlines_main.c b/examples/nxlines/nxlines_main.c index bca311c70..7a209637c 100644 --- a/examples/nxlines/nxlines_main.c +++ b/examples/nxlines/nxlines_main.c @@ -1,7 +1,7 @@ /**************************************************************************** * examples/nxlines/nxlines_main.c * - * Copyright (C) 2011-2012, 2015-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -54,13 +54,8 @@ #include #include -#ifdef CONFIG_NX_LCDDRIVER -# include -#else -# include -# ifdef CONFIG_VNCSERVER -# include -# endif +#ifdef CONFIG_VNCSERVER +# include #endif #include @@ -103,13 +98,14 @@ struct nxlines_data_s g_nxlines = { - 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 */ }; /**************************************************************************** @@ -122,107 +118,81 @@ struct nxlines_data_s g_nxlines = static inline int nxlines_initialize(void) { - FAR NX_DRIVERTYPE *dev; + struct sched_param param; + pthread_t thread; int ret; -#if defined(CONFIG_EXAMPLES_NXLINES_EXTERNINIT) - struct boardioc_graphics_s devinfo; + /* Set the client task priority */ - /* Use external graphics driver initialization */ - - printf("nxlines_initialize: Initializing external graphics device\n"); - - devinfo.devno = CONFIG_EXAMPLES_NXLINES_DEVNO; - devinfo.dev = NULL; - - ret = boardctl(BOARDIOC_GRAPHICS_SETUP, (uintptr_t)&devinfo); + param.sched_priority = CONFIG_EXAMPLES_NXLINES_CLIENTPRIO; + ret = sched_setparam(0, ¶m); if (ret < 0) { - printf("nxlines_initialize: boardctl failed, devno=%d: %d\n", - CONFIG_EXAMPLES_NXLINES_DEVNO, errno); - g_nxlines.code = NXEXIT_EXTINITIALIZE; + printf("nxlines_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("nxlines_initialize: Initializing LCD\n"); - ret = board_lcd_initialize(); + ret = boardctl(BOARDIOC_NX_START, 0); if (ret < 0) { - printf("nxlines_initialize: board_lcd_initialize failed: %d\n", -ret); - g_nxlines.code = NXEXIT_LCDINITIALIZE; + printf("nxlines_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_NXLINES_DEVNO); - if (!dev) + g_nxlines.hnx = nx_connect(); + if (g_nxlines.hnx) { - printf("nxlines_initialize: board_lcd_getdev failed, devno=%d\n", - CONFIG_EXAMPLES_NXLINES_DEVNO); - g_nxlines.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("nxlines_initialize: Initializing framebuffer\n"); - - ret = up_fbinitialize(0); - if (ret < 0) - { - printf("nxlines_initialize: up_fbinitialize failed: %d\n", -ret); - - g_nxlines.code = NXEXIT_FBINITIALIZE; - return ERROR; - } - - dev = up_fbgetvplane(0, CONFIG_EXAMPLES_NXLINES_VPLANE); - if (!dev) - { - printf("nxlines_initialize: up_fbgetvplane failed, vplane=%d\n", - CONFIG_EXAMPLES_NXLINES_VPLANE); - - g_nxlines.code = NXEXIT_FBGETVPLANE; - return ERROR; - } -#endif - - /* Then open NX */ - - printf("nxlines_initialize: Open NX\n"); - - g_nxlines.hnx = nx_open(dev); - if (!g_nxlines.hnx) - { - printf("nxlines_initialize: nx_open failed: %d\n", errno); - - g_nxlines.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_nxlines.hnx); - if (ret < 0) + ret = vnc_default_fbinitialize(0, g_nxlines.hnx); + if (ret < 0) + { + printf("vnc_default_fbinitialize failed: %d\n", ret); + nx_disconnect(g_nxlines.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_NXLINES_LISTENERPRIO; + (void)pthread_attr_setschedparam(&attr, ¶m); + (void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_NXLINES_LISTENER_STACKSIZE); + + ret = pthread_create(&thread, &attr, nxlines_listener, NULL); + if (ret != 0) + { + printf("nxlines_initialize: pthread_create failed: %d\n", ret); + return ERROR; + } + + /* Don't return until we are connected to the server */ + + while (!g_nxlines.connected) + { + /* Wait for the listener thread to wake us up when we really + * are connected. + */ + + (void)sem_wait(&g_nxlines.eventsem); + } + } + else { - printf("vnc_default_fbinitialize failed: %d\n", ret); - - nx_close(g_nxlines.hnx); - g_nxlines.code = NXEXIT_FBINITIALIZE; + printf("nxlines_initialize: nx_connect failed: %d\n", errno); return ERROR; } -#endif + return OK; } @@ -250,7 +220,7 @@ int nxlines_main(int argc, char *argv[]) if (!g_nxlines.hnx || ret < 0) { printf("nxlines_main: Failed to get NX handle: %d\n", errno); - g_nxlines.code = NXEXIT_NXOPEN; + g_nxlines.code = NXEXIT_INIT; goto errout; } @@ -284,8 +254,9 @@ int nxlines_main(int argc, char *argv[]) while (!g_nxlines.havepos) { - (void)sem_wait(&g_nxlines.sem); + (void)sem_wait(&g_nxlines.eventsem); } + printf("nxlines_main: Screen resolution (%d,%d)\n", g_nxlines.xres, g_nxlines.yres); /* Now, say perform the lines (these test does not return so the remaining @@ -301,8 +272,9 @@ int nxlines_main(int argc, char *argv[]) /* Close NX */ errout_with_nx: - printf("nxlines_main: Close NX\n"); - nx_close(g_nxlines.hnx); + printf("nxhello_main: Disconnect from the server\n"); + nx_disconnect(g_nxlines.hnx); + errout: return g_nxlines.code; }