Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Thread.h Source File

Thread.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2012 ARM Limited
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00020  * SOFTWARE.
00021  */
00022 #ifndef THREAD_H
00023 #define THREAD_H
00024 
00025 #include <stdint.h>
00026 #include "cmsis_os2.h"
00027 #include "mbed_rtos1_types.h"
00028 #include "mbed_rtos_storage.h"
00029 #include "platform/Callback.h"
00030 #include "platform/mbed_toolchain.h"
00031 #include "platform/NonCopyable.h"
00032 #include "rtos/Semaphore.h"
00033 #include "rtos/Mutex.h"
00034 
00035 namespace rtos {
00036 /** \addtogroup rtos */
00037 /** @{*/
00038 /**
00039  * \defgroup rtos_Thread Thread class
00040  * @{
00041  */
00042 
00043 /** The Thread class allow defining, creating, and controlling thread functions in the system.
00044  *
00045  *  Example:
00046  *  @code
00047  *  #include "mbed.h"
00048  *  #include "rtos.h"
00049  *
00050  *  Thread thread;
00051  *  DigitalOut led1(LED1);
00052  *  volatile bool running = true;
00053  *
00054  *  // Blink function toggles the led in a long running loop
00055  *  void blink(DigitalOut *led) {
00056  *      while (running) {
00057  *          *led = !*led;
00058  *          wait(1);
00059  *      }
00060  *  }
00061  *
00062  *  // Spawns a thread to run blink for 5 seconds
00063  *  int main() {
00064  *      thread.start(callback(blink, &led1));
00065  *      wait(5);
00066  *      running = false;
00067  *      thread.join();
00068  *  }
00069  *  @endcode
00070  *
00071  * @note
00072  * Memory considerations: The thread control structures will be created on current thread's stack, both for the mbed OS
00073  * and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
00074  * Additionally the stack memory for this thread will be allocated on the heap, if it wasn't supplied to the constructor.
00075  *
00076  * @note
00077  * MBED_TZ_DEFAULT_ACCESS (default:0) flag can be used to change the default access of all user threads in non-secure mode.
00078  * MBED_TZ_DEFAULT_ACCESS set to 1, means all non-secure user threads have access to call secure functions.
00079  * MBED_TZ_DEFAULT_ACCESS set to 0, means none of the non-secure user thread have access to call secure functions,
00080  * to give access to particular thread used overloaded constructor with `tz_module` as argument during thread creation.
00081  *
00082  * MBED_TZ_DEFAULT_ACCESS is target specific define, should be set in targets.json file for Cortex-M23/M33 devices.
00083  */
00084 
00085 class Thread : private mbed::NonCopyable<Thread> {
00086 public:
00087     /** Allocate a new thread without starting execution
00088       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00089       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00090       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00091       @param   name           name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: NULL)
00092 
00093       @note Default value of tz_module will be MBED_TZ_DEFAULT_ACCESS
00094       @note You cannot call this function from ISR context.
00095     */
00096 
00097     Thread(osPriority priority=osPriorityNormal,
00098            uint32_t stack_size=OS_STACK_SIZE,
00099            unsigned char *stack_mem=NULL, const char *name=NULL) {
00100         constructor(priority, stack_size, stack_mem, name);
00101     }
00102 
00103     /** Allocate a new thread without starting execution
00104       @param   tz_module      trustzone thread identifier (osThreadAttr_t::tz_module)
00105                               Context of RTOS threads in non-secure state must be saved when calling secure functions.
00106                               tz_module ID is used to allocate context memory for threads, and it can be safely set to zero for
00107                               threads not using secure calls at all. See "TrustZone RTOS Context Management" for more details.
00108       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00109       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00110       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00111       @param   name           name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: NULL)
00112 
00113       @note You cannot call this function from ISR context.
00114     */
00115 
00116     Thread(uint32_t tz_module, osPriority priority=osPriorityNormal,
00117            uint32_t stack_size=OS_STACK_SIZE,
00118            unsigned char *stack_mem=NULL, const char *name=NULL) {
00119         constructor(tz_module, priority, stack_size, stack_mem, name);
00120     }
00121 
00122 
00123     /** Create a new thread, and start it executing the specified function.
00124       @param   task           function to be executed by this thread.
00125       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00126       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00127       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00128       @deprecated
00129         Thread-spawning constructors hide errors. Replaced by thread.start(task).
00130 
00131         @code
00132         Thread thread(priority, stack_size, stack_mem);
00133 
00134         osStatus status = thread.start(task);
00135         if (status != osOK) {
00136             error("oh no!");
00137         }
00138         @endcode
00139 
00140       @note You cannot call this function from ISR context.
00141     */
00142     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00143         "Thread-spawning constructors hide errors. "
00144         "Replaced by thread.start(task).")
00145     Thread(mbed::Callback<void()> task,
00146            osPriority priority=osPriorityNormal,
00147            uint32_t stack_size=OS_STACK_SIZE,
00148            unsigned char *stack_mem=NULL) {
00149         constructor(task, priority, stack_size, stack_mem);
00150     }
00151 
00152     /** Create a new thread, and start it executing the specified function.
00153       @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
00154       @param   task           argument to task.
00155       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00156       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00157       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00158       @deprecated
00159         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00160 
00161         @code
00162         Thread thread(priority, stack_size, stack_mem);
00163 
00164         osStatus status = thread.start(callback(task, argument));
00165         if (status != osOK) {
00166             error("oh no!");
00167         }
00168         @endcode
00169 
00170         @note You cannot call this function from ISR context.
00171     */
00172     template <typename T>
00173     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00174         "Thread-spawning constructors hide errors. "
00175         "Replaced by thread.start(callback(task, argument)).")
00176     Thread(T *argument, void (T::*task)(),
00177            osPriority priority=osPriorityNormal,
00178            uint32_t stack_size=OS_STACK_SIZE,
00179            unsigned char *stack_mem=NULL) {
00180         constructor(mbed::callback(task, argument),
00181                     priority, stack_size, stack_mem);
00182     }
00183 
00184     /** Create a new thread, and start it executing the specified function.
00185       @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
00186       @param   task           argument to task.
00187       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00188       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00189       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00190       @deprecated
00191         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00192 
00193         @code
00194         Thread thread(priority, stack_size, stack_mem);
00195 
00196         osStatus status = thread.start(callback(task, argument));
00197         if (status != osOK) {
00198             error("oh no!");
00199         }
00200         @endcode
00201 
00202       @note You cannot call this function from ISR context.
00203     */
00204     template <typename T>
00205     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00206         "Thread-spawning constructors hide errors. "
00207         "Replaced by thread.start(callback(task, argument)).")
00208     Thread(T *argument, void (*task)(T *),
00209            osPriority priority=osPriorityNormal,
00210            uint32_t stack_size=OS_STACK_SIZE,
00211            unsigned char *stack_mem=NULL) {
00212         constructor(mbed::callback(task, argument),
00213                     priority, stack_size, stack_mem);
00214     }
00215 
00216     /** Create a new thread, and start it executing the specified function.
00217         Provided for backwards compatibility
00218       @param   task           function to be executed by this thread.
00219       @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
00220       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00221       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00222       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00223       @deprecated
00224         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00225 
00226         @code
00227         Thread thread(priority, stack_size, stack_mem);
00228 
00229         osStatus status = thread.start(callback(task, argument));
00230         if (status != osOK) {
00231             error("oh no!");
00232         }
00233         @endcode
00234 
00235         @note You cannot call this function from ISR context.
00236     */
00237     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00238         "Thread-spawning constructors hide errors. "
00239         "Replaced by thread.start(callback(task, argument)).")
00240     Thread(void (*task)(void const *argument), void *argument=NULL,
00241            osPriority priority=osPriorityNormal,
00242            uint32_t stack_size=OS_STACK_SIZE,
00243            unsigned char *stack_mem=NULL) {
00244         constructor(mbed::callback((void (*)(void *))task, argument),
00245                     priority, stack_size, stack_mem);
00246     }
00247 
00248     /** Starts a thread executing the specified function.
00249       @param   task           function to be executed by this thread.
00250       @return  status code that indicates the execution status of the function.
00251       @note a thread can only be started once
00252 
00253       @note You cannot call this function ISR context.
00254     */
00255     osStatus start(mbed::Callback<void()> task);
00256 
00257     /** Starts a thread executing the specified function.
00258       @param   obj            argument to task
00259       @param   method         function to be executed by this thread.
00260       @return  status code that indicates the execution status of the function.
00261       @deprecated
00262           The start function does not support cv-qualifiers. Replaced by start(callback(obj, method)).
00263 
00264       @note You cannot call this function from ISR context.
00265     */
00266     template <typename T, typename M>
00267     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00268         "The start function does not support cv-qualifiers. "
00269         "Replaced by thread.start(callback(obj, method)).")
00270     osStatus start(T *obj, M method) {
00271         return start(mbed::callback(obj, method));
00272     }
00273 
00274     /** Wait for thread to terminate
00275       @return  status code that indicates the execution status of the function.
00276       @note not callable from interrupt
00277 
00278       @note You cannot call this function from ISR context.
00279     */
00280     osStatus join();
00281 
00282     /** Terminate execution of a thread and remove it from Active Threads
00283       @return  status code that indicates the execution status of the function.
00284 
00285       @note You cannot call this function from ISR context.
00286     */
00287     osStatus terminate();
00288 
00289     /** Set priority of an active thread
00290       @param   priority  new priority value for the thread function.
00291       @return  status code that indicates the execution status of the function.
00292 
00293       @note You cannot call this function from ISR context.
00294     */
00295     osStatus set_priority(osPriority priority);
00296 
00297     /** Get priority of an active thread
00298       @return  current priority value of the thread function.
00299 
00300       @note You cannot call this function from ISR context.
00301     */
00302     osPriority get_priority();
00303 
00304     /** Set the specified Thread Flags for the thread.
00305       @param   signals  specifies the signal flags of the thread that should be set.
00306       @return  signal flags after setting or osFlagsError in case of incorrect parameters.
00307 
00308       @note You may call this function from ISR context.
00309     */
00310     int32_t signal_set(int32_t signals);
00311 
00312     /** State of the Thread */
00313     enum State {
00314         Inactive,           /**< NOT USED */
00315         Ready,              /**< Ready to run */
00316         Running,            /**< Running */
00317         WaitingDelay,       /**< Waiting for a delay to occur */
00318         WaitingJoin,        /**< Waiting for thread to join. Only happens when using RTX directly. */
00319         WaitingThreadFlag,  /**< Waiting for a thread flag to be set */
00320         WaitingEventFlag,   /**< Waiting for a event flag to be set */
00321         WaitingMutex,       /**< Waiting for a mutex event to occur */
00322         WaitingSemaphore,   /**< Waiting for a semaphore event to occur */
00323         WaitingMemoryPool,  /**< Waiting for a memory pool */
00324         WaitingMessageGet,  /**< Waiting for message to arrive */
00325         WaitingMessagePut,  /**< Waiting for message to be send */
00326         WaitingInterval,    /**< NOT USED */
00327         WaitingOr,          /**< NOT USED */
00328         WaitingAnd,         /**< NOT USED */
00329         WaitingMailbox,     /**< NOT USED (Mail is implemented as MemoryPool and Queue) */
00330 
00331         /* Not in sync with RTX below here */
00332         Deleted,            /**< The task has been deleted or not started */
00333     };
00334 
00335     /** State of this Thread
00336       @return  the State of this Thread
00337 
00338       @note You cannot call this function from ISR context.
00339     */
00340     State get_state();
00341     
00342     /** Get the total stack memory size for this Thread
00343       @return  the total stack memory size in bytes
00344 
00345       @note You cannot call this function from ISR context.
00346     */
00347     uint32_t stack_size();
00348     
00349     /** Get the currently unused stack memory for this Thread
00350       @return  the currently unused stack memory in bytes
00351 
00352       @note You cannot call this function from ISR context.
00353     */
00354     uint32_t free_stack();
00355     
00356     /** Get the currently used stack memory for this Thread
00357       @return  the currently used stack memory in bytes
00358 
00359       @note You cannot call this function from ISR context.
00360     */
00361     uint32_t used_stack();
00362     
00363     /** Get the maximum stack memory usage to date for this Thread
00364       @return  the maximum stack memory usage to date in bytes
00365 
00366       @note You cannot call this function from ISR context.
00367     */
00368     uint32_t max_stack();
00369 
00370     /** Get thread name
00371       @return  thread name or NULL if the name was not set.
00372 
00373       @note You may call this function from ISR context.
00374      */
00375     const char *get_name();
00376 
00377     /** Clears the specified Thread Flags of the currently running thread.
00378       @param   signals  specifies the signal flags of the thread that should be cleared.
00379       @return  signal flags before clearing or osFlagsError in case of incorrect parameters.
00380 
00381       @note You cannot call this function from ISR context.
00382     */
00383     static int32_t signal_clr(int32_t signals);
00384 
00385     /** Wait for one or more Thread Flags to become signaled for the current RUNNING thread.
00386       @param   signals   wait until all specified signal flags are set or 0 for any single signal flag.
00387       @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
00388       @return  event flag information or error code. @note if @a millisec is set to 0 and flag is no set the event carries osOK value.
00389 
00390       @note You cannot call this function from ISR context.
00391     */
00392     static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
00393 
00394     /** Wait for a specified time period in milliseconds
00395       Being tick-based, the delay will be up to the specified time - eg for
00396       a value of 1 the system waits until the next millisecond tick occurs,
00397       leading to a delay of 0-1 milliseconds.
00398       @param   millisec  time delay value
00399       @return  status code that indicates the execution status of the function.
00400 
00401       @note You cannot call this function from ISR context.
00402     */
00403     static osStatus wait(uint32_t millisec);
00404 
00405     /** Wait until a specified time in millisec
00406       The specified time is according to Kernel::get_ms_count().
00407       @param   millisec absolute time in millisec
00408       @return  status code that indicates the execution status of the function.
00409       @note not callable from interrupt
00410       @note if millisec is equal to or lower than the current tick count, this
00411             returns immediately, either with an error or "osOK".
00412       @note the underlying RTOS may have a limit to the maximum wait time
00413             due to internal 32-bit computations, but this is guaranteed to work if the
00414             delay is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
00415             it may return with an immediate error, or wait for the maximum delay.
00416 
00417       @note You cannot call this function from ISR context.
00418     */
00419     static osStatus wait_until(uint64_t millisec);
00420 
00421     /** Pass control to next thread that is in state READY.
00422       @return  status code that indicates the execution status of the function.
00423 
00424       @note You cannot call this function from ISR context.
00425     */
00426     static osStatus yield();
00427 
00428     /** Get the thread id of the current running thread.
00429       @return  thread ID for reference by other functions or NULL in case of error.
00430 
00431       @note You may call this function from ISR context.
00432     */
00433     static osThreadId gettid();
00434 
00435     /** Attach a function to be called by the RTOS idle task
00436       @param   fptr  pointer to the function to be called
00437 
00438       @note You may call this function from ISR context.
00439     */
00440     static void attach_idle_hook(void (*fptr)(void));
00441 
00442     /** Attach a function to be called when a task is killed
00443       @param   fptr  pointer to the function to be called
00444 
00445       @note You may call this function from ISR context.
00446     */
00447     static void attach_terminate_hook(void (*fptr)(osThreadId id));
00448 
00449     /** Thread destructor
00450      *
00451      * @note You cannot call this function from ISR context.
00452      */
00453     virtual ~Thread();
00454 
00455 private:
00456     // Required to share definitions without
00457     // delegated constructors
00458     void constructor(osPriority priority=osPriorityNormal,
00459                      uint32_t stack_size=OS_STACK_SIZE,
00460                      unsigned char *stack_mem=NULL,
00461                      const char *name=NULL);
00462     void constructor(mbed::Callback<void()> task,
00463                      osPriority priority=osPriorityNormal,
00464                      uint32_t stack_size=OS_STACK_SIZE,
00465                      unsigned char *stack_mem=NULL,
00466                      const char *name=NULL);
00467     void constructor(uint32_t tz_module,
00468                      osPriority priority=osPriorityNormal,
00469                      uint32_t stack_size=OS_STACK_SIZE,
00470                      unsigned char *stack_mem=NULL,
00471                      const char *name=NULL);
00472     static void _thunk(void * thread_ptr);
00473 
00474     mbed::Callback<void()>     _task;
00475     osThreadId_t               _tid;
00476     osThreadAttr_t             _attr;
00477     bool                       _dynamic_stack;
00478     Semaphore                  _join_sem;
00479     Mutex                      _mutex;
00480     mbed_rtos_storage_thread_t _obj_mem;
00481     bool                       _finished;
00482 };
00483 /** @}*/
00484 /** @}*/
00485 }
00486 #endif
00487 
00488