色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RT-Thread記錄(三、RT-Thread線程操作函數(shù))

矜辰所致 ? 來源:矜辰所致 ? 作者:矜辰所致 ? 2022-06-20 00:31 ? 次閱讀
前2課講完了RT-Thread開發(fā)環(huán)境,啟動(dòng)流程,啟動(dòng)以后當(dāng)然是開始跑線程了,那么自然我們得學(xué)會(huì)如何創(chuàng)建線程以及線程的有關(guān)操作。

目錄

前言
一、RT-Thread線程操作函數(shù)
1.1 動(dòng)態(tài)創(chuàng)建線程
1.2 靜態(tài)創(chuàng)建線程
1.3 啟動(dòng)線程
線程創(chuàng)建的一個(gè)細(xì)節(jié)—?jiǎng)?chuàng)建和初始化?
句柄是什么?
1.4 刪除線程和脫離線程
1.5 掛起和恢復(fù)線程
1.6 其他線程輔助函數(shù)
1.6.1 獲得當(dāng)前線程
1.6.2 讓出處理器資源
1.6.3 線程睡眠(延時(shí)函數(shù))
1.6.4 線程控制函數(shù)
1.6.5 設(shè)置和刪除空閑鉤子
1.6.6 設(shè)置調(diào)度器鉤子
二、RT-Thread線程創(chuàng)建示例
2.1 靜態(tài)創(chuàng)建線程示例
2.1 動(dòng)態(tài)創(chuàng)建線程示例
三、RT-Thread線程管理簡(jiǎn)析
3.1 線程調(diào)度的基本特點(diǎn)
3.2 線程控制塊
3.3 線程狀態(tài)
3.4 系統(tǒng)線程
結(jié)語

前言

前段時(shí)間寫完 RT-Thread 版本,開發(fā)環(huán)境,啟動(dòng)流程后,停了好一段時(shí)間,因?yàn)橥瓿闪饲懊?課的講解,感覺直接用起來都問題不大了,為啥,因?yàn)?a href="http://m.1cnz.cn/tags/RTOS/" target="_blank">RTOS的調(diào)度,線程通訊等機(jī)制,學(xué)習(xí)過FreeRTOS,看看RT-Thread官方的文檔說明,很多東西就很清楚了= =!以至于在寫本文的時(shí)候,都感覺,是不是太簡(jiǎn)單了?

但是后來又想了想:

1、本系列博文的目的在于總結(jié)記錄,為的是以后在項(xiàng)目中使用起來,我可以直接參考自己總結(jié)的博文,而不是去翻官方的文檔資料。
2、盡量使得沒有學(xué)習(xí)過 RT-Thread 的同學(xué)根據(jù)系列博文能夠?qū)?RT-Thread 有個(gè)認(rèn)識(shí),然后在一些細(xì)節(jié)的點(diǎn)上面有一定的理解,同時(shí)在遇到 RT-Thread 與 FreeRTOS不同的地方,會(huì)加以說明。
3、當(dāng)初的FreeRTOS系列,真就是很隨意的按照自己學(xué)習(xí)測(cè)試的流程來走,對(duì)小白來說并不友好,回頭看起來,雖然我是真的畫了精力和事件去說明遇到的問題以及解決辦法,但是少了循序漸進(jìn)的過程,整體也沒有一個(gè)好的框架體系,所以好像沒有幫到太多人(看的人不多哈= =?。?。所以在 RT-Thread 系列上面,該系統(tǒng)的還是得系統(tǒng)起來,即便有些東西簡(jiǎn)單基礎(chǔ),官方和網(wǎng)上文檔詳細(xì),當(dāng)做一個(gè)筆記,該記錄的還是得記錄!

好的,題外話說到這里,我們回到 RT-Thread 本身,上回我們已經(jīng)把啟動(dòng)流程講清楚了,
上文的最后講到:整個(gè)系統(tǒng)就正常跑起來了,然后用戶運(yùn)行自己想要做的事情,可以在 main 中設(shè)計(jì)自己的應(yīng)用代碼,或者創(chuàng)建線程。

所以我們接下來當(dāng)然得說說如何創(chuàng)建線程以及線程的一些操作。

本 RT-Thread 專欄記錄的開發(fā)環(huán)境:

RT-Thread記錄(一、RT-Thread 版本、RT-Thread Studio開發(fā)環(huán)境 及 配合CubeMX開發(fā)快速上手)

RT-Thread記錄(二、RT-Thread內(nèi)核啟動(dòng)流程 — 啟動(dòng)文件和源碼分析

一、RT-Thread線程操作函數(shù)

RT-Thread線程操作包含:創(chuàng)建 / 初始化線程、啟動(dòng)線程、運(yùn)行線程、刪除 / 脫離線程。

1.1 動(dòng)態(tài)創(chuàng)建線程

函數(shù)比較簡(jiǎn)單,具體的看注釋就好(本文余下的函數(shù)介紹類似,看注釋):

/*
demo,用來接收動(dòng)態(tài)線程返回的句柄
比如 led2_thread  = rt_thread_create(......);
*/
static rt_thread_t led2_thread = RT_NULL; 

#ifdef RT_USING_HEAP      					//定義使用了HEAP才能動(dòng)態(tài)創(chuàng)建線程
/*
參數(shù)的含義,放在上面看起來更加方便,要不然太長了
1、線程的名稱;線程名稱的最大長度由 rtconfig.h 中的宏 RT_NAME_MAX 指定,多余部分會(huì)被自動(dòng)截掉
2、線程入口函數(shù)
3、線程入口函數(shù)參數(shù),沒有就用 RT_NULL
4、線程棧大小,單位是字節(jié)
5、線程的優(yōu)先級(jí)。優(yōu)先級(jí)范圍根據(jù)系統(tǒng)配置情況(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定義),
如果支持的是 256 級(jí)優(yōu)先級(jí),那么范圍是從 0~255,數(shù)值越小優(yōu)先級(jí)越高,0 代表最高優(yōu)先級(jí)
6、線程的時(shí)間片大小。時(shí)間片(tick)的單位是操作系統(tǒng)時(shí)鐘節(jié)拍。
當(dāng)系統(tǒng)中存在相同優(yōu)先級(jí)線程時(shí),這個(gè)參數(shù)指定線程一次調(diào)度能夠運(yùn)行的最大時(shí)間長度。
這個(gè)時(shí)間片運(yùn)行結(jié)束時(shí),調(diào)度器自動(dòng)選擇下一個(gè)就緒態(tài)的同優(yōu)先級(jí)線程進(jìn)行運(yùn)行
返回值:
線程創(chuàng)建成功,返回線程句柄
線程創(chuàng)建失敗,返回RT_BULL 
*/
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)

1.2 靜態(tài)創(chuàng)建線程

static struct rt_thread led1_thread;   //demo,用戶定義的線程句柄
static char led1_thread_stack[256];    //demo,用戶定義的靜態(tài)線程大小
/*
參數(shù)的含義
1、線程句柄。線程句柄由用戶提供出來,并指向?qū)?yīng)的線程控制塊內(nèi)存地址,上面的led1_thread。
2、線程的名稱;線程名稱的最大長度由 rtconfig.h 中定義的 RT_NAME_MAX 宏指定,多余部分會(huì)被自動(dòng)截掉
3、線程入口函數(shù)
4、線程入口函數(shù)參數(shù),沒有就用 RT_NULL
5、線程棧起始地址,根據(jù)上面定義就是 &led1_thread_stack[0],
6、線程棧大小,單位是字節(jié)。根據(jù)上面定義就是 sizeof(led1_thread_stack),
在大多數(shù)系統(tǒng)中需要做??臻g地址對(duì)齊(例如 ARM 體系結(jié)構(gòu)中需要向 4 字節(jié)地址對(duì)齊)
7、線程的優(yōu)先級(jí)。優(yōu)先級(jí)范圍根據(jù)系統(tǒng)配置情況(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定義),
如果支持的是 256 級(jí)優(yōu)先級(jí),那么范圍是從 0~255,數(shù)值越小優(yōu)先級(jí)越高,0 代表最高優(yōu)先級(jí)
8、線程的時(shí)間片大小。時(shí)間片(tick)的單位是操作系統(tǒng)的時(shí)鐘節(jié)拍。
當(dāng)系統(tǒng)中存在相同優(yōu)先級(jí)線程時(shí),這個(gè)參數(shù)指定線程一次調(diào)度能夠運(yùn)行的最大時(shí)間長度。
這個(gè)時(shí)間片運(yùn)行結(jié)束時(shí),調(diào)度器自動(dòng)選擇下一個(gè)就緒態(tài)的同優(yōu)先級(jí)線程進(jìn)行運(yùn)行
返回值:
線程創(chuàng)建成功,返回RT_EOK
線程創(chuàng)建失敗,返回RT_ERROR 	
*/
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);

