線程?它是啥?編程
在咱們剛開始進入嵌入式軟件的編程領域時,每次都會接觸到一個函數——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系統的魅力。
(因爲我的水平有限,可能會出現理解,語句錯誤,請注意~:)