Rtos API example

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