Ok

Dependencies:   mbed_rtos_types Mutex mbed_rtos_storage mbed Semaphore

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 "rtos/mbed_rtos_types.h"
00027 #include "rtos/mbed_rtos1_types.h"
00028 #include "rtos/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 #if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY) || defined(UNITTEST)
00036 
00037 namespace rtos {
00038 /** \addtogroup rtos */
00039 /** @{*/
00040 /**
00041  * \defgroup rtos_Thread Thread class
00042  * @{
00043  */
00044 
00045 /** The Thread class allow defining, creating, and controlling thread functions in the system.
00046  *
00047  *  Example:
00048  *  @code
00049  *  #include "mbed.h"
00050  *  #include "rtos.h"
00051  *
00052  *  Thread thread;
00053  *  DigitalOut led1(LED1);
00054  *  volatile bool running = true;
00055  *
00056  *  // Blink function toggles the led in a long running loop
00057  *  void blink(DigitalOut *led) {
00058  *      while (running) {
00059  *          *led = !*led;
00060  *          wait(1);
00061  *      }
00062  *  }
00063  *
00064  *  // Spawns a thread to run blink for 5 seconds
00065  *  int main() {
00066  *      thread.start(callback(blink, &led1));
00067  *      wait(5);
00068  *      running = false;
00069  *      thread.join();
00070  *  }
00071  *  @endcode
00072  *
00073  * @note
00074  * Memory considerations: The thread control structures will be created on current thread's stack, both for the mbed OS
00075  * and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
00076  * Additionally the stack memory for this thread will be allocated on the heap, if it wasn't supplied to the constructor.
00077  *
00078  * @note
00079  * MBED_TZ_DEFAULT_ACCESS (default:0) flag can be used to change the default access of all user threads in non-secure mode.
00080  * MBED_TZ_DEFAULT_ACCESS set to 1, means all non-secure user threads have access to call secure functions.
00081  * MBED_TZ_DEFAULT_ACCESS set to 0, means none of the non-secure user thread have access to call secure functions,
00082  * to give access to particular thread used overloaded constructor with `tz_module` as argument during thread creation.
00083  *
00084  * MBED_TZ_DEFAULT_ACCESS is target specific define, should be set in targets.json file for Cortex-M23/M33 devices.
00085  */
00086 
00087 class Thread : private mbed::NonCopyable<Thread> {
00088 public:
00089     /** Allocate a new thread without starting execution
00090       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00091       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00092       @param   stack_mem      pointer to the stack area to be used by this thread (default: nullptr).
00093       @param   name           name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: nullptr)
00094 
00095       @note Default value of tz_module will be MBED_TZ_DEFAULT_ACCESS
00096       @note You cannot call this function from ISR context.
00097     */
00098 
00099     Thread(osPriority priority = osPriorityNormal,
00100            uint32_t stack_size = OS_STACK_SIZE,
00101            unsigned char *stack_mem = nullptr, const char *name = nullptr)
00102     {
00103         constructor(priority, stack_size, stack_mem, name);
00104     }
00105 
00106     /** Allocate a new thread without starting execution
00107       @param   tz_module      trustzone thread identifier (osThreadAttr_t::tz_module)
00108                               Context of RTOS threads in non-secure state must be saved when calling secure functions.
00109                               tz_module ID is used to allocate context memory for threads, and it can be safely set to zero for
00110                               threads not using secure calls at all. See "TrustZone RTOS Context Management" for more details.
00111       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00112       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00113       @param   stack_mem      pointer to the stack area to be used by this thread (default: nullptr).
00114       @param   name           name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: nullptr)
00115 
00116       @note You cannot call this function from ISR context.
00117     */
00118 
00119     Thread(uint32_t tz_module, osPriority priority = osPriorityNormal,
00120            uint32_t stack_size = OS_STACK_SIZE,
00121            unsigned char *stack_mem = nullptr, const char *name = nullptr)
00122     {
00123         constructor(tz_module, priority, stack_size, stack_mem, name);
00124     }
00125 
00126 
00127     /** Create a new thread, and start it executing the specified function.
00128       @param   task           function to be executed by this thread.
00129       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00130       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00131       @param   stack_mem      pointer to the stack area to be used by this thread (default: nullptr).
00132       @deprecated
00133         Thread-spawning constructors hide errors. Replaced by thread.start(task).
00134 
00135         @code
00136         Thread thread(priority, stack_size, stack_mem);
00137 
00138         osStatus status = thread.start(task);
00139         if (status != osOK) {
00140             error("oh no!");
00141         }
00142         @endcode
00143 
00144       @note You cannot call this function from ISR context.
00145     */
00146     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00147                           "Thread-spawning constructors hide errors. "
00148                           "Replaced by thread.start(task).")
00149     Thread(mbed::Callback<void()> task,
00150            osPriority priority = osPriorityNormal,
00151            uint32_t stack_size = OS_STACK_SIZE,
00152            unsigned char *stack_mem = nullptr)
00153     {
00154         constructor(task, priority, stack_size, stack_mem);
00155     }
00156 
00157     /** Create a new thread, and start it executing the specified function.
00158       @param   argument       pointer that is passed to the thread function as start argument. (default: nullptr).
00159       @param   task           argument to task.
00160       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00161       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00162       @param   stack_mem      pointer to the stack area to be used by this thread (default: nullptr).
00163       @deprecated
00164         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00165 
00166         @code
00167         Thread thread(priority, stack_size, stack_mem);
00168 
00169         osStatus status = thread.start(callback(task, argument));
00170         if (status != osOK) {
00171             error("oh no!");
00172         }
00173         @endcode
00174 
00175         @note You cannot call this function from ISR context.
00176     */
00177     template <typename T>
00178     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00179                           "Thread-spawning constructors hide errors. "
00180                           "Replaced by thread.start(callback(task, argument)).")
00181     Thread(T *argument, void (T::*task)(),
00182            osPriority priority = osPriorityNormal,
00183            uint32_t stack_size = OS_STACK_SIZE,
00184            unsigned char *stack_mem = nullptr)
00185     {
00186         constructor(mbed::callback(task, argument),
00187                     priority, stack_size, stack_mem);
00188     }
00189 
00190     /** Create a new thread, and start it executing the specified function.
00191       @param   argument       pointer that is passed to the thread function as start argument. (default: nullptr).
00192       @param   task           argument to task.
00193       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00194       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00195       @param   stack_mem      pointer to the stack area to be used by this thread (default: nullptr).
00196       @deprecated
00197         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00198 
00199         @code
00200         Thread thread(priority, stack_size, stack_mem);
00201 
00202         osStatus status = thread.start(callback(task, argument));
00203         if (status != osOK) {
00204             error("oh no!");
00205         }
00206         @endcode
00207 
00208       @note You cannot call this function from ISR context.
00209     */
00210     template <typename T>
00211     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00212                           "Thread-spawning constructors hide errors. "
00213                           "Replaced by thread.start(callback(task, argument)).")
00214     Thread(T *argument, void (*task)(T *),
00215            osPriority priority = osPriorityNormal,
00216            uint32_t stack_size = OS_STACK_SIZE,
00217            unsigned char *stack_mem = nullptr)
00218     {
00219         constructor(mbed::callback(task, argument),
00220                     priority, stack_size, stack_mem);
00221     }
00222 
00223     /** Create a new thread, and start it executing the specified function.
00224         Provided for backwards compatibility
00225       @param   task           function to be executed by this thread.
00226       @param   argument       pointer that is passed to the thread function as start argument. (default: nullptr).
00227       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00228       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00229       @param   stack_mem      pointer to the stack area to be used by this thread (default: nullptr).
00230       @deprecated
00231         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00232 
00233         @code
00234         Thread thread(priority, stack_size, stack_mem);
00235 
00236         osStatus status = thread.start(callback(task, argument));
00237         if (status != osOK) {
00238             error("oh no!");
00239         }
00240         @endcode
00241 
00242         @note You cannot call this function from ISR context.
00243     */
00244     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00245                           "Thread-spawning constructors hide errors. "
00246                           "Replaced by thread.start(callback(task, argument)).")
00247     Thread(void (*task)(void const *argument), void *argument = nullptr,
00248            osPriority priority = osPriorityNormal,
00249            uint32_t stack_size = OS_STACK_SIZE,
00250            unsigned char *stack_mem = nullptr)
00251     {
00252         constructor(mbed::callback((void (*)(void *))task, argument),
00253                     priority, stack_size, stack_mem);
00254     }
00255 
00256     /** Starts a thread executing the specified function.
00257       @param   task           function to be executed by this thread.
00258       @return  status code that indicates the execution status of the function.
00259       @note a thread can only be started once
00260 
00261       @note You cannot call this function ISR context.
00262     */
00263     osStatus start(mbed::Callback<void()> task);
00264 
00265     /** Starts a thread executing the specified function.
00266       @param   obj            argument to task
00267       @param   method         function to be executed by this thread.
00268       @return  status code that indicates the execution status of the function.
00269       @deprecated
00270           The start function does not support cv-qualifiers. Replaced by start(callback(obj, method)).
00271 
00272       @note You cannot call this function from ISR context.
00273     */
00274     template <typename T, typename M>
00275     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00276                           "The start function does not support cv-qualifiers. "
00277                           "Replaced by thread.start(callback(obj, method)).")
00278     osStatus start(T *obj, M method)
00279     {
00280         return start(mbed::callback(obj, method));
00281     }
00282 
00283     /** Wait for thread to terminate
00284       @return  status code that indicates the execution status of the function.
00285 
00286       @note You cannot call this function from ISR context.
00287     */
00288     osStatus join();
00289 
00290     /** Terminate execution of a thread and remove it from Active Threads
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 terminate();
00296 
00297     /** Set priority of an active thread
00298       @param   priority  new priority value for the thread function.
00299       @return  status code that indicates the execution status of the function.
00300 
00301       @note You cannot call this function from ISR context.
00302     */
00303     osStatus set_priority(osPriority priority);
00304 
00305     /** Get priority of an active thread
00306       @return  current priority value of the thread function.
00307 
00308       @note You cannot call this function from ISR context.
00309     */
00310     osPriority get_priority() const;
00311 
00312     /** Set the specified Thread Flags for the thread.
00313       @param   flags  specifies the flags of the thread that should be set.
00314       @return  thread flags after setting or osFlagsError in case of incorrect parameters.
00315 
00316       @note You may call this function from ISR context.
00317     */
00318     uint32_t flags_set(uint32_t flags);
00319 
00320     /** Set the specified Thread Flags for the thread.
00321       @param   signals  specifies the signal flags of the thread that should be set.
00322       @return  signal flags after setting or osFlagsError in case of incorrect parameters.
00323 
00324       @note You may call this function from ISR context.
00325       @deprecated Other signal_xxx methods have been deprecated in favour of ThisThread::flags functions.
00326                   To match this naming scheme, derived from CMSIS-RTOS2, Thread::flags_set is now provided.
00327     */
00328     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00329                           "Other signal_xxx methods have been deprecated in favour of ThisThread::flags functions. "
00330                           "To match this naming scheme, derived from CMSIS-RTOS2, Thread::flags_set is now provided.")
00331     int32_t signal_set(int32_t signals);
00332 
00333     /** State of the Thread */
00334     enum State {
00335         Inactive,           /**< NOT USED */
00336         Ready,              /**< Ready to run */
00337         Running,            /**< Running */
00338         WaitingDelay,       /**< Waiting for a delay to occur */
00339         WaitingJoin,        /**< Waiting for thread to join. Only happens when using RTX directly. */
00340         WaitingThreadFlag,  /**< Waiting for a thread flag to be set */
00341         WaitingEventFlag,   /**< Waiting for a event flag to be set */
00342         WaitingMutex,       /**< Waiting for a mutex event to occur */
00343         WaitingSemaphore,   /**< Waiting for a semaphore event to occur */
00344         WaitingMemoryPool,  /**< Waiting for a memory pool */
00345         WaitingMessageGet,  /**< Waiting for message to arrive */
00346         WaitingMessagePut,  /**< Waiting for message to be send */
00347         WaitingInterval,    /**< NOT USED */
00348         WaitingOr,          /**< NOT USED */
00349         WaitingAnd,         /**< NOT USED */
00350         WaitingMailbox,     /**< NOT USED (Mail is implemented as MemoryPool and Queue) */
00351 
00352         /* Not in sync with RTX below here */
00353         Deleted,            /**< The task has been deleted or not started */
00354     };
00355 
00356     /** State of this Thread
00357       @return  the State of this Thread
00358 
00359       @note You cannot call this function from ISR context.
00360     */
00361     State get_state() const;
00362 
00363     /** Get the total stack memory size for this Thread
00364       @return  the total stack memory size in bytes
00365 
00366       @note You cannot call this function from ISR context.
00367     */
00368     uint32_t stack_size() const;
00369 
00370     /** Get the currently unused stack memory for this Thread
00371       @return  the currently unused stack memory in bytes
00372 
00373       @note You cannot call this function from ISR context.
00374     */
00375     uint32_t free_stack() const;
00376 
00377     /** Get the currently used stack memory for this Thread
00378       @return  the currently used stack memory in bytes
00379 
00380       @note You cannot call this function from ISR context.
00381     */
00382     uint32_t used_stack() const;
00383 
00384     /** Get the maximum stack memory usage to date for this Thread
00385       @return  the maximum stack memory usage to date in bytes
00386 
00387       @note You cannot call this function from ISR context.
00388     */
00389     uint32_t max_stack() const;
00390 
00391     /** Get thread name
00392       @return  thread name or nullptr if the name was not set.
00393 
00394       @note You may call this function from ISR context.
00395      */
00396     const char *get_name() const;
00397 
00398     /** Get thread id
00399       @return  thread ID for reference by other functions.
00400 
00401       @note You may call this function from ISR context.
00402      */
00403     osThreadId_t get_id() const;
00404 
00405     /** Clears the specified Thread Flags of the currently running thread.
00406       @param   signals  specifies the signal flags of the thread that should be cleared.
00407       @return  signal flags before clearing or osFlagsError in case of incorrect parameters.
00408 
00409       @note You cannot call this function from ISR context.
00410       @deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::flags_clear.
00411     */
00412     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00413                           "Static methods only affecting current thread cause confusion. "
00414                           "Replaced by ThisThread::flags_clear.")
00415     static int32_t signal_clr(int32_t signals);
00416 
00417     /** Wait for one or more Thread Flags to become signaled for the current RUNNING thread.
00418       @param   signals   wait until all specified signal flags are set or 0 for any single signal flag.
00419       @param   millisec  timeout value. (default: osWaitForever).
00420       @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.
00421 
00422       @note You cannot call this function from ISR context.
00423       @deprecated Static methods only affecting current thread cause confusion.
00424                   Replaced by ThisThread::flags_wait_all, ThisThread::flags_wait_all_for, ThisThread::flags_wait_any and ThisThread:wait_any_for.
00425     */
00426     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00427                           "Static methods only affecting current thread cause confusion. "
00428                           "Replaced by ThisThread::flags_wait_all, ThisThread::flags_wait_all_for, ThisThread::flags_wait_any and ThisThread:wait_any_for.")
00429     static osEvent signal_wait(int32_t signals, uint32_t millisec = osWaitForever);
00430 
00431     /** Wait for a specified time period in milliseconds
00432       Being tick-based, the delay will be up to the specified time - eg for
00433       a value of 1 the system waits until the next millisecond tick occurs,
00434       leading to a delay of 0-1 milliseconds.
00435       @param   millisec  time delay value
00436       @return  status code that indicates the execution status of the function.
00437 
00438       @note You cannot call this function from ISR context.
00439       @deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_for.
00440     */
00441     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00442                           "Static methods only affecting current thread cause confusion. "
00443                           "Replaced by ThisThread::sleep_for.")
00444     static osStatus wait(uint32_t millisec);
00445 
00446     /** Wait until a specified time in millisec
00447       The specified time is according to Kernel::get_ms_count().
00448       @param   millisec absolute time in millisec
00449       @return  status code that indicates the execution status of the function.
00450       @note not callable from interrupt
00451       @note if millisec is equal to or lower than the current tick count, this
00452             returns immediately, either with an error or "osOK".
00453       @note the underlying RTOS may have a limit to the maximum wait time
00454             due to internal 32-bit computations, but this is guaranteed to work if the
00455             delay is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
00456             it may return with an immediate error, or wait for the maximum delay.
00457 
00458       @note You cannot call this function from ISR context.
00459       @deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_until.
00460     */
00461     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00462                           "Static methods only affecting current thread cause confusion. "
00463                           "Replaced by ThisThread::sleep_until.")
00464     static osStatus wait_until(uint64_t millisec);
00465 
00466     /** Pass control to next thread that is in state READY.
00467       @return  status code that indicates the execution status of the function.
00468 
00469       @note You cannot call this function from ISR context.
00470       @deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::sleep_until.
00471     */
00472     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00473                           "Static methods only affecting current thread cause confusion. "
00474                           "Replaced by ThisThread::yield.")
00475     static osStatus yield();
00476 
00477     /** Get the thread id of the current running thread.
00478       @return  thread ID for reference by other functions or nullptr in case of error.
00479 
00480       @note You may call this function from ISR context.
00481       @deprecated Static methods only affecting current thread cause confusion. Replaced by ThisThread::get_id.
00482                   Use Thread::get_id for the ID of a specific Thread.
00483     */
00484     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00485                           "Static methods only affecting current thread cause confusion. "
00486                           "Replaced by ThisThread::get_id. Use Thread::get_id for the ID of a specific Thread.")
00487     static osThreadId gettid();
00488 
00489     /** Attach a function to be called by the RTOS idle task
00490       @param   fptr  pointer to the function to be called
00491 
00492       @note You may call this function from ISR context.
00493       @deprecated Static methods affecting system cause confusion. Replaced by Kernel::attach_idle_hook.
00494     */
00495     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00496                           "Static methods affecting system cause confusion. "
00497                           "Replaced by Kernel::attach_idle_hook.")
00498     static void attach_idle_hook(void (*fptr)(void));
00499 
00500     /** Attach a function to be called when a task is killed
00501       @param   fptr  pointer to the function to be called
00502 
00503       @note You may call this function from ISR context.
00504       @deprecated Static methods affecting system cause confusion. Replaced by Kernel::attach_thread_terminate_hook.
00505     */
00506     MBED_DEPRECATED_SINCE("mbed-os-5.10",
00507                           "Static methods affecting system cause confusion. "
00508                           "Replaced by Kernel::attach_thread_terminate_hook.")
00509     static void attach_terminate_hook(void (*fptr)(osThreadId id));
00510 
00511     /** Thread destructor
00512      *
00513      * @note You cannot call this function from ISR context.
00514      */
00515     virtual ~Thread();
00516 
00517 private:
00518     // Required to share definitions without
00519     // delegated constructors
00520     void constructor(osPriority priority = osPriorityNormal,
00521                      uint32_t stack_size = OS_STACK_SIZE,
00522                      unsigned char *stack_mem = nullptr,
00523                      const char *name = nullptr);
00524     void constructor(mbed::Callback<void()> task,
00525                      osPriority priority = osPriorityNormal,
00526                      uint32_t stack_size = OS_STACK_SIZE,
00527                      unsigned char *stack_mem = nullptr,
00528                      const char *name = nullptr);
00529     void constructor(uint32_t tz_module,
00530                      osPriority priority = osPriorityNormal,
00531                      uint32_t stack_size = OS_STACK_SIZE,
00532                      unsigned char *stack_mem = nullptr,
00533                      const char *name = nullptr);
00534     static void _thunk(void *thread_ptr);
00535 
00536     mbed::Callback<void()>     _task;
00537     osThreadId_t               _tid;
00538     osThreadAttr_t             _attr;
00539     bool                       _dynamic_stack;
00540     Semaphore                  _join_sem;
00541     mutable Mutex              _mutex;
00542     mbed_rtos_storage_thread_t _obj_mem;
00543     bool                       _finished;
00544 };
00545 /** @}*/
00546 /** @}*/
00547 }
00548 #endif
00549 
00550 #endif
00551