Lee Shen / FTHR_USB_serial_qSPI
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 /** The Thread class allow defining, creating, and controlling thread functions in the system.
00040  *
00041  *  Example:
00042  *  @code
00043  *  #include "mbed.h"
00044  *  #include "rtos.h"
00045  *
00046  *  Thread thread;
00047  *  DigitalOut led1(LED1);
00048  *  volatile bool running = true;
00049  *
00050  *  // Blink function toggles the led in a long running loop
00051  *  void blink(DigitalOut *led) {
00052  *      while (running) {
00053  *          *led = !*led;
00054  *          wait(1);
00055  *      }
00056  *  }
00057  *
00058  *  // Spawns a thread to run blink for 5 seconds
00059  *  int main() {
00060  *      thread.start(callback(blink, &led1));
00061  *      wait(5);
00062  *      running = false;
00063  *      thread.join();
00064  *  }
00065  *  @endcode
00066  *
00067  * @note
00068  * Memory considerations: The thread control structures will be created on current thread's stack, both for the mbed OS
00069  * and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
00070  * Additionally the stack memory for this thread will be allocated on the heap, if it wasn't supplied to the constructor.
00071  */
00072 class Thread : private mbed::NonCopyable<Thread> {
00073 public:
00074     /** Allocate a new thread without starting execution
00075       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00076       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00077       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00078       @param   name           name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: NULL)
00079     */
00080     Thread(osPriority priority=osPriorityNormal,
00081            uint32_t stack_size=OS_STACK_SIZE,
00082            unsigned char *stack_mem=NULL, const char *name=NULL) {
00083         constructor(priority, stack_size, stack_mem, name);
00084     }
00085 
00086     /** Create a new thread, and start it executing the specified function.
00087       @param   task           function to be executed by this thread.
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       @deprecated
00092         Thread-spawning constructors hide errors. Replaced by thread.start(task).
00093 
00094         @code
00095         Thread thread(priority, stack_size, stack_mem);
00096 
00097         osStatus status = thread.start(task);
00098         if (status != osOK) {
00099             error("oh no!");
00100         }
00101         @endcode
00102     */
00103     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00104         "Thread-spawning constructors hide errors. "
00105         "Replaced by thread.start(task).")
00106     Thread(mbed::Callback<void()> task,
00107            osPriority priority=osPriorityNormal,
00108            uint32_t stack_size=OS_STACK_SIZE,
00109            unsigned char *stack_mem=NULL) {
00110         constructor(task, priority, stack_size, stack_mem);
00111     }
00112 
00113     /** Create a new thread, and start it executing the specified function.
00114       @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
00115       @param   task           argument to task.
00116       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00117       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00118       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00119       @deprecated
00120         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00121 
00122         @code
00123         Thread thread(priority, stack_size, stack_mem);
00124 
00125         osStatus status = thread.start(callback(task, argument));
00126         if (status != osOK) {
00127             error("oh no!");
00128         }
00129         @endcode
00130     */
00131     template <typename T>
00132     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00133         "Thread-spawning constructors hide errors. "
00134         "Replaced by thread.start(callback(task, argument)).")
00135     Thread(T *argument, void (T::*task)(),
00136            osPriority priority=osPriorityNormal,
00137            uint32_t stack_size=OS_STACK_SIZE,
00138            unsigned char *stack_mem=NULL) {
00139         constructor(mbed::callback(task, argument),
00140                     priority, stack_size, stack_mem);
00141     }
00142 
00143     /** Create a new thread, and start it executing the specified function.
00144       @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
00145       @param   task           argument to task.
00146       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00147       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00148       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00149       @deprecated
00150         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00151 
00152         @code
00153         Thread thread(priority, stack_size, stack_mem);
00154 
00155         osStatus status = thread.start(callback(task, argument));
00156         if (status != osOK) {
00157             error("oh no!");
00158         }
00159         @endcode
00160     */
00161     template <typename T>
00162     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00163         "Thread-spawning constructors hide errors. "
00164         "Replaced by thread.start(callback(task, argument)).")
00165     Thread(T *argument, void (*task)(T *),
00166            osPriority priority=osPriorityNormal,
00167            uint32_t stack_size=OS_STACK_SIZE,
00168            unsigned char *stack_mem=NULL) {
00169         constructor(mbed::callback(task, argument),
00170                     priority, stack_size, stack_mem);
00171     }
00172 
00173     /** Create a new thread, and start it executing the specified function.
00174         Provided for backwards compatibility
00175       @param   task           function to be executed by this thread.
00176       @param   argument       pointer that is passed to the thread function as start argument. (default: NULL).
00177       @param   priority       initial priority of the thread function. (default: osPriorityNormal).
00178       @param   stack_size     stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
00179       @param   stack_mem      pointer to the stack area to be used by this thread (default: NULL).
00180       @deprecated
00181         Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
00182 
00183         @code
00184         Thread thread(priority, stack_size, stack_mem);
00185 
00186         osStatus status = thread.start(callback(task, argument));
00187         if (status != osOK) {
00188             error("oh no!");
00189         }
00190         @endcode
00191     */
00192     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00193         "Thread-spawning constructors hide errors. "
00194         "Replaced by thread.start(callback(task, argument)).")
00195     Thread(void (*task)(void const *argument), void *argument=NULL,
00196            osPriority priority=osPriorityNormal,
00197            uint32_t stack_size=OS_STACK_SIZE,
00198            unsigned char *stack_mem=NULL) {
00199         constructor(mbed::callback((void (*)(void *))task, argument),
00200                     priority, stack_size, stack_mem);
00201     }
00202 
00203     /** Starts a thread executing the specified function.
00204       @param   task           function to be executed by this thread.
00205       @return  status code that indicates the execution status of the function.
00206       @note a thread can only be started once
00207     */
00208     osStatus start(mbed::Callback<void()> task);
00209 
00210     /** Starts a thread executing the specified function.
00211       @param   obj            argument to task
00212       @param   method         function to be executed by this thread.
00213       @return  status code that indicates the execution status of the function.
00214       @deprecated
00215           The start function does not support cv-qualifiers. Replaced by start(callback(obj, method)).
00216     */
00217     template <typename T, typename M>
00218     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00219         "The start function does not support cv-qualifiers. "
00220         "Replaced by thread.start(callback(obj, method)).")
00221     osStatus start(T *obj, M method) {
00222         return start(mbed::callback(obj, method));
00223     }
00224 
00225     /** Wait for thread to terminate
00226       @return  status code that indicates the execution status of the function.
00227       @note not callable from interrupt
00228     */
00229     osStatus join();
00230 
00231     /** Terminate execution of a thread and remove it from Active Threads
00232       @return  status code that indicates the execution status of the function.
00233     */
00234     osStatus terminate();
00235 
00236     /** Set priority of an active thread
00237       @param   priority  new priority value for the thread function.
00238       @return  status code that indicates the execution status of the function.
00239     */
00240     osStatus set_priority(osPriority priority);
00241 
00242     /** Get priority of an active thread
00243       @return  current priority value of the thread function.
00244     */
00245     osPriority get_priority();
00246 
00247     /** Set the specified Thread Flags for the thread.
00248       @param   signals  specifies the signal flags of the thread that should be set.
00249       @return  signal flags after setting or osFlagsError in case of incorrect parameters.
00250     */
00251     int32_t signal_set(int32_t signals);
00252 
00253     /** State of the Thread */
00254     enum State {
00255         Inactive,           /**< NOT USED */
00256         Ready,              /**< Ready to run */
00257         Running,            /**< Running */
00258         WaitingDelay,       /**< Waiting for a delay to occur */
00259         WaitingJoin,        /**< Waiting for thread to join. Only happens when using RTX directly. */
00260         WaitingThreadFlag,  /**< Waiting for a thread flag to be set */
00261         WaitingEventFlag,   /**< Waiting for a event flag to be set */
00262         WaitingMutex,       /**< Waiting for a mutex event to occur */
00263         WaitingSemaphore,   /**< Waiting for a semaphore event to occur */
00264         WaitingMemoryPool,  /**< Waiting for a memory pool */
00265         WaitingMessageGet,  /**< Waiting for message to arrive */
00266         WaitingMessagePut,  /**< Waiting for message to be send */
00267         WaitingInterval,    /**< NOT USED */
00268         WaitingOr,          /**< NOT USED */
00269         WaitingAnd,         /**< NOT USED */
00270         WaitingMailbox,     /**< NOT USED (Mail is implemented as MemoryPool and Queue) */
00271 
00272         /* Not in sync with RTX below here */
00273         Deleted,            /**< The task has been deleted or not started */
00274     };
00275 
00276     /** State of this Thread
00277       @return  the State of this Thread
00278     */
00279     State get_state();
00280     
00281     /** Get the total stack memory size for this Thread
00282       @return  the total stack memory size in bytes
00283     */
00284     uint32_t stack_size();
00285     
00286     /** Get the currently unused stack memory for this Thread
00287       @return  the currently unused stack memory in bytes
00288     */
00289     uint32_t free_stack();
00290     
00291     /** Get the currently used stack memory for this Thread
00292       @return  the currently used stack memory in bytes
00293     */
00294     uint32_t used_stack();
00295     
00296     /** Get the maximum stack memory usage to date for this Thread
00297       @return  the maximum stack memory usage to date in bytes
00298     */
00299     uint32_t max_stack();
00300 
00301     /** Get thread name
00302       @return  thread name or NULL if the name was not set.
00303      */
00304     const char *get_name();
00305 
00306     /** Clears the specified Thread Flags of the currently running thread.
00307       @param   signals  specifies the signal flags of the thread that should be cleared.
00308       @return  signal flags before clearing or osFlagsError in case of incorrect parameters.
00309     */
00310     static int32_t signal_clr(int32_t signals);
00311 
00312     /** Wait for one or more Thread Flags to become signaled for the current RUNNING thread.
00313       @param   signals   wait until all specified signal flags are set or 0 for any single signal flag.
00314       @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
00315       @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.
00316       @note not callable from interrupt
00317     */
00318     static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
00319 
00320     /** Wait for a specified time period in millisec:
00321       @param   millisec  time delay value
00322       @return  status code that indicates the execution status of the function.
00323       @note not callable from interrupt
00324     */
00325     static osStatus wait(uint32_t millisec);
00326 
00327     /** Pass control to next thread that is in state READY.
00328       @return  status code that indicates the execution status of the function.
00329       @note not callable from interrupt
00330     */
00331     static osStatus yield();
00332 
00333     /** Get the thread id of the current running thread.
00334       @return  thread ID for reference by other functions or NULL in case of error.
00335     */
00336     static osThreadId gettid();
00337 
00338     /** Attach a function to be called by the RTOS idle task
00339       @param   fptr  pointer to the function to be called
00340     */
00341     static void attach_idle_hook(void (*fptr)(void));
00342 
00343     /** Attach a function to be called when a task is killed
00344       @param   fptr  pointer to the function to be called
00345     */
00346     static void attach_terminate_hook(void (*fptr)(osThreadId id));
00347 
00348     virtual ~Thread();
00349 
00350 private:
00351     // Required to share definitions without
00352     // delegated constructors
00353     void constructor(osPriority priority=osPriorityNormal,
00354                      uint32_t stack_size=OS_STACK_SIZE,
00355                      unsigned char *stack_mem=NULL,
00356                      const char *name=NULL);
00357     void constructor(mbed::Callback<void()> task,
00358                      osPriority priority=osPriorityNormal,
00359                      uint32_t stack_size=OS_STACK_SIZE,
00360                      unsigned char *stack_mem=NULL,
00361                      const char *name=NULL);
00362     static void _thunk(void * thread_ptr);
00363 
00364     mbed::Callback<void()>     _task;
00365     osThreadId_t               _tid;
00366     osThreadAttr_t             _attr;
00367     bool                       _dynamic_stack;
00368     Semaphore                  _join_sem;
00369     Mutex                      _mutex;
00370     mbed_rtos_storage_thread_t _obj_mem;
00371     bool                       _finished;
00372 };
00373 
00374 }
00375 #endif
00376 
00377 /** @}*/