/*
    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
    This file is part of ChibiOS/RT.
    ChibiOS/RT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    ChibiOS/RT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/
/**
 * @page article_create_thread How to create a thread
 * At the system startup there are already two active threads:
 * - Idle thread. This thread has the lowest priority in the system so
 *   it runs only when the other threads in the system are sleeping. This
 *   threads usually switches the system in a low power mode and does nothing
 *   else.
 * - Main thread. This thread executes your @p main() function at
 *   startup. The main thread is created at the @p NORMALPRIO level but it
 *   can change its own priority if required. It is from the main thread
 *   that the other threads are usually created.
 * .
 * There are two kind of threads in ChibiOS/RT:
 * - Static Threads. This kind of threads are statically allocated in
 *   memory. The memory used by the thread cannot reused except for restarting
 *   the threads.
 * - Dynamic Threads. Threads created by allocating memory from a memory
 *   heap or a memory pool.
 * .
 * 
Creating a static thread
 * In order to create a static thread a working area must be declared using
 * the macro @p WORKING_AREA as shown:
 * @code
static WORKING_AREA(myThreadWorkingArea, 128);
 * @endcode
 * This macro reserves 128 bytes of stack for the thread and space for all
 * the required thread related structures. The total size and the alignment
 * problems are handled inside the macro, you only need to specify the pure
 * stack size.
 * A thread can be started by invoking @p chThdCreateStatic() as shown in this
 * example:
 * @code
  Thread *tp = chThdCreateStatic(myThreadWorkingArea,
                                 sizeof(myThreadWorkingArea),
                                 NORMALPRIO,    /* Initial priority.    */
                                 myThread,      /* Thread function.     */
                                 NULL);         /* Thread parameter.    */
 * @endcode
 * Tre variable tp receives the pointer to the thread object, it is taken
 * by other APIs as parameter.
 * Now a complete example:
 * @code
/*
* * My simple application.
 */
#include 
/*
* * Working area for the LED flashing thread.
 */
static WORKING_AREA(myThreadWorkingArea, 128);
/*
* * LED flashing thread.
 */
static msg_t myThread(void *arg) {
  while (TRUE) {
    LED_ON();
    chThdSleepMilliseconds(500);
    LED_OFF();
    chThdSleepMilliseconds(500);
  }
}
int main(int argc, char *argv[]) {
  /* Starting the flashing LEDs thread.*/
  (void)chThdCreateStatic(myThreadWorkingArea, sizeof(myThreadWorkingArea),
                          NORMALPRIO, myThread, NULL);
  .
  .
  .
}
 * @endcode
 * Note that is memory allocated to myThread() is statically defined and cannot
 * be reused. Static threads are ideal for safety applications because there is
 * no risk of a memory allocation failure because progressive heap
 * fragmentation.
 *
 * Creating a dynamic thread using the heap allocator
 * In order to create a thread from a memory heap is very easy:
 * @code
  Thread *tp = chThdCreateFromHeap(NULL,        /* NULL = Default heap. */
                                   128,         /* Stack size.          */
                                   NORMALPRIO,  /* Initial priority.    */
                                   myThread,    /* Thread function.     */
                                   NULL);       /* Thread parameter.    */
 * @endcode
 * The memory is allocated from the spawned heap and the thread is started.
 * Note that the memory is not freed when the thread terminates but when the
 * thread final status (its return value) is collected by the spawning thread.
 * As example:
 * @code
static msg_t myThread(void *arg) {
  unsigned i = 10;
  while (i > 0) {
    LED_ON();
    chThdSleepMilliseconds(500);
    LED_OFF();
    chThdSleepMilliseconds(500);
    i--;
  }
  return (msg_t)i;
}
int main(int argc, char *argv[]) {
  Thread *tp = chThdCreateFromHeap(NULL, 128, NORMALPRIO+1, myThread, NULL);
  if (tp == NULL)
    chSysHalt();    /* Memory exausted. */
  
  /* The main thread continues its normal execution.*/
  .
  .
  /*
*   * Now waits for the spawned thread to terminate (if it has not terminated
*   * already) then gets the thread exit message (msg) and returns the
*   * terminated thread memory to the heap (default system heap in this
*   * example).
   */
  msg_t msg = chThdWait(tp);
  .
  .
}
 * @endcode
 *
 * Creating a dynamic thread using the heap allocator
 * A pool is a collection of equally sized memory blocks, creating a thread from
 * a memry pool is very similar to the previous example but the memory of
 * terminated threads is returned to the memory pool rather than to a heap:
 * @code
static msg_t myThread(void *arg) {
  unsigned i = 10;
  while (i > 0) {
    LED_ON();
    chThdSleepMilliseconds(500);
    LED_OFF();
    chThdSleepMilliseconds(500);
    i--;
  }
  return (msg_t)i;
}
int main(int argc, char *argv[]) {
  Thread *tp = chThdCreateFromMemoryPool(myPool, NORMALPRIO+1, myThread, NULL);
  if (tp == NULL)
    chSysHalt();    /* Pool empty. */
  
  /* The main thread continues its normal execution.*/
  .
  .
  /*
*   * Now waits for the spawned thread to terminate (if it has not terminated
*   * already) then gets the thread exit message (msg) and returns the
*   * terminated thread memory to the original memory pool.
   */
  msg_t msg = chThdWait(tp);
  .
  .
}
 * @endcode
 */