這里需要說明一下,為什么用戶定義一個(gè) char 類型的數(shù)組可以作為線程??臻g呢?

因?yàn)樯暾?qǐng)一個(gè)全局變量的數(shù)組,本質(zhì)就是開辟了一段連續(xù)的內(nèi)存空間!這是用戶申請(qǐng)的,所以在編譯的時(shí)候就被確定分配好了,這段內(nèi)存空間申請(qǐng)出來,通過rt_thread_init函數(shù),就分配給了這個(gè)線程使用。

如果知道了上面的話,但是還不能理解內(nèi)存空間和線程有什么關(guān)系的時(shí)候,這個(gè)就得慢慢來……簡(jiǎn)單來說就是,線程運(yùn)行需要占用一段內(nèi)存空間,這段內(nèi)存空間每個(gè)線程的都不一樣,他們是用來線程運(yùn)行的時(shí)候,函數(shù)調(diào)用線程切換保存現(xiàn)場(chǎng)用的。
反正先記住必須給每個(gè)線程單獨(dú)的一片內(nèi)存空間,RTOS才能正常運(yùn)行,所有的RTOS都是。
動(dòng)態(tài)創(chuàng)建同樣的意思,只不過你看不到,由內(nèi)核函數(shù)自動(dòng)處理了就沒那么直觀。


在上面示例代碼中,256個(gè)char類型的數(shù)組,就是占用256個(gè)字節(jié)(char類型占用1個(gè)字節(jié)),所以最后分配給線程的空間就是256個(gè)字節(jié)。

1.3 啟動(dòng)線程

創(chuàng)建完線程并不代表線程就運(yùn)行了,在RT-Thread稱為初始狀態(tài),要跑起來需要人為的給他“開”一下,這里與FreeRTOS創(chuàng)建任務(wù)后是不同的,F(xiàn)reeRTOS是直接創(chuàng)建完成就開始運(yùn)行參與調(diào)度了。

創(chuàng)建的線程狀態(tài)處于初始狀態(tài),并未進(jìn)入就緒線程的調(diào)度隊(duì)列,我們可以在線程創(chuàng)建成功后調(diào)用rt_thread_startup函數(shù)接口讓該線程進(jìn)入就緒態(tài):

/*
static rt_thread_t led2_thread = RT_NULL;
static struct rt_thread led1_thread;
上面的兩個(gè)demo就是:
rt_thread_startup(&led1_thread);
rt_thread_startup(led2_thread);
*/
rt_err_t rt_thread_startup(rt_thread_t thread);

這里又有一個(gè)小細(xì)節(jié)需要說明一下,動(dòng)態(tài)和靜態(tài)創(chuàng)建線程的rt_thread_startup使用的小區(qū)別!

上面代碼的注釋中,兩個(gè)Demo:
一個(gè)是rt_thread_startup(&led1_thread);(靜態(tài))
一個(gè)是rt_thread_startup(led2_thread);(動(dòng)態(tài))

靜態(tài)線程為什么需要取地址,動(dòng)態(tài)可以直接用,不仔細(xì)看的話還不一定發(fā)現(xiàn)這個(gè)問題, 其實(shí)從他們的定義就已經(jīng)不同了,只不過rt_thread_t 和rt_thread 一眼看去還真可能傻傻分不清楚 = =!以前我剛用的時(shí)候也在這里迷糊了一會(huì)


static struct rt_thread led1_thread 靜態(tài)類型為struct rt_thread 類型就是線程控制塊結(jié)構(gòu)體
static rt_thread_t led2_thread 動(dòng)態(tài)類型為rt_thread_t 類型是一個(gè)指針,如下解釋:

