STM3240G-EVAL: Kernel mode board initialization can't run on the IDLE thread; needs its on initialization kernel thread

This commit is contained in:
Gregory Nutt 2013-12-31 07:59:56 -06:00
parent 9e416c2363
commit 118c4b1d67
4 changed files with 140 additions and 46 deletions

View File

@ -6,17 +6,18 @@
if ARCH_BOARD_STM3240G_EVAL
config STM3240G_LCD
bool "Select support for the STM3210E-EVAL LCD"
bool "Support STM3240G-EVAL LCD"
default y
depends on LCD && STM32_FSMC
---help---
Enable support for the LCD on the STM3240G-EVAL board. See additional,
LCD-common settings in the drivers/lcd Kconfig file.
if STM3240G_LCD
config LCD_RDSHIFT
int "LCD data shift"
default 5
depends on STM3240G_LCD
---help---
When reading 16-bit gram data, there appears to be a shift in the returned
data. This value fixes the offset. Default 5.
@ -24,7 +25,6 @@ config LCD_RDSHIFT
config STM32_ILI9320_DISABLE
bool "Disable LCD_ILI9320 (and LCD_ILI9321) support"
default n
depends on STM3240G_LCD
---help---
The LCD driver dynamically selects the LCD based on the reported LCD
ID value. However, code size can be reduced by suppressing support for
@ -33,10 +33,43 @@ config STM32_ILI9320_DISABLE
config STM32_ILI9325_DISABLE
bool "Disable LCD_ILI9325 support"
default n
depends on STM3240G_LCD
---help---
The LCD driver dynamically selects the LCD based on the reported LCD
ID value. However, code size can be reduced by suppressing support for
individual LCDs using this option
endif
endif # STM3240G_LCD
if BOARD_INITIALIZE
config STM3240G_BOARDINIT_PRIO
int "Board initialization thread priority"
default 196
---help---
If BOARD_INITIALIZE initialize is defined, then the function
board_initialize() will be called to perform board-specific
initialization. board_initialize() runs on the IDLE thread.
Depending on the features that are enabled, this board
initialization logic may need to start a kernel thread that has
more capability than the IDLE thread. This setting then provides
the priority of the board initialization thread.
NOTE: STM3240G_BOARDINIT_PRIO should have a relatively high
priority to assure that board level initialization completes
before the application requires the initialized board services.
Default: 196
config STM3240G_BOARDINIT_STACK
int "Board initialization thread Size"
default 2048
---help---
If BOARD_INITIALIZE initialize is defined, then the function
board_initialize() will be called to perform board-specific
initialization. board_initialize() runs on the IDLE thread.
Depending on the features that are enabled, this board
initialization logic may need to start a kernel thread that has
more capability than the IDLE thread. This setting then provides
the size of the stack to use with the initialization kernel thread.
endif # BOARD_INITIALIZE
endif # ARCH_BOARD_STM3240G_EVAL

View File

@ -381,6 +381,8 @@ CONFIG_ARCH_HAVE_IRQBUTTONS=y
# CONFIG_STM32_ILI9325_DISABLE is not set
CONFIG_LCD_RDSHIFT=5
CONFIG_STM3240G_LCD=y
CONFIG_STM3240G_BOARDINIT_PRIO=196
CONFIG_STM3240G_BOARDINIT_STACK=2048
#
# RTOS Features

View File

