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

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

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

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

rt-thread心法系列(一)那些你必須知道的幾類(lèi) api

出出 ? 來(lái)源:出出 ? 作者:出出 ? 2022-07-08 08:49 ? 次閱讀

前言

多任務(wù)系統(tǒng),線程和中斷是兩個(gè)競(jìng)爭(zhēng)關(guān)系的各自獨(dú)立的實(shí)體。很多 api 是禁止在中斷中調(diào)用的。
和線程運(yùn)行息息相關(guān)的函數(shù),要求必須在任務(wù)調(diào)度運(yùn)行起來(lái)以后才能使用。
以及,一些 api 被設(shè)計(jì)出來(lái)是用來(lái)在某線程操作另外一個(gè)線程,是不可以某線程針對(duì)自己使用的。
今天就說(shuō)說(shuō)哪些 api 禁止在中斷中調(diào)用、哪些必須在任務(wù)調(diào)度器運(yùn)行以后才能使用、哪些不能線程用在自己身上。

禁止在中斷調(diào)用的 api 列表

內(nèi)存堆操作類(lèi)

rt_system_heap_init
rt_malloc
rt_realloc
rt_free

內(nèi)存池類(lèi)

rt_mp_create
rt_mp_delete
rt_mp_alloc

內(nèi)核對(duì)象類(lèi)

rt_object_allocate
rt_object_find

idle 線程

rt_defunct_execute

ipc 同步和消息機(jī)制類(lèi)

rt_sem_create
rt_sem_delete
rt_mutex_create
rt_mutex_trytake
rt_mutex_delete
rt_event_create
rt_event_delete
rt_mb_create
rt_mb_delete
rt_mq_create
rt_mq_delete

完成量

rt_completion_wait

隊(duì)列類(lèi)

rt_wqueue_wait
rt_data_queue_push
rt_data_queue_pop

延時(shí)

rt_thread_sleep
rt_thread_delay
rt_thread_delay_until
rt_thread_mdelay

注:源碼中摘錄,并無(wú)理論考證,更無(wú)實(shí)際驗(yàn)證

所有被禁止在中斷中調(diào)用的函數(shù)都有個(gè)相似的特征 —— 它可能是阻塞的,導(dǎo)致中斷無(wú)法短時(shí)間內(nèi)返回;或者它想調(diào)用可能發(fā)生阻塞的 api 。
任何引用了他們的函數(shù)也被帶跑了,不能在中斷中使用。

RT_DEBUG_NOT_IN_INTERRUPT 調(diào)試宏定義

rt-thread 定義了一個(gè)宏,當(dāng)我們開(kāi)啟調(diào)試的時(shí)候,它可以幫我檢查當(dāng)前函數(shù)是否被中斷調(diào)用了。其實(shí)現(xiàn)如下:

#define RT_DEBUG_NOT_IN_INTERRUPT                                             \
do                                                                            \
{                                                                             \
   rt_base_t level;                                                          \
   level = rt_hw_interrupt_disable();                                        \
   if (rt_interrupt_get_nest() != 0)                                         \
   {                                                                         \
       rt_kprintf("Function[%s] shall not be used in ISR\n", __FUNCTION__);  \
       RT_ASSERT(0)                                                          \
   }                                                                         \
   rt_hw_interrupt_enable(level);                                            \
}                                                                             \
while (0)

當(dāng)你在源碼里看見(jiàn)某個(gè)函數(shù)體中有一行

引用 RT_DEBUG_NOT_IN_INTERRUPT 調(diào)試宏的幾點(diǎn)問(wèn)題