rt_thread_t這個(gè)類型他是經(jīng)過 typedef 重名命的:

pYYBAGKugY6AFcjLAAA33jozQiM609.png

所以回到開始的問題,搞清楚了rt_thread_startup 函數(shù)的參數(shù)是線程控制塊結(jié)構(gòu)體指針, 再結(jié)合動(dòng)態(tài)靜態(tài)創(chuàng)建線程的線程句柄定義,這么問題就清楚了!明白了這個(gè),那么這里又可以說明一個(gè)細(xì)節(jié)問題!如下

線程創(chuàng)建的一個(gè)細(xì)節(jié)—?jiǎng)?chuàng)建和初始化?

在文中,我介紹API使用的標(biāo)題是“動(dòng)態(tài)創(chuàng)建線程” 和“靜態(tài)創(chuàng)建線程”,個(gè)人認(rèn)為看上去好理解,也沒問題,但是這里注意官方的用語:

動(dòng)態(tài)是 – 創(chuàng)建和刪除線程
靜態(tài)是 – 初始化和脫離線程

說白了都是新建線程,但是用詞卻不一樣,為什么動(dòng)態(tài)用創(chuàng)建,而靜態(tài)用初始化呢?帶著疑問我們回頭再去看看兩種方式的不同。
在使用rt_thread_init之前,我們需要定義兩個(gè)東西,一個(gè)結(jié)構(gòu)體,一個(gè)數(shù)組:

static struct rt_thread led1_thread;   //demo,用戶定義的線程句柄
static char led1_thread_stack[256];    //demo,用戶定義的靜態(tài)線程大小

在編譯的時(shí)候,這個(gè)結(jié)構(gòu)體和數(shù)組,就被分配了一定的內(nèi)存空間,這段空間默認(rèn)一般是初始化為0,就是空間給你留著了,但是等著你去放數(shù)據(jù)。不管在程序后面使不使用rt_thread_init,這段空間都已經(jīng)存在了的! 這樣來說,調(diào)用rt_thread_init只是對(duì)已經(jīng)存在的一段內(nèi)存空間的賦值,對(duì)一個(gè)存在的東西的設(shè)置,不就是叫做 初始化嗎。所以使用靜態(tài)的創(chuàng)建嚴(yán)格的來說,更應(yīng)該稱之為初始化線程!

而在使用rt_thread_create之前,我們只需要定義一個(gè)rt_thread_t 類型的指針,初始化是NULL就沒有了,只有在調(diào)用rt_thread_create成功之后,才會(huì)開辟出一塊存放線程控制塊的內(nèi)存空間,從無到有的一個(gè)過程,所以叫做 創(chuàng)建。

不得不佩服,官方還是用詞嚴(yán)謹(jǐn),其實(shí)想想也能更好的理解函數(shù)功能!

句柄是什么?

講到這里,為了讓有些小伙伴更容易看懂,我們?cè)俨逡粋€(gè)細(xì)節(jié),我們經(jīng)常聽到返回句柄,函數(shù)句柄,任務(wù)句柄,那么句柄是什么?

記住一句話:句柄其實(shí)就是指針,它是指向指針的指針。

在我們的rt_thread_create函數(shù)中,如果成功返回值是 線程句柄,類型為rt_thread_t ,我們前面又講過rt_thread_t 是一個(gè)結(jié)構(gòu)體指針,這個(gè)結(jié)構(gòu)體是線程控制塊結(jié)構(gòu)體,所以 在上面示例代碼中返回句柄的意思 ,就是返回了一個(gè)指針,這個(gè)指針指向線程控制塊。

(如果指針,指向指針的指針不明白,這是C語言基礎(chǔ)知識(shí),可以查看相關(guān)資料,我有一篇博文也提到過一二:C語言學(xué)習(xí)點(diǎn)滴筆記 中 4、指針: 一種特殊的變量 和 多元指針,指向指針的指針)

1.4 刪除線程和脫離線程

針對(duì)上面動(dòng)態(tài)靜態(tài)方法創(chuàng)建的線程,RT-Thread 有不同的刪除函數(shù):
對(duì)于使用rt_thread_create動(dòng)態(tài)創(chuàng)建的線程,我們使用rt_thread_delete函數(shù),如下:

/*
參數(shù):thread 	要?jiǎng)h除的線程句柄
返回值:
RT_EOK 		刪除線程成功
-RT_ERROR 	刪除線程失敗
*/
rt_err_t rt_thread_delete(rt_thread_t thread);

調(diào)用該函數(shù)后,線程對(duì)象將會(huì)被移出線程隊(duì)列并且從內(nèi)核對(duì)象管理器中刪除,線程占用的堆??臻g也會(huì)被釋放。實(shí)際上,用 rt_thread_delete() 函數(shù)刪除線程接口,僅僅是把相應(yīng)的線程狀態(tài)更改為 RT_THREAD_CLOSE 狀態(tài),然后放入到 rt_thread_defunct 隊(duì)列中;而真正的刪除動(dòng)作(釋放線程控制塊和釋放線程棧)需要到下一次執(zhí)行空閑線程時(shí),由空閑線程完成最后的線程刪除動(dòng)作。

對(duì)于使用rt_thread_init 靜態(tài)創(chuàng)建的線程,我們使用rt_thread_detach 函數(shù),如下:

/*
參數(shù):線程句柄,它應(yīng)該是由 rt_thread_init 進(jìn)行初始化的線程句柄。
返回值:
RT_EOK 		線程脫離成功
-RT_ERROR  	線程脫離失敗
*/
rt_err_t rt_thread_detach (rt_thread_t thread);

官方在介紹rt_thread_detach有一句話,同樣,線程本身不應(yīng)調(diào)用這個(gè)接口脫離線程本身。這句話我理解就是不管動(dòng)態(tài)刪除還是靜態(tài)刪除,不能在線程函數(shù)中自己把自己刪除。
這里也與FreeRTOS任務(wù)后不同,F(xiàn)reeRTOS可以直接在任務(wù)中調(diào)用函數(shù)刪除自己。

