/* 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 */