1. rt-thread 中有多處引用了這個(gè)宏,上面函數(shù)列表里絕大部分有;
2. 有一些沒(méi)有,比如 memheap.c 文件中的 `rt_memheap_alloc` `rt_memheap_realloc` 等操作。
3. 仔細(xì)查看引用了 `RT_DEBUG_NOT_IN_INTERRUPT` 的所有函數(shù),有部分使用宏的地方真讓人揪心,以 `rt_defunct_execute` 函數(shù)為例:

   static void rt_defunct_execute(void)
   {
       // Loop until there is no dead thread. 
       // So one call to rt_defunct_execute
       // will do all the cleanups. */
       while (1)
       {
           register rt_base_t level;
           rt_thread_t thread;
           void (*cleanup)(struct rt_thread *tid);
#ifdef RT_USING_MODULE
           struct rt_dlmodule *module = RT_NULL;
#endif
           RT_DEBUG_NOT_IN_INTERRUPT;          // <<--

為什么放 while 里?不是 while 之前?不應(yīng)該放到函數(shù)開(kāi)頭醒目的地方嗎?有人反駁了啊,放哪兒不一樣,放哪也是一行代碼的事兒!
RT_DEBUG_IN_THREAD_CONTEXT 也有用樣的使用不當(dāng),放到某個(gè)判斷內(nèi)部,而不是函數(shù)開(kāi)頭就引用。
4. 那么我還有個(gè)疑問(wèn):這是 idle 線程的內(nèi)部調(diào)用的局部函數(shù),會(huì)被中斷調(diào)用了?!誰(shuí)有權(quán)限在中斷里引用它?!**`rt_defunct_execute` 函數(shù)應(yīng)該從上面的列表里刪除掉**,這個(gè)筆者已經(jīng)在 github 上 pr 修改過(guò)了

必須在線程上下文調(diào)用的 api 列表

信號(hào)

rt_signal_wait

ipc 同步和消息機(jī)制

rt_sem_take
rt_mutex_take
rt_mutex_release
rt_event_recv
rt_mb_send_wait
rt_mb_recv
rt_mq_send_wait
rt_mq_recv

線程操作類(lèi)

rt_thread_detach
rt_thread_delete
rt_thread_yield
rt_thread_delay
rt_thread_delay_until
rt_thread_mdelay
rt_thread_suspend
rt_thread_resume

其它

rt_tick_get
rt_enter_critical
rt_exit_critical

可以這么說(shuō),任務(wù)調(diào)度器啟動(dòng)前,只允許 init/create/startup 某線程。
雖然,沒(méi)有發(fā)現(xiàn)有誰(shuí)在任務(wù)調(diào)度器啟動(dòng)前調(diào)用 `rt_thread_suspend` ,但是,有一大批人想使用 `rt_thread_mdelay` 幾個(gè)延時(shí)函數(shù)。以上這幾個(gè)函數(shù)開(kāi)頭都應(yīng)該添加 `RT_DEBUG_IN_THREAD_CONTEXT` 檢測(cè),在源碼中用于明示此 api 的使用限制。

RT_DEBUG_IN_THREAD_CONTEXT 調(diào)試宏定義

首先,貼出來(lái)它的定義

#define RT_DEBUG_IN_THREAD_CONTEXT                                            \
   RT_DEBUG_NOT_IN_INTERRUPT;                                                \
do                                                                            \
{                                                                             \
   rt_base_t level;                                                          \
   level = rt_hw_interrupt_disable();                                        \
   if (rt_thread_self() == RT_NULL)                                          \
   {                                                                         \
       rt_kprintf("Function[%s] shall not be used before scheduler start\n", \
                  __FUNCTION__);                                             \
       RT_ASSERT(0)                                                          \
   }                                                                         \
   rt_hw_interrupt_enable(level);                                            \
}                                                                             \
while (0)
#else
#define RT_DEBUG_NOT_IN_INTERRUPT
#define RT_DEBUG_IN_THREAD_CONTEXT
#endif

注:此定義代碼略有改動(dòng)。

在線程上下文調(diào)用的函數(shù)有兩個(gè)特征:
1. 不能在中斷中調(diào)用。
2. 不能在任務(wù)調(diào)度器啟動(dòng)前調(diào)用,必須線程啟動(dòng)后,被線程入口函數(shù)調(diào)用。

因此,函數(shù)體中添加了此宏引用的函數(shù),也不能在中斷響應(yīng)過(guò)程中被調(diào)用。

鑒于此,本篇開(kāi)頭的***“禁止在中斷調(diào)用的 api 列表” 需要進(jìn)行擴(kuò)充,添加上 “必須在線程上下文調(diào)用的 api 列表” 中的所有 api***。

不能用在線程自己身上的 api

首先,這類(lèi) api 有個(gè)特征,那就是形參有個(gè) rt_thread_t 類(lèi)型參數(shù)

rt_thread_detach
rt_thread_delete

這倆不多說(shuō),一個(gè)針對(duì)靜態(tài)線程對(duì)象,一個(gè)針對(duì)動(dòng)態(tài)線程對(duì)象。作用均是退出線程、清理線程。當(dāng)前線程退出可以直接從 while 循環(huán)里跳出來(lái),從線程入口函數(shù) return 就可以。

`rt_thread_startup` 當(dāng)一個(gè)線程正在運(yùn)行的時(shí)候,它自己再 startup 自己是不是就很詭異了。

`rt_thread_resume` 線程掛起由得自己,喚醒就由不得自己了。

`rt_thread_control` 控制某線程的動(dòng)作可能有:改變優(yōu)先級(jí)、啟動(dòng)線程、關(guān)閉線程、以及多核cpu上綁定線程到某 cpu。某線程偷偷修改自己的運(yùn)行優(yōu)先級(jí)也說(shuō)得過(guò)去;自己想換個(gè) cpu 核心做依靠,看似也可以,但是,知道當(dāng)前核的感受嗎?有 cpu 資源可用已經(jīng)不錯(cuò)了,不是嗎?
因此,這個(gè) api 只能用來(lái)修改自己的優(yōu)先級(jí)。

特別的,目前 rt-thread 只支持當(dāng)前線程自己主動(dòng) suspend ,然后等待中斷或者其它線程 resume 它。而且,僅限于定時(shí)、線程間同步和通信機(jī)制里使用。不支持 A 線程 suspend B 線程,然后某個(gè)時(shí)機(jī)再 resume B。不支持 `rt_thread_suspend` `rt_thread_resume` 直接調(diào)用。
雖然 `rt_thread_detach` `rt_thread_delete` 用來(lái)退出線程,但是,不了解線程運(yùn)行機(jī)制,千萬(wàn)別隨意使用這倆函數(shù)退出其它線程。如果有需要,使用消息機(jī)制讓現(xiàn)在自己跳出線程入口函數(shù)的 while 循環(huán),自己從線程入口函數(shù)返回,這樣更安全可靠。

結(jié)束


感謝您的閱讀,歡迎各位提出意見(jiàn),對(duì)文中的不當(dāng)之處不吝賜教。

審核編輯:湯梓紅

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

    關(guān)注

    2

    文章

    1510

    瀏覽量

    62296
  • 多任務(wù)系統(tǒng)

    關(guān)注

    0

    文章

    11

    瀏覽量

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

    關(guān)注

    31

    文章

    1305

    瀏覽量

    40315
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RT-Thread記錄(、版本開(kāi)發(fā)環(huán)境及配合CubeMX)

    RT-Thread 學(xué)習(xí)記錄的第篇文章,RT-Thread記錄(RT-Thread 版本、RT-T
    的頭像 發(fā)表于 06-20 00:28 ?5316次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(<b class='flag-5'>一</b>、版本開(kāi)發(fā)環(huán)境及配合CubeMX)

    RT-Thread記錄(二、RT-Thread內(nèi)核啟動(dòng)流程)

    在前面我們RT-Thread Studio工程基礎(chǔ)之上講RT-Thread內(nèi)核啟動(dòng)流程.
    的頭像 發(fā)表于 06-20 00:30 ?5082次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(二、<b class='flag-5'>RT-Thread</b>內(nèi)核啟動(dòng)流程)

    【原創(chuàng)精選】RT-Thread征文精選技術(shù)文章合集

    rt-thread心法系列那些必須知道幾類(lèi)
    發(fā)表于 07-26 14:56

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開(kāi)發(fā)組(2015-03-31)。RT-Thread做為國(guó)內(nèi)有較大影響力的開(kāi)源實(shí)時(shí)操作系統(tǒng),本文是RT-Thread實(shí)時(shí)操作系統(tǒng)的編程指南
    發(fā)表于 11-26 16:06 ?0次下載

    RT-Thread AI kit開(kāi)源:輕松實(shí)現(xiàn)鍵部署AI模型至 RT-Thread

    RT-AK 是 RT-Thread 團(tuán)隊(duì)為 RT-Thread 實(shí)時(shí)操作系統(tǒng)所開(kāi)發(fā)的 AI 套件,能夠鍵將 AI 模型部署到 RT-Thread
    發(fā)表于 01-25 18:18 ?3次下載
    <b class='flag-5'>RT-Thread</b> AI kit開(kāi)源:輕松實(shí)現(xiàn)<b class='flag-5'>一</b>鍵部署AI模型至 <b class='flag-5'>RT-Thread</b>

    RT-Thread新版入門(mén)系列教程18講

    作為名 RTOS 的初學(xué)者,也許對(duì) RT-Thread 還比較陌生。然而,隨著的深入接觸,會(huì)逐漸發(fā)現(xiàn)
    發(fā)表于 01-25 20:00 ?0次下載
    <b class='flag-5'>RT-Thread</b>新版入門(mén)<b class='flag-5'>系列</b>教程18講

    rt-thread 心法系列(二) 使用寶典

    接觸 rt-thread 已有半年,混論壇也5個(gè)半月了,期間遇到過(guò)各種奇奇怪怪的棘手問(wèn)題,有過(guò)尷尬,也自信曾經(jīng)提供過(guò)比較妙的應(yīng)對(duì)方案。所以產(chǎn)生了將些典型的使用技巧匯總分享出來(lái)的想法,遂有此篇。
    的頭像 發(fā)表于 07-08 09:41 ?3244次閱讀
    <b class='flag-5'>rt-thread</b> <b class='flag-5'>心法系列</b>(二) 使用寶典

    RT-Thread學(xué)習(xí)筆記 RT-Thread的架構(gòu)概述

    RT-Thread 簡(jiǎn)介 作為名 RTOS 的初學(xué)者,也許對(duì) RT-Thread 還比較陌生。然而,隨著的深入接觸,
    的頭像 發(fā)表于 07-09 11:27 ?4595次閱讀
    <b class='flag-5'>RT-Thread</b>學(xué)習(xí)筆記 <b class='flag-5'>RT-Thread</b>的架構(gòu)概述

    RT-Thread文檔_RT-Thread 簡(jiǎn)介

    RT-Thread文檔_RT-Thread 簡(jiǎn)介
    發(fā)表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡(jiǎn)介

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南
    發(fā)表于 02-22 18:23 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發(fā)表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    基于RT-Thread Studio學(xué)習(xí)

    前期準(zhǔn)備:從官網(wǎng)下載 RT-Thread Studio,弄個(gè)賬號(hào)登陸,開(kāi)啟rt-thread學(xué)習(xí)之旅。
    的頭像 發(fā)表于 05-15 11:00 ?4092次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio學(xué)習(xí)

    怎么知道RT-Thread的CRYPTO設(shè)備對(duì)M2354支持怎樣呢?

    前面碰到了個(gè)問(wèn)題,RT-Thread 支持 MD5,可是 M2354 卻不支持,那怎么知道 RT-Thread 的 CRYPTO 設(shè)備對(duì) M2354 支持怎樣呢?
    的頭像 發(fā)表于 07-27 15:21 ?917次閱讀
    怎么<b class='flag-5'>知道</b><b class='flag-5'>RT-Thread</b>的CRYPTO設(shè)備對(duì)M2354支持怎樣呢?

    基于 RT-Thread 的 RoboMaster 電控框架(

    。但也正是因?yàn)檫@些優(yōu)點(diǎn)的覆蓋面較廣,很多初學(xué)者會(huì)覺(jué)得無(wú)從下手,但只要步入 RT-Thread 的大門(mén),就發(fā)現(xiàn)她的美好。這系列文檔將作為本人基于 RT-Thread 開(kāi)發(fā) RoboMa
    的頭像 發(fā)表于 09-19 19:55 ?806次閱讀

    RT-Thread v5.0.2 發(fā)布

    一系列令人激動(dòng)的變化和改進(jìn)。 以下是些亮點(diǎn)和關(guān)鍵變更: ?內(nèi)核改進(jìn): ●?新增了AMP支持。 ●?新增了消息隊(duì)列的消息優(yōu)先級(jí)。 ●?新增了rt_hw_interrupt_is_disabled
    的頭像 發(fā)表于 10-10 18:45 ?1546次閱讀
    <b class='flag-5'>RT-Thread</b> v5.0.2 發(fā)布
    主站蜘蛛池模板: 狠狠色欧美亚洲狠狠色www | 欧美午夜精品一区区电影 | 绿巨人www在线观看 绿巨人www | 第七色 夜夜撸 | 亚洲AV无码乱码国产麻豆穿越 | 亚洲视频国产 | 天美传媒在线观看免费完整版 | 伊人久久大香线蕉综合99 | 精品国产乱码久久久久久下载 | 国产曰批试看免费视频播放免费 | 纯肉腐文高H总受男男 | 97色伦久久视频在观看 | 小小水蜜桃免费影院 | 无码一区二区在线欧洲 | 92国产精品午夜免费福利视频 | 久久福利影院 | 欧美性情video sexo视频 | 久久精品一区二区影院 | 色播播电影 | 日本熟妇乱妇熟色在线电影 | 亚洲AV无码一区二区三区牛牛 | 97视频国产 | 2020亚洲色噜噜狠狠网站 | 视频一区视频二区在线观看 | 粗大分开挺进内射 | 欧美一级做a爰片免费 | 色婷婷国产精品视频一区二区 | 亚洲AV怡红院影院怡春院 | 99在线免费 | 国产永不无码精品AV永久 | 成人伦理影院 | 久久综合色悠悠 | 在线天天看片视频免费观看 | 美女打开双腿扒开屁股男生 | 亚洲AV色香蕉一区二区三区 | 第一会所欧美无码原创 | 国产精品美女久久久网站动漫 | 99视频这里只有精品国产 | 99热久久久无码国产精品性麻豆 | 麻豆沈芯语 | 国产午夜电影在线观看不卡 |