但是需要特別說明的是,在 RT-Thread 中執(zhí)行完畢的線程系統(tǒng)會(huì)自動(dòng)將其刪除!用戶無需多余操作,如何理解呢,看下面的例子:

我們一般線程函數(shù)都是死循環(huán),通過延時(shí)釋放CPU控制權(quán),比如:

static void led1_thread_entry(void *par){
    while(1){   		
        //do_something
        rt_thread_mdelay(100);
    }
}

我們需要?jiǎng)h除的線程往往只是為了做某一件事,某一次特殊的事情,比如:

static void this_is_a_need_delete_task(void *par){ 	
  			//do_one_time_thing
}

其實(shí)這個(gè)線程是為了某一件特殊事情而創(chuàng)建的,它是需要?jiǎng)h除的,我們并不需要做任何特殊處理,因?yàn)閳?zhí)行是沒有循環(huán)的,執(zhí)行完成以后,RT-Thread 內(nèi)核會(huì)自動(dòng)把線程刪除!!

1.5 掛起和恢復(fù)線程

線程掛起和恢復(fù),在官方有單獨(dú)的說明:

poYBAGKugY-AHofUAADH8yWiUeU475.png

既然官方強(qiáng)烈不建議在程序中使用該接口,我們這里就不說明了,因?yàn)橐詰?yīng)用為主,我們就不去用了。

需要說明的一點(diǎn)是,這里和FreeRTOS也是不同的,F(xiàn)reeRTOS用戶可以隨意用,最典型的就是使一段代碼進(jìn)入臨界區(qū)掛起其他任務(wù)。

1.6 其他線程輔助函數(shù)

其他的線程輔助函數(shù),除了線程睡眠函數(shù),其他的在一般的應(yīng)用中都可以不需要。所以我們簡(jiǎn)單的過一遍,引用一下官方的介紹。如果后期應(yīng)用的時(shí)候有用到,再來加以詳細(xì)說明:

1.6.1 獲得當(dāng)前線程

在程序的運(yùn)行過程中,相同的一段代碼可能會(huì)被多個(gè)線程執(zhí)行,在執(zhí)行的時(shí)候可以通過下面的函數(shù)接口獲得當(dāng)前執(zhí)行的線程句柄,把下面的函數(shù)加在這段代碼中的,哪個(gè)線程調(diào)用就返回哪個(gè)線程句柄:

/*
返回值
thread 	當(dāng)前運(yùn)行的線程句柄
RT_NULL 	失敗,調(diào)度器還未啟動(dòng)
*/
rt_thread_t rt_thread_self(void);

1.6.2 讓出處理器資源

rt_err_t rt_thread_yield(void);

調(diào)用該函數(shù)后,當(dāng)前線程首先把自己從它所在的就緒優(yōu)先級(jí)線程隊(duì)列中刪除,然后把自己掛到這個(gè)優(yōu)先級(jí)隊(duì)列鏈表的尾部,然后激活調(diào)度器進(jìn)行線程上下文切換(如果當(dāng)前優(yōu)先級(jí)只有這一個(gè)線程,則這個(gè)線程繼續(xù)執(zhí)行,不進(jìn)行上下文切換動(dòng)作)。

1.6.3 線程睡眠(延時(shí)函數(shù))

線程睡眠,直白點(diǎn)說,就是延時(shí)函數(shù),只不過RTOS中的延時(shí)函數(shù),是會(huì)釋放CPU使用權(quán)的,釋放CPU使用權(quán),就等于線程睡眠了。

/*
參數(shù):tick/ms 	
線程睡眠的時(shí)間:sleep/delay 的傳入?yún)?shù) tick 以 1 個(gè) OS Tick 為單位 ;
mdelay 的傳入?yún)?shù) ms 以 1ms 為單位;
返回
RT_EOK 	操作成功,一般不需要
*/
rt_err_t rt_thread_sleep(rt_tick_t tick);
rt_err_t rt_thread_delay(rt_tick_t tick);
rt_err_t rt_thread_mdelay(rt_int32_t ms);

1.6.4 線程控制函數(shù)

/*
參數(shù)說明:
1、thread 	線程句柄
2、cmd 	指示控制命令
cmd 當(dāng)前支持的命令包括:
?RT_THREAD_CTRL_CHANGE_PRIORITY:動(dòng)態(tài)更改線程的優(yōu)先級(jí);
?RT_THREAD_CTRL_STARTUP:開始運(yùn)行一個(gè)線程,等同于 rt_thread_startup() 函數(shù)調(diào)用;
?RT_THREAD_CTRL_CLOSE:關(guān)閉一個(gè)線程,
等同于 rt_thread_delete() 或 rt_thread_detach() 函數(shù)調(diào)

用。
3、arg 	控制參數(shù)
返回值:
RT_EOK 		控制執(zhí)行正確
-RT_ERROR 	失敗
*/
rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg);

1.6.5 設(shè)置和刪除空閑鉤子

空閑鉤子函數(shù)是空閑線程的鉤子函數(shù)(不要和調(diào)度器鉤子函數(shù)搞混了),如果設(shè)置了空閑鉤子函數(shù),就可以在系統(tǒng)執(zhí)行空閑線程時(shí),自動(dòng)執(zhí)行空閑鉤子函數(shù)來做一些其他事情,比如系統(tǒng)指示燈。設(shè)置 / 刪除空閑鉤子的接口如下:

/*
參數(shù):
hook 	設(shè)置的鉤子函數(shù),在函數(shù)中實(shí)現(xiàn)一些操作,但是不要有掛起操作
返回值:
RT_EOK 	設(shè)置成功
-RT_EFULL 	設(shè)置失敗
*/
rt_err_t rt_thread_idle_sethook(void (*hook)(void));
rt_err_t rt_thread_idle_delhook(void (*hook)(void));

官方有一段注意說明如下:

pYYBAGKugY-ABrtwAACBToveT2k280.png

1.6.6 設(shè)置調(diào)度器鉤子

