自由分配的內存(堆)起始地址爲RAM的起始地址加上RW+ZI段後的地址區域。html
編譯出的program size分爲:數組
實際佔用空間狀況爲:數據結構
板子上電後默認從flash啓動,啓動以後會將RW段中的RW-data(初始化的全局變量)搬運到RAM中,但不會搬運RO段,即CPU的執行代碼從flash中讀取,另外根據編譯器給出的ZI地址和大小,分配出ZI段,並將這塊RAM區域清零。動態內存堆爲未使用的RAM空間,應用程序申請和釋放的內存都來自該空間
架構
char *ptr; ptr = rt_malloc(10); if (ptr != RT_NULL) { rt_memset(ptr, 0, 10); rt_kprintf("malloc success\n"); rt_free(ptr); ptr = RT_NULL; }
RT-Thread中,線程由三部分組成:線程代碼(入口函數)、線程控制塊、線程堆棧app
無限循環結構 void thread_entry(void *parameter) { while(1) { /* 等待事件發生 */ /* 處理事件 */ } } 順序執行結構 void thread_entry(void *parameter) { /* 事務1處理 */ /* 事務2處理 */ /* 事務3處理 */ }
操做系統管理線程的一個數據結構。存放線程的一些信息,好比優先級、線程名稱、線程狀態等等,也包括線程與線程之間鏈接用的鏈表結構,線程等待時間集合等ide
struct rt_thread; struct rt_thread *rt_thread_t;
每一個線程都有獨立的棧空間,線程切換時,系統會將當前線程的上下文保存在線程棧中,當線程要恢復運行時,再從線程棧中讀取上下文信息,恢復線程的運行。線程上下文是指線程執行時的環境,各個變量和數據包括全部的寄存器變量,堆棧信息,內存信息等。線程棧在形式上是一段連續的內存空間,能夠經過定義一個數組或者申請一段動態內存來做爲線程的棧
建立線程:函數
建立靜態線程 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) 建立動態線程 rt_thread_t rt_thread_create(const char *name, void (*entry(void *parameter), void *parameter, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick)) 啓動線程 rt_err_t rt_thread_startup(rt_thread_t thread) 調用此函數後建立的線程會被加入到線程的就緒隊列,執行調度 rt_err_t thread_static_init() { rt_err_t result; result = rt_thread_init(&thread, "test", thread_entry, RT_NULL, &thread_stack[0], sizeof(thread_stack), THREAD_PRIORITY, 10); if (result == RT_EOK) rt_thread_startup(&thread); else tc_stat(TC_STAT_END | TC_STAT_FAILED); return result; } int thread_dynamic_init() { rt_thread_t tid; tid = rt_thread_create("test", thread_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (tid != RT_NULL) rt_thread_startup(tid); else tc_stat(TC_STAT_END | TC_STAT_FAILED); return 0; } rt_thread_delay(15); // 根據時鐘頻率決定。時鐘頻率100HZ,那麼一次delay 10ms.此處就未150ms rt_thread_sleep(15); rt_thread_mdelay(15); // delay 15ms
區別:ui
心跳時鐘由硬件定時器的定時中斷產生。稱之爲系統滴答或者時鐘節拍。其頻率須要根據CPU的處理能力來決定。始終街拍使得內核能夠將線程延時若干個時鐘節拍,以及線程等待時間發生時,超時的依據。頻率越快,內核函數介入系統運行的機率越大,內核佔用的處理器時間就越長,系統的負荷就越大。頻率越小,時間處理精度又不夠。在stm32平臺上通常設置系統滴答頻率爲100HZ,即每一個滴答的時間是10ms。在rtconfig.h中的RT_TICK_PER_SECOND宏,就是表明的HZ數操作系統
#include <rt_device.h> IO初始化 void rt_pin_mode(rt_base_t pin, rt_base_t mode) PIN_MODE_OUTPUT PIN_MODE_INPUT PIN_MODE_INPUT_PULLUP PIN_MODE_INPUT_PULLDOWN PIN_MODE_OUTPUT_OD IO寫入 void rt_pin_write(rt_base_t pin, rt_base_t value) PIN_HIGH PIN_LOW IO讀出 int rt_pin_read(rt_base_t pin) 首先經過看drv_gpio.c中的宏,得知咱們設置的芯片有多少個腳。再看__STM32_PIN(2, E, 4).那麼這裏傳入2,就表示要操做PE4引腳
使用msh中的命令:list_thread。列出當前全部線程的棧使用狀況
能夠先將線程棧大小設置一個固定值(好比2048),在線程運行時經過該命令查看線程棧的使用狀況,瞭解線程棧使用的實際狀況,根據狀況設置合理的大小。通常將線程棧最大使用量設置爲70%線程
分別描述了線程競爭處理器資源的能力和持有處理器時間長短的能力。RT-Thread最大支持256個優先級,數值越小優先級越高,0爲最高優先級,最低優先級保留給空閒線程idle。能夠經過rt_config.h中的RT_THREAD_PRIORITY_MAX宏,修改最大支持的優先級。針對STM32默認設置最大支持32個優先級。具體應用中,線程總數不受限制,能建立的線程總數之和具體硬件平臺的內存有關
只有在相同優先級的就緒態線程中起做用,時間片起到約束線程單次運行時長的做用,其單位是一個系統街拍(OS Tick)
當有高優先級線程處於就緒態後,就會發生任務調度
相同優先級的線程,操做系統按照時間片大小輪流調度線程,時間片起到約束線程單次運行時長的做用。保證同優先級任務輪流佔有處理器
特殊的系統線程,具備最低的優先級。系統中無其餘就緒線程可運行時,調度器將調度到空閒線程。空閒線程負責一些系統資源回收以及將一些處於關閉態的線程從線程調度列表中移除的動做。空閒線程在形式上是一個無限循環結構,且永遠不被掛起。在RT-Thread實時操做系統中空閒線程向用戶提供了鉤子函數,空閒線程鉤子函數能夠在系統空閒的時候,執行一些非緊急事務,例如系統運行指示燈閃爍,CPU使用率統計等等
rt_err_t rt_thread_idle_sethook(void(*hook)(void)) rt_err rt_thread_idle_delhook(void(*hook)(void))
注意:
系統上下文切換是最廣泛的時間,若是用戶想知道在某一個時刻發生了什麼樣的線程切換,RT-Thread提供了一個系統調度鉤子函數,這個鉤子函數在系統進行任務切換時運行,經過這個鉤子函數,能夠了解到系統任務調度時的信息
rt_scheduler_sethook(void(*hook)(struct rt_thread *from, struct rt_thread *to))
本文做者: CrazyCatJack
本文連接: https://www.cnblogs.com/CrazyCatJack/p/14408835.html
版權聲明:本博客全部文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
關注博主:若是您以爲該文章對您有幫助,能夠點擊文章右下角推薦一下,您的支持將成爲我最大的動力!