RTThread學習筆記——對線程的我的瞭解

線程?它是啥?編程

  在咱們剛開始進入嵌入式軟件的編程領域時,每次都會接觸到一個函數——main函數,在裸機的編程中,程序的執行流程就是在main函數中進行的,main函數也能夠理解爲一個線程,它也有它的棧空間來存儲變量。可是,若是有許多線程呢,怎樣來區分它們?又怎樣來分配存儲空間?數組

  對於這個問題,RTThread有它的解決辦法。多線程


 

首先是線程棧app

  棧,是一種經典的儲存結構,RTThread爲每一個線程都分配了棧空間,來看看它是怎樣定義的。函數

ALIGN(RT_ALIGN_SIZE)  //線程棧對齊
static rt_uint8_t rt_led1_thread_stack[1024];  //定義線程棧

  這是一個rt_uint8_t(RTThread中的宏定義,無符號8位)類型的全局數組,第一句話是爲了棧空間對齊,使得CPU對數據的訪問更加高效,第二句就是線程的具體定義了,這裏定義1024的長度。ui


 

而後是線程的ID卡——線程控制塊this

  在操做系統中,經常有許多的線程在運行,面對着這麼多的的線程,天然須要一個身份塊來標識每一個線程,使得系統便於管理。而這個身份,就是線程控制塊。spa

  具體定義以下:操作系統

struct rt_thread
{
    /* rt object */
    char        name[RT_NAME_MAX];                      /**< the name of thread */
    rt_uint8_t  type;                                   /**< type of object */
    rt_uint8_t  flags;                                  /**< thread's flags */

#ifdef RT_USING_MODULE
    void       *module_id;                              /**< id of application module */
#endif

    rt_list_t   list;                                   /**< the object list */
    rt_list_t   tlist;                                  /**< the thread list */

    /* stack point and entry */
    void       *sp;                                     /**< stack point */
    void       *entry;                                  /**< entry */
    void       *parameter;                              /**< parameter */
    void       *stack_addr;                             /**< stack address */
    rt_uint32_t stack_size;                             /**< stack size */

    /* error code */
    rt_err_t    error;                                  /**< error code */

    rt_uint8_t  stat;                                   /**< thread status */

    /* priority */
    rt_uint8_t  current_priority;                       /**< current priority */
    rt_uint8_t  init_priority;                          /**< initialized priority */
#if RT_THREAD_PRIORITY_MAX > 32
    rt_uint8_t  number;
    rt_uint8_t  high_mask;
#endif
    rt_uint32_t number_mask;

#if defined(RT_USING_EVENT)
    /* thread event */
    rt_uint32_t event_set;
    rt_uint8_t  event_info;
#endif

#if defined(RT_USING_SIGNALS)
    rt_sigset_t     sig_pending;                        /**< the pending signals */
    rt_sigset_t     sig_mask;                           /**< the mask bits of signal */

    void            *sig_ret;                           /**< the return stack pointer from signal */
    rt_sighandler_t *sig_vectors;                       /**< vectors of signal handler */
    void            *si_list;                           /**< the signal infor list */
#endif

    rt_ubase_t  init_tick;                              /**< thread's initialized tick */
    rt_ubase_t  remaining_tick;                         /**< remaining tick */

    struct rt_timer thread_timer;                       /**< built-in thread timer */

    void (*cleanup)(struct rt_thread *tid);             /**< cleanup function when thread exit */

    /* light weight process if present */
#ifdef RT_USING_LWP
    void        *lwp;
#endif

    rt_uint32_t user_data;                             /**< private user data beyond this thread */
};

  看起來線程控制塊的定義很是複雜,實際上,線程控制塊的主要包含信息有對象成員相關(RTT(hread)經過對象來進行管理),線程鏈表相關(RTT經過線程鏈表實現調度,也被稱爲優先級表/就緒鏈表),線程棧相關和線程自己的相關地址。使用時,須要經過static struct定義一個控制塊結構體線程


 

初始化:

  線程初始化定義以下:

rt_err_t rt_thread_init(struct rt_thread *thread,
                        const char       *name,
                        void (*entry)(void *parameter),
                        void             *parameter,
                        void             *stack_start,
                        rt_uint32_t       stack_size,
                        rt_uint8_t        priority,
                        rt_uint32_t       tick)

  初始化的須要的參數有(從上到下):線程控制塊地址,線程名稱,入口函數地址,入口函數參數,棧起始地址,線程優先級和線程時間片。使用時,需引入具體參數。


 

具體定義:

  線程的具體定義,給出一個荔枝(這裏部分參考了野火哥的例程):

static void led_thread_entry(void *parameter)
{
    while(1)
    {
        LED_ON;
        rt_thread_mdelay(1000);
        LED_OFF;
        rt_thread_mdelay(1000);
    }
}        

  須要特別注意的是,這裏必定要用RTT系統的延時,不然線程不會讓出CPU供其餘線程使用,這就不是一個RTOS系統了。


 

啓動線程,開始調度:

  萬事俱備,只欠東風,只須要啓動線程(參數爲線程控制塊地址):

rt_thread_startup(&ABCDEFG);

  便可縱享RTOS系統的魅力。

 

(因爲我的水平有限,可能會出現理解,語句錯誤,請注意~:)

相關文章
相關標籤/搜索