在整個(gè)系統(tǒng)的運(yùn)行時(shí),系統(tǒng)都處于線程運(yùn)行、中斷觸發(fā) - 響應(yīng)中斷、切換到其他線程,甚至是線程間的切換過程中,或者說系統(tǒng)的上下文切換是系統(tǒng)中最普遍的事件。有時(shí)用戶可能會(huì)想知道在一個(gè)時(shí)刻發(fā)生了什么樣的線程切換,可以通過調(diào)用下面的函數(shù)接口設(shè)置一個(gè)相應(yīng)的鉤子函數(shù)。在系統(tǒng)線程切換時(shí),這個(gè)鉤子函數(shù)將被調(diào)用:

/*
參數(shù):
hook 	表示用戶定義的鉤子函數(shù)指針
*/
void rt_scheduler_sethook(void (*hook)(struct rt_thread* from, struct rt_thread* to));
/*
鉤子函數(shù) hook() 的聲明
參數(shù)說明:
1、from 	表示系統(tǒng)所要切換出的線程控制塊指針
2、to 	表示系統(tǒng)所要切換到的線程控制塊指針
*/
void hook(struct rt_thread* from, struct rt_thread* to);

————————————————
版權(quán)聲明:本文為CSDN博主「矜辰所致」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_42328389/article/details/123440027

注:請(qǐng)仔細(xì)編寫你的鉤子函數(shù),稍有不慎將很可能導(dǎo)致整個(gè)系統(tǒng)運(yùn)行不正常(在這個(gè)鉤子函數(shù)中,基本上不允許調(diào)用系統(tǒng) API,更不應(yīng)該導(dǎo)致當(dāng)前運(yùn)行的上下文掛起)。

二、RT-Thread線程創(chuàng)建示例

雖然上面介紹了有一部分的線程操作函數(shù),但是正常需要也就前面幾個(gè),記住線程創(chuàng)建,啟動(dòng),一般的應(yīng)用就足夠了,其他的一些輔助函數(shù)在實(shí)際中有很多情況是出了問題以后找 bug 的時(shí)候才會(huì)想起來。

所以我們演示起來也很簡(jiǎn)單,還記得在 RT-Thread記錄 第一篇文章中:

RT-Thread記錄(一、RT-Thread 版本、RT-Thread Studio開發(fā)環(huán)境 及 配合CubeMX開發(fā)快速上手)

在上面博文的最后一節(jié):3.3 創(chuàng)建一個(gè)跑馬燈任務(wù) 我上傳了一段源碼,這里我就不再重復(fù)上一邊了,我們直接通過截圖說明的方式講解下示例:

2.1 靜態(tài)創(chuàng)建線程示例

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

2.1 動(dòng)態(tài)創(chuàng)建線程示例

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

三、RT-Thread線程管理簡(jiǎn)析

經(jīng)過上面的說明,我們其實(shí)能夠使用 RT-Thread 對(duì)于的函數(shù)創(chuàng)建線程進(jìn)行一般的設(shè)計(jì)了,但是為了加深對(duì)RT-Thread的理解,我們還得聊聊 RT-Thread線程管理。

這一塊在官網(wǎng)其實(shí)有詳細(xì)的說明,官方的鏈接如下:RT-Thread官方文檔 RT-Thread內(nèi)核線程管理

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

3.1 線程調(diào)度的基本特點(diǎn)

我這邊按照自己的理解認(rèn)知記錄幾個(gè)重要的點(diǎn):

1、RT-Thread 的線程調(diào)度器是搶占式的,主要的工作就是從就緒線程列表中查找最高優(yōu)先級(jí)線程,保證最高優(yōu)先級(jí)的線程能夠被運(yùn)行,最高優(yōu)先級(jí)的任務(wù)一旦就緒,總能得到 CPU 的使用權(quán)。

調(diào)度器開啟以后,就不停的在查詢列表,所有的線程根據(jù)優(yōu)先級(jí),狀態(tài),在列表中排序,調(diào)度器總是找到排序“第一位”的線程執(zhí)行。RTOS的核心就是鏈表,這個(gè)有時(shí)間會(huì)單獨(dú)的介紹。

2、當(dāng)一個(gè)運(yùn)行著的線程使一個(gè)比它優(yōu)先級(jí)高的線程滿足運(yùn)行條件,當(dāng)前線程的 CPU 使用權(quán)就被剝奪了,或者說被讓出了,高優(yōu)先級(jí)的線程立刻得到了 CPU 的使用權(quán)。

如果是中斷服務(wù)程序使一個(gè)高優(yōu)先級(jí)的線程滿足運(yùn)行條件,中斷完成時(shí),被中斷的線程掛起,優(yōu)先級(jí)高的線程開始運(yùn)行。

還是上面說到的調(diào)度器的作用,使得高優(yōu)先級(jí)的能夠及時(shí)執(zhí)行。

3、當(dāng)調(diào)度器調(diào)度線程切換時(shí),先將當(dāng)前線程上下文保存起來,當(dāng)再切回到這個(gè)線程時(shí),線程調(diào)度器將該線程的上下文信息恢復(fù)。
RT-Thread 線程具有獨(dú)立的棧,當(dāng)進(jìn)行線程切換時(shí),會(huì)將當(dāng)前線程的上下文存在棧中,當(dāng)線程要恢復(fù)運(yùn)行時(shí),再從棧中讀取上下文信息,進(jìn)行恢復(fù)。

要理解上面的話,推薦一篇博文:
FreeRTOS記錄(三、FreeRTOS任務(wù)調(diào)度原理解析_Systick、PendSV、SVC)
雖然說的是FreeRTOS的,但是都是基于Cortex-M內(nèi)核的,原理機(jī)制類似。

4、每個(gè)線程都有時(shí)間片這個(gè)參數(shù),但時(shí)間片僅對(duì)優(yōu)先級(jí)相同的就緒態(tài)線程有效。

時(shí)間片只有在優(yōu)先級(jí)相同的線程間會(huì)根據(jù)用戶的設(shè)置進(jìn)行對(duì)應(yīng)的分配。

5、線程中不能陷入死循環(huán)操作,必須要有讓出 CPU 使用權(quán)的動(dòng)作,如循環(huán)中調(diào)用延時(shí)函數(shù)或者主動(dòng)掛起。

使用rtos延時(shí)函數(shù),是實(shí)際使用最常見的一種方式,切記,delay是需要在while(1){}大括號(hào)里面的:

pYYBAGKugZCAFA24AAA7uJ1Dcwk673.png