@ -41,9 +41,6 @@
#include <debug.h>
#include <arch/board/board.h>
#include "up_arch.h"
#include "stm3240g-internal.h"
/************************************************************************************
@ -102,10 +99,97 @@
# endif
#endif
/* Check if we will need to support the initialization kernel thread */
#undef HAVE_INITTHREAD
#ifdef CONFIG_BOARD_INITIALIZE
# if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_NSH_ARCHINIT)
# define HAVE_INITTHREAD 1
# elif defined(HAVE_NXSTART)
# define HAVE_INITTHREAD 1
# elif defined(HAVE_TCINIT)
# define HAVE_INITTHREAD 1
# endif
#endif
#ifdef HAVE_INITTHREAD
# include <stdlib.h>
# include <assert.h>
# include <nuttx/kthread.h>
# ifndef CONFIG_STM3240G_BOARDINIT_PRIO
# define CONFIG_STM3240G_BOARDINIT_PRIO 196
# endif
# ifndef CONFIG_STM3240G_BOARDINIT_STACK
# define CONFIG_STM3240G_BOARDINIT_STACK 2048
# endif
#endif
/************************************************************************************
* Private Functions
************************************************************************************/
/************************************************************************************
* Name: board_initthread
*
* Description:
* Board initialization kernel thread. This thread exists to support
* initialization when CONFIG_BOARD_INITIALIZE is defined. It is started by
* board_initialize() which runs on the IDLE thread.
*
* This function thread exists because some initialization steps may require
* waiting for events. Such waiting is not possible on the IDLE thread.
*
* Input Parameters:
* Standard task start-up parameters (none of which are used)
*
* Returned Value:
* Always returns EXIT_SUCCESS.
*
************************************************************************************/
#ifdef HAVE_INITTHREAD
static int board_initthread(int argc, char *argv[])
{
int ret;
/* Perform NSH initialization here instead of from the NSH. This
* alternative NSH initialization is necessary when NSH is ran in user-space
* but the initialization function must run in kernel space.
*/
#if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_NSH_ARCHINIT)
ret = nsh_archinitialize();
if (ret < 0)
{
gdbg("ERROR: nsh_archinitialize failed: %d\n", ret);
}
#endif
/* Initialize the NX server */
#ifdef HAVE_NXSTART
ret = nx_start();
if (ret < 0)
{
gdbg("ERROR: nx_start failed: %d\n", ret);
}
#endif
/* Initialize the touchscreen */
#ifdef HAVE_TCINIT
ret = arch_tcinitialize(CONFIG_NXWM_TOUCHSCREEN_DEVNO);
if (ret < 0)
{
gdbg("ERROR: arch_tcinitialize failed: %d\n", ret);
}
#endif
return EXIT_SUCCESS;
}
#endif
/************************************************************************************
* Public Functions
************************************************************************************/
@ -115,7 +199,7 @@
*
* Description:
* All STM32 architectures must provide the following entry point. This entry point
* is called early in the intitialization -- after all memory has been configured
* is called early in the initialization -- after all memory has been configured
* and mapped but before any devices have been initialized.
*
************************************************************************************/
@ -158,6 +242,7 @@ void stm32_boardinitialize(void)
up_ledinit();
#endif
}
/****************************************************************************
* Name: board_initialize
*
@ -174,39 +259,15 @@ void stm32_boardinitialize(void)
#ifdef CONFIG_BOARD_INITIALIZE
void board_initialize(void)
{
int ret;
#ifdef HAVE_INITTHREAD
pid_t server;
/* Perform NSH initialization here instead of from the NSH. This
* alternative NSH initialization is necessary when NSH is ran in user-space
* but the initialization function must run in kernel space.
*/
/* Start the board initialization kernel thread */
#if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_NSH_ARCHINIT)
ret = nsh_archinitialize();
if (ret < 0)
{
gdbg("ERROR: nsh_archinitialize failed: %d\n", ret);
}
#endif
/* Initialize the NX server */
#ifdef HAVE_NXSTART
ret = nx_start();
if (ret < 0)
{
gdbg("ERROR: nx_start failed: %d\n", ret);
}
#endif
/* Initialize the touchscreen */
#ifdef HAVE_TCINIT
ret = arch_tcinitialize(CONFIG_NXWM_TOUCHSCREEN_DEVNO);
if (ret < 0)
{
gdbg("ERROR: arch_tcinitialize failed: %d\n", ret);
}
server = KERNEL_THREAD("Board Init", CONFIG_STM3240G_BOARDINIT_PRIO,
CONFIG_STM3240G_BOARDINIT_STACK, board_initthread,
NULL);
ASSERT(server > 0);
#endif
}
#endif

View File

@ -189,8 +189,7 @@ int nx_start(void)
gvdbg("Starting server task\n");
server = KERNEL_THREAD("NX Server", CONFIG_NXSTART_SERVERPRIO,
CONFIG_NXSTART_SERVERSTACK, nx_server,
(FAR char * const *)0);
CONFIG_NXSTART_SERVERSTACK, nx_server, NULL);
if (server < 0)
{
int errcode = errno;
@ -200,12 +199,11 @@ int nx_start(void)
return -errcode;
}
#if 0 /* Can't do this on the IDLE thread */
/* Wait a bit to make sure that the server get started */
/* Wait a bit to make sure that the server get started. NOTE that this
* operation cannot be done from the IDLE thread!
*/
usleep(50*1000);
#endif
return OK;
}