Add capability to perform initial board initialization on a separate worker thread.

This commit is contained in:
Gregory Nutt 2014-09-03 18:36:43 -06:00
parent b2a94b6f2b
commit e958040269
3 changed files with 133 additions and 17 deletions

View File

@ -419,6 +419,9 @@ CONFIG_NAME_MAX=32
# RTOS hooks
#
CONFIG_BOARD_INITIALIZE=y
CONFIG_BOARD_INITTHREAD=y
CONFIG_BOARD_INITTHREAD_STACKSIZE=2048
CONFIG_BOARD_INITTHREAD_PRIORITY=240
# CONFIG_SCHED_STARTHOOK is not set
# CONFIG_SCHED_ATEXIT is not set
# CONFIG_SCHED_ONEXIT is not set

View File

@ -651,6 +651,40 @@ config BOARD_INITIALIZE
phase may be used, for example, to initialize board-specific
device drivers.
if BOARD_INITIALIZE
config BOARD_INITTHREAD
bool "Board initialization thread"
default n
---help---
Some initialization operations cannot be performed on the start-up,
initialization thread. That is because the initialization thread
cannot wait for event. If waiting is required as part of the board
initialization then this option must be selected. Waiting may be
required, for example, to mount a file system or or initialize a
device such as an SD card.
if BOARD_INITTHREAD
config BOARD_INITTHREAD_STACKSIZE
int "Board initialization thread stack size"
default 2048
---help---
The size of the stack to allocate when starting the board
initialization thread.
config BOARD_INITTHREAD_PRIORITY
int "Board initialization thread priority"
default 240
---help---
The priority of the board initialization thread. This priority is
not a critical setting. No other application threads will be
started until the board initialization is completed. Hence, there
is very little competition for the CPU.
endif # BOARD_INITTHREAD
endif # BOARD_INITIALIZE
config SCHED_STARTHOOK
bool "Enable startup hook"
default n

View File

@ -260,10 +260,11 @@ static inline void os_workqueues(void)
#endif /* CONFIG_SCHED_WORKQUEUE */
/****************************************************************************
* Name: os_init_thread
* Name: os_start_application
*
* Description:
* Start the application initialization thread.
* Execute the board initialization function (if so configured) and start
* the application initialization thread.
*
* Input Parameters:
* None
@ -274,18 +275,26 @@ static inline void os_workqueues(void)
****************************************************************************/
#if defined(CONFIG_INIT_ENTRYPOINT)
static inline void os_init_thread(void)
static inline void os_do_appstart(void)
{
int taskid;
svdbg("Starting init thread\n");
#ifdef CONFIG_BOARD_INITIALIZE
/* Perform any last-minute, board-specific initialization, if so
* configured.
*/
/* Start the application initialization ask. In a flat build, this is
board_initialize();
#endif
/* Start the application initialization task. In a flat build, this is
* entrypoint is given by the definitions, CONFIG_USER_ENTRYPOINT. In
* the protected build, however, we must get the address of the
* entrypoint from the header at the beginning of the user-space blob.
*/
svdbg("Starting init thread\n");
#ifdef CONFIG_BUILD_PROTECTED
DEBUGASSERT(USERSPACE->us_entrypoint != NULL);
taskid = task_create("init", SCHED_PRIORITY_DEFAULT,
@ -301,10 +310,23 @@ static inline void os_init_thread(void)
}
#elif defined(CONFIG_INIT_FILEPATH)
static inline void os_init_thread(void)
static inline void os_do_appstart(void)
{
int ret;
#ifdef CONFIG_BOARD_INITIALIZE
/* Perform any last-minute, board-specific initialization, if so
* configured.
*/
board_initialize();
#endif
/* Start the application initialization program from a program in a
* mounted file system. Presumably the file system was mounted as part
* of the board_initialize() operation.
*/
svdbg("Starting init task: %s\n", CONFIG_USER_INITPATH);
ret = exec(CONFIG_USER_INITPATH, NULL, CONFIG_INIT_SYMTAB,
@ -313,13 +335,78 @@ static inline void os_init_thread(void)
}
#elif defined(CONFIG_INIT_NONE)
# define os_init_thread()
# define os_do_appstart()
#else
# error "Cannot start initialization thread"
#endif
/****************************************************************************
* Name: os_start_task
*
* Description:
* This is the framework for a short duration worker thread. It off-loads
* the board initialization and application start-up from the limited
* start-up, initialization thread to a more robust kernel thread.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_BOARD_INITTHREAD
static int os_start_task(int argc, FAR char **argv)
{
/* Do the board/application initialization and exit */
os_do_appstart();
return OK;
}
#endif
/****************************************************************************
* Name: os_start_application
*
* Description:
* Execute the board initialization function (if so configured) and start
* the application initialization thread. This will be done either on the
* thread of execution of the caller or on a separate thread of execution
* if so configured.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static inline void os_start_application(void)
{
#ifdef CONFIG_BOARD_INITTHREAD
int taskid;
/* Do the board/application initialization on a separate thread of
* execution.
*/
taskid = kernel_thread("AppBringUp", CONFIG_BOARD_INITTHREAD_PRIORITY,
CONFIG_BOARD_INITTHREAD_STACKSIZE,
(main_t)os_start_task, (FAR char * const *)NULL);
ASSERT(taskid > 0);
#else
/* Do the board/application initialization on this thread of execution. */
os_do_appstart();
#endif
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -384,20 +471,12 @@ int os_bringup(void)
os_workqueues();
/* Perform any last-minute, board-specific initialization, if so
* configured.
*/
#ifdef CONFIG_BOARD_INITIALIZE
board_initialize();
#endif
/* Once the operating system has been initialized, the system must be
* started by spawning the user initialization thread of execution. This
* is the first user-mode thread.
* will be the first user-mode thread.
*/
os_init_thread();
os_start_application();
/* We an save a few bytes by discarding the IDLE thread's environment. */