3.2 線程控制塊

在我們上面介紹線程操作函數(shù)的時(shí)候,經(jīng)常提到一個(gè)詞語,線程控制塊,線控控制塊結(jié)構(gòu)體,RT-Thread 內(nèi)核對(duì)于線程的管理,都是基于這個(gè)結(jié)構(gòu)體進(jìn)行的。這里我們先有個(gè)基本的認(rèn)識(shí),如果真的深入探討,還是要說到RTOS的鏈表,需要單獨(dú)的開篇博文說明。

我們現(xiàn)在要了解的是,內(nèi)核對(duì)于線程的管理是通過這個(gè)線程控制塊結(jié)構(gòu)體,里面包括 RT-Thread線程所有的“屬性”,對(duì)這些屬性的查看,修改就可以對(duì)實(shí)現(xiàn)對(duì)這個(gè)線程的管理控制。

我們來看看控制塊結(jié)構(gòu)體(不是直接復(fù)制官網(wǎng)的哦?。?/p>

/** * Thread structure */struct rt_thread{    /* rt object */    char        name[RT_NAME_MAX];        /**< the name of thread 線程名稱*/    rt_uint8_t  type;                     /**< type of object 對(duì)象類型*/    rt_uint8_t  flags;                    /**< thread's flags 標(biāo)志位*/#ifdef RT_USING_MODULE    void       *module_id;                /**< id of application module */#endif    rt_list_t   list;                     /**< the object list 對(duì)象列表*/    rt_list_t   tlist;                    /**< the thread list 線程列表*/    /* stack point and entry 棧指針與入口指針*/    void       *sp;                       /**< stack point 棧指針*/    void       *entry;                    /**< entry 入口函數(shù)指針*/    void       *parameter;                /**< parameter 參數(shù)*/    void       *stack_addr;               /**< stack address 棧地址指針 */    rt_uint32_t stack_size;               /**< stack size 棧大小*/    /* error code */    rt_err_t    error;                    /**< error code 線程錯(cuò)誤代碼*/    rt_uint8_t  stat;                     /**< thread status 線程狀態(tài) */#ifdef RT_USING_SMP           		 /*多核相關(guān)支持,我們這里就一個(gè)M3內(nèi)核*/    rt_uint8_t  bind_cpu;                /**< thread is bind to cpu */    rt_uint8_t  oncpu;                   /**< process on cpu` */    rt_uint16_t scheduler_lock_nest;        /**< scheduler lock count */    rt_uint16_t cpus_lock_nest;             /**< cpus lock count */    rt_uint16_t critical_lock_nest;         /**< critical lock count */#endif /*RT_USING_SMP*/    /* priority 優(yōu)先級(jí)*/    rt_uint8_t  current_priority;           /**< current priority 當(dāng)前優(yōu)先級(jí) */    rt_uint8_t  init_priority;              /**< initialized priority 初始優(yōu)先級(jí) */#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 */#ifndef RT_USING_SMP					/*多核相關(guān)支持,我們這里就一個(gè)M3內(nèi)核*/    void            *sig_ret;           /**< the return stack pointer from signal */#endif    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 線程初始化計(jì)數(shù)值*/    rt_ubase_t  remaining_tick;         /**< remaining tick 線程剩余計(jì)數(shù)值*/    struct rt_timer thread_timer;       /**< built-in thread timer 內(nèi)置線程定時(shí)器*/     /**< cleanup function when thread exit      線程退出清除函數(shù)     cleanup 函數(shù)指針指向的函數(shù),會(huì)在線程退出的時(shí)候,被idle 線程回調(diào)一次,     執(zhí)行用戶的清理現(xiàn)場(chǎng)工作。     */    void (*cleanup)(struct rt_thread *tid);      /* light weight process if present */#ifdef RT_USING_LWP    void        *lwp;#endif    rt_ubase_t user_data;      /**< private user data beyond this thread  用戶數(shù)據(jù)*/};typedef struct rt_thread *rt_thread_t;

3.3 線程狀態(tài)

線程的狀態(tài)我們借用官方的幾張圖,加以說明:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

來看看 RT-Thread 的任務(wù)狀態(tài):

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_20,color_FFFFFF,t_70,g_se,x_16

在上圖中除了今天我們介紹的線程操作函數(shù),還有一些函數(shù)還沒有介紹過,比如rt_sem_take(),rt_mutex_take(),rt_mb_recv() ,這是我們后期會(huì)介紹到的關(guān)于線程間通信的一些信號(hào)量,互斥量相關(guān)的函數(shù)。

作為對(duì)比,再來看看FreeRTOS 的任務(wù)狀態(tài):

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA55-c6L6w5omA6Ie0,size_1,color_FFFFFF,t_70,g_se,x_16

3.4 系統(tǒng)線程

在 RT-Thread 內(nèi)核中的系統(tǒng)線程有空閑線程和主線程。

空閑線程 IDLE線程:

空閑線程是系統(tǒng)創(chuàng)建的最低優(yōu)先級(jí)的線程,線程狀態(tài)永遠(yuǎn)為就緒態(tài)。當(dāng)系統(tǒng)中無其他就緒線程存在時(shí),調(diào)度器將調(diào)度到空閑線程,它通常是一個(gè)死循環(huán),且永遠(yuǎn)不能被掛起。這點(diǎn)其實(shí)所有RTOS都是一樣的。

但是,空閑線程在 RT-Thread 也有著它的特殊用途:

若某線程運(yùn)行完畢,系統(tǒng)將自動(dòng)刪除線程:自動(dòng)執(zhí)行 rt_thread_exit() 函數(shù),先將該線程從系統(tǒng)就緒隊(duì)列中刪除,再將該線程的狀態(tài)更改為關(guān)閉狀態(tài),不再參與系統(tǒng)調(diào)度,然后掛入 rt_thread_defunct 僵尸隊(duì)列(資源未回收、處于關(guān)閉狀態(tài)的線程隊(duì)列)中,最后空閑線程會(huì)回收被刪除線程的資源。

空閑線程也提供了接口來運(yùn)行用戶設(shè)置的鉤子函數(shù),在空閑線程運(yùn)行時(shí)會(huì)調(diào)用該鉤子函數(shù),適合鉤入功耗管理、看門狗喂狗等工作。

主線程:

在我們上一篇博文中介紹 RT-Thread 啟動(dòng)流程的時(shí)候,說到了系統(tǒng)啟動(dòng)會(huì)創(chuàng)建main線程:

pYYBAGKugZKAMPHcAAAbMTA-wqk588.png


FreeRTOS只有空閑線程,并不會(huì)創(chuàng)建主線程,所以在FreeRTOS中,一般在main() 之前開啟調(diào)度,永遠(yuǎn)不會(huì)執(zhí)行到main()。

結(jié)語

本文的主要目的是認(rèn)識(shí) RT-Thread 線程操作函數(shù),同時(shí)簡(jiǎn)單的說明了一下 RT-Thread 線程管理的一些要點(diǎn),說明了一下 RT-Thread 與 FreeRTOS 在線程操作某些地方的不同,此外還加了一些博主認(rèn)為的細(xì)節(jié)的問題, 希望懂的小伙伴可以多多指教,不懂的小伙伴看完還是不明白的可以留言。講得不好的地方還希望能夠指出,我一定加以修正。

總的來說,本文內(nèi)容還是比較簡(jiǎn)單的,小伙伴們可以開動(dòng)起來,線程創(chuàng)建跑起來玩玩。優(yōu)先級(jí),任務(wù)調(diào)度,線程死循環(huán)什么的情況都可以試試。更能加加深線程調(diào)度的理解。

下一篇 RT-Thread 記錄,我會(huì)講一講 RT-Thread 時(shí)鐘管理的內(nèi)容,系統(tǒng)時(shí)鐘,軟件定時(shí)器相關(guān)。

謝謝!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4332

    瀏覽量

    62651
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    505

    瀏覽量

    19693
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1291

    瀏覽量

    40164
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RT-Thread上CAN實(shí)踐

    開箱測(cè)試RT-Thread官方已完成了對(duì)英飛凌XMC7200EVK的移植,通過shell可以看到做好了uart3的console。本文將介紹如何進(jìn)行RT-ThreadCan移植。接下來我們要完成CAN_FD的驅(qū)動(dòng)移植,并正常啟動(dòng)RT-T
    的頭像 發(fā)表于 11-13 01:03 ?1193次閱讀
    <b class='flag-5'>RT-Thread</b>上CAN實(shí)踐

    開源共生 商業(yè)共贏 | RT-Thread 2024開發(fā)者大會(huì)報(bào)名啟動(dòng)!

    親愛的RT-Thread開發(fā)者我們很高興地宣布,一年一度的RDC(RT-ThreadDeveloperConference,RT-Thread開發(fā)者大會(huì))正式啟動(dòng)報(bào)名!2024RT-Threa
    的頭像 發(fā)表于 10-29 08:06 ?408次閱讀
    開源共生 商業(yè)共贏 | <b class='flag-5'>RT-Thread</b> 2024開發(fā)者大會(huì)報(bào)名啟動(dòng)!

    2024 RT-Thread全球巡回 線下培訓(xùn)火熱來襲!

    親愛的RT-Thread社區(qū)成員們:我們非常高興地宣布,2024年RT-Thread全球開發(fā)者線下培訓(xùn)即將拉開帷幕!24年全球巡回培訓(xùn)將覆蓋超10座城市及國家,為開發(fā)者提供一個(gè)深入學(xué)習(xí)RT-Thread嵌入式開發(fā)的絕佳機(jī)會(huì)。
    的頭像 發(fā)表于 08-07 08:35 ?1262次閱讀
    2024 <b class='flag-5'>RT-Thread</b>全球巡回 線下培訓(xùn)火熱來襲!

    【好書推薦】RT-Thread設(shè)備驅(qū)動(dòng)開發(fā)指南

    近年來國內(nèi)芯片產(chǎn)業(yè)和物聯(lián)網(wǎng)產(chǎn)業(yè)的快速崛起,行業(yè)發(fā)展迫切需要更多人才,尤其需要掌握嵌入式操作系統(tǒng)等底層技術(shù)的人才。隨著RT-Thread被更廣泛地應(yīng)用于行業(yè)中,開發(fā)者對(duì)嵌入式驅(qū)動(dòng)開發(fā)的需求越來越
    的頭像 發(fā)表于 08-01 08:35 ?648次閱讀
    【好書推薦】<b class='flag-5'>RT-Thread</b>設(shè)備驅(qū)動(dòng)開發(fā)指南

    RT-Thread 新里程碑達(dá)成——GitHub Star 破萬!

    RT-Thread實(shí)時(shí)操作系統(tǒng)開源項(xiàng)目在GitHub上的star數(shù)量突破一萬!截止發(fā)文,RT-Thread作為實(shí)時(shí)操作系統(tǒng)在業(yè)界Star數(shù)量排名第一!倉庫地址:https://gith
    的頭像 發(fā)表于 07-04 08:35 ?481次閱讀
    <b class='flag-5'>RT-Thread</b> 新里程碑達(dá)成——GitHub Star 破萬!

    基于 RT-Thread專業(yè)版的EtherCAT主站方案

    特點(diǎn)。在RT-Thread實(shí)時(shí)操作系統(tǒng)上運(yùn)行EtherCAT主站協(xié)議,大大提高了實(shí)時(shí)性,極大降低了循環(huán)同步抖動(dòng)時(shí)間,可滿足各種對(duì)實(shí)時(shí)性要求苛刻的應(yīng)用場(chǎng)景。以下是在瑞
    的頭像 發(fā)表于 06-19 08:35 ?937次閱讀
    基于 <b class='flag-5'>RT-Thread</b>專業(yè)版的EtherCAT主站方案

    6月6日杭州站RT-Thread線下workshop,探索RT-Thread混合部署新模式!

    6月6日下午我們將在杭州舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺(tái)上實(shí)現(xiàn)同時(shí)運(yùn)行RT-Thread和linux,本次workshop邀請(qǐng)到RT-Thread資深
    的頭像 發(fā)表于 05-28 08:35 ?451次閱讀
    6月6日杭州站<b class='flag-5'>RT-Thread</b>線下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    2024 RT-Thread 全球技術(shù)大會(huì)演講議程發(fā)布!

    RT-ThreadGlobalTechConference(RT-ThreadGTC,RT-Thread全球技術(shù)大會(huì))致力于圍繞RT-Thread基礎(chǔ)軟件技術(shù)發(fā)展、實(shí)踐創(chuàng)新、開發(fā)者能力
    的頭像 發(fā)表于 05-16 08:34 ?558次閱讀
    2024 <b class='flag-5'>RT-Thread</b> 全球技術(shù)大會(huì)演講議程發(fā)布!

    新書發(fā)布——《實(shí)時(shí)操作系統(tǒng)應(yīng)用技術(shù):RT-Thread與ARM編程實(shí)踐》

    RT-Thread又一本新書《實(shí)時(shí)操作系統(tǒng)應(yīng)用技術(shù)——基于RT-Thread與ARM的編程實(shí)踐》發(fā)布,標(biāo)志著RT-Thread生態(tài)和實(shí)時(shí)操作
    的頭像 發(fā)表于 05-11 08:35 ?809次閱讀
    新書發(fā)布——《實(shí)時(shí)<b class='flag-5'>操作</b>系統(tǒng)應(yīng)用技術(shù):<b class='flag-5'>RT-Thread</b>與ARM編程實(shí)踐》

    RT-Thread混合部署Workshop北京站來啦!

    4月25日,下午我們將在北京舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺(tái)上實(shí)現(xiàn)同時(shí)運(yùn)行RT-Thread和linux,本次workshop邀請(qǐng)到RT-Thread資深
    的頭像 發(fā)表于 04-19 08:34 ?449次閱讀
    <b class='flag-5'>RT-Thread</b>混合部署Workshop北京站來啦!

    4月25日北京站RT-Thread線下workshop,探索RT-Thread混合部署新模式

    4月25日,下午我們將在北京舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺(tái)上實(shí)現(xiàn)同時(shí)運(yùn)行RT-Thread和linux,本次workshop邀請(qǐng)到RT-Thread資深
    的頭像 發(fā)表于 04-16 08:35 ?424次閱讀
    4月25日北京站<b class='flag-5'>RT-Thread</b>線下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式

    4月10日深圳場(chǎng)RT-Thread線下workshop,探索RT-Thread混合部署新模式!

    4月10日我們將在深圳福田舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺(tái)上實(shí)現(xiàn)同時(shí)運(yùn)行RT-Thread和linux,本次workshop邀請(qǐng)到RT-Thread資深嵌入式軟件工程師農(nóng)曉明老師為您講
    的頭像 發(fā)表于 03-27 11:36 ?833次閱讀
    4月10日深圳場(chǎng)<b class='flag-5'>RT-Thread</b>線下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    4月10日深圳場(chǎng)RT-Thread線下workshop,探索RT-Thread混合部署新模式!

    4月10日我們將在深圳福田舉辦RT-Thread混合部署線下workshop,在瑞芯微RK3568平臺(tái)上實(shí)現(xiàn)同時(shí)運(yùn)行RT-Thread和linux,本次workshop邀請(qǐng)到RT-Thread資深
    的頭像 發(fā)表于 03-27 08:34 ?537次閱讀
    4月10日深圳場(chǎng)<b class='flag-5'>RT-Thread</b>線下workshop,探索<b class='flag-5'>RT-Thread</b>混合部署新模式!

    恩智浦半導(dǎo)體正式加入RT-Thread全球合作伙伴計(jì)劃!

    前不久,恩智浦半導(dǎo)體正式加入RT-Thread全球合作伙伴計(jì)劃,成為RT-Thread高級(jí)會(huì)員合作伙伴。同時(shí),RT-Thread現(xiàn)已成為恩智浦注冊(cè)合作伙伴(RT-Thread| 簡(jiǎn)介合
    的頭像 發(fā)表于 03-14 10:40 ?630次閱讀
    恩智浦半導(dǎo)體正式加入<b class='flag-5'>RT-Thread</b>全球合作伙伴計(jì)劃!

    RT-Thread設(shè)備驅(qū)動(dòng)開發(fā)指南基礎(chǔ)篇—以先楫bsp的hwtimer設(shè)備為例

    RT-Thread設(shè)備驅(qū)動(dòng)開發(fā)指南》書籍是RT-thread官方出品撰寫,系統(tǒng)講解RT-thread IO設(shè)備驅(qū)動(dòng)開發(fā)方法,從方面進(jìn)行講解。
    的頭像 發(fā)表于 02-20 16:01 ?1720次閱讀
    <b class='flag-5'>RT-Thread</b>設(shè)備驅(qū)動(dòng)開發(fā)指南基礎(chǔ)篇—以先楫bsp的hwtimer設(shè)備為例
    主站蜘蛛池模板: 亚洲精品一区国产欧美| 67194在线入口免费| 都市妖奇谈有声| 熟女人妻久久精品AV天堂| 国产日韩精品一区二区在线观看| 亚洲第一天堂无码专区| 久久免费精品一区二区| AV国产乱码一区二区三视频 | 久久99re8热在线播放| 97超级碰久久久久香蕉人人| 日欧一片内射VA在线影院| 狠狠色综合久久丁香婷婷| A级超碰视频在线观看| 午夜在线视频国产极品片| 狂野欧美性猛XXXX乱大交| 丰满少妇69激懒啪啪无码| 伊人久久大香| 色吧.com| 免费黄色网址在线观看| 国产午夜亚洲精品一区| a一级一片免费观看视频| 亚洲精品无码葡京AV天堂| 暖暖视频在线观看高清...| 国产亚洲AV精品无码麻豆| 99精品视频在线观看| 亚洲精品乱码久久久久久v | 日韩中文字幕欧美在线视频| 久久re热线视频精品99| 俄罗斯爱爱| 《乳色吐息》无删减版在线观看 | 亚洲精品久久久久69影院| 欧美极品尿交| 久久99国产精品自在自在| 国产成人精品免费青青草原app| 在线观看永久免费网站| 西施打开双腿下面好紧| 青娱乐在线一区| 乱码国产丰满人妻WWW| 国产一区二区高清| 国产AV无码熟妇人妻麻豆| bbwvideoa欧美老妇|