精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

出出 ? 來源:出出 ? 作者:出出 ? 2022-07-08 08:49 ? 次閱讀

前言

多任務系統,線程和中斷是兩個競爭關系的各自獨立的實體。很多 api 是禁止在中斷中調用的。
和線程運行息息相關的函數,要求必須在任務調度運行起來以后才能使用。
以及,一些 api 被設計出來是用來在某線程操作另外一個線程,是不可以某線程針對自己使用的。
今天就說說哪些 api 禁止在中斷中調用、哪些必須在任務調度器運行以后才能使用、哪些不能線程用在自己身上。

禁止在中斷調用的 api 列表

內存堆操作類

rt_system_heap_init
rt_malloc
rt_realloc
rt_free

內存池類

rt_mp_create
rt_mp_delete
rt_mp_alloc

內核對象類

rt_object_allocate
rt_object_find

idle 線程

rt_defunct_execute

ipc 同步和消息機制類

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

隊列類

rt_wqueue_wait
rt_data_queue_push
rt_data_queue_pop

延時

rt_thread_sleep
rt_thread_delay
rt_thread_delay_until
rt_thread_mdelay

注:源碼中摘錄,并無理論考證,更無實際驗證

所有被禁止在中斷中調用的函數都有個相似的特征 —— 它可能是阻塞的,導致中斷無法短時間內返回;或者它想調用可能發生阻塞的 api 。
任何引用了他們的函數也被帶跑了,不能在中斷中使用。

RT_DEBUG_NOT_IN_INTERRUPT 調試宏定義

rt-thread 定義了一個宏,當我們開啟調試的時候,它可以幫我檢查當前函數是否被中斷調用了。其實現如下:

#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)

當你在源碼里看見某個函數體中有一行

引用 RT_DEBUG_NOT_IN_INTERRUPT 調試宏的幾點問題

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

   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 之前?不應該放到函數開頭醒目的地方嗎?有人反駁了啊,放哪兒不一樣,放哪也是一行代碼的事兒!
RT_DEBUG_IN_THREAD_CONTEXT 也有用樣的使用不當,放到某個判斷內部,而不是函數開頭就引用。
4. 那么我還有個疑問:這是 idle 線程的內部調用的局部函數,會被中斷調用了?!誰有權限在中斷里引用它?!**`rt_defunct_execute` 函數應該從上面的列表里刪除掉**,這個筆者已經在 github 上 pr 修改過了

必須在線程上下文調用的 api 列表

信號

rt_signal_wait

ipc 同步和消息機制

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

線程操作類

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

可以這么說,任務調度器啟動前,只允許 init/create/startup 某線程。
雖然,沒有發現有誰在任務調度器啟動前調用 `rt_thread_suspend` ,但是,有一大批人想使用 `rt_thread_mdelay` 幾個延時函數。以上這幾個函數開頭都應該添加 `RT_DEBUG_IN_THREAD_CONTEXT` 檢測,在源碼中用于明示此 api 的使用限制。

RT_DEBUG_IN_THREAD_CONTEXT 調試宏定義

首先,貼出來它的定義

#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

注:此定義代碼略有改動。

在線程上下文調用的函數有兩個特征:
1. 不能在中斷中調用。
2. 不能在任務調度器啟動前調用,必須線程啟動后,被線程入口函數調用。

因此,函數體中添加了此宏引用的函數,也不能在中斷響應過程中被調用。

鑒于此,本篇開頭的***“禁止在中斷調用的 api 列表” 需要進行擴充,添加上 “必須在線程上下文調用的 api 列表” 中的所有 api***。

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

首先,這類 api 有個特征,那就是形參有個 rt_thread_t 類型參數

rt_thread_detach
rt_thread_delete

這倆不多說,一個針對靜態線程對象,一個針對動態線程對象。作用均是退出線程、清理線程。當前線程退出可以直接從 while 循環里跳出來,從線程入口函數 return 就可以。

`rt_thread_startup` 當一個線程正在運行的時候,它自己再 startup 自己是不是就很詭異了。

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

`rt_thread_control` 控制某線程的動作可能有:改變優先級、啟動線程、關閉線程、以及多核cpu上綁定線程到某 cpu。某線程偷偷修改自己的運行優先級也說得過去;自己想換個 cpu 核心做依靠,看似也可以,但是,知道當前核的感受嗎?有 cpu 資源可用已經不錯了,不是嗎?
因此,這個 api 只能用來修改自己的優先級。

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

結束


感謝您的閱讀,歡迎各位提出意見,對文中的不當之處不吝賜教。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • API
    API
    +關注

    關注

    2

    文章

    1485

    瀏覽量

    61817
  • 多任務系統
    +關注

    關注

    0

    文章

    11

    瀏覽量

    6867
  • RT-Thread
    +關注

    關注

    31

    文章

    1272

    瀏覽量

    39924
收藏 人收藏

    評論

    相關推薦

    RT-Thread記錄(、版本開發環境及配合CubeMX)

    RT-Thread 學習記錄的第篇文章,RT-Thread記錄(RT-Thread 版本、RT-T
    的頭像 發表于 06-20 00:28 ?5144次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(<b class='flag-5'>一</b>、版本開發環境及配合CubeMX)

    RT-Thread記錄(二、RT-Thread內核啟動流程)

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

    【原創精選】RT-Thread征文精選技術文章合集

    rt-thread心法系列那些必須知道幾類
    發表于 07-26 14:56

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開發組(2015-03-31)。RT-Thread做為國內有較大影響力的開源實時操作系統,本文是RT-Thread實時操作系統的編程指南
    發表于 11-26 16:06 ?0次下載

    RT-Thread AI kit開源:輕松實現鍵部署AI模型至 RT-Thread

    RT-AK 是 RT-Thread 團隊為 RT-Thread 實時操作系統所開發的 AI 套件,能夠鍵將 AI 模型部署到 RT-Thread
    發表于 01-25 18:18 ?3次下載
    <b class='flag-5'>RT-Thread</b> AI kit開源:輕松實現<b class='flag-5'>一</b>鍵部署AI模型至 <b class='flag-5'>RT-Thread</b>

    RT-Thread新版入門系列教程18講

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

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

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

    RT-Thread學習筆記 RT-Thread的架構概述

    RT-Thread 簡介 作為名 RTOS 的初學者,也許RT-Thread 還比較陌生。然而,隨著的深入接觸,
    的頭像 發表于 07-09 11:27 ?4483次閱讀
    <b class='flag-5'>RT-Thread</b>學習筆記 <b class='flag-5'>RT-Thread</b>的架構概述

    RT-Thread文檔_RT-Thread 簡介

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

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

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南
    發表于 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 介紹與移植
    發表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    基于RT-Thread Studio學習

    前期準備:從官網下載 RT-Thread Studio,弄個賬號登陸,開啟rt-thread學習之旅。
    的頭像 發表于 05-15 11:00 ?3825次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio學習

    怎么知道RT-Thread的CRYPTO設備對M2354支持怎樣呢?

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

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

    。但也正是因為這些優點的覆蓋面較廣,很多初學者會覺得無從下手,但只要步入 RT-Thread 的大門,就發現她的美好。這系列文檔將作為本人基于 RT-Thread 開發 RoboMa
    的頭像 發表于 09-19 19:55 ?739次閱讀

    RT-Thread v5.0.2 發布

    一系列令人激動的變化和改進。 以下是些亮點和關鍵變更: ?內核改進: ●?新增了AMP支持。 ●?新增了消息隊列的消息優先級。 ●?新增了rt_hw_interrupt_is_disabled
    的頭像 發表于 10-10 18:45 ?1397次閱讀
    <b class='flag-5'>RT-Thread</b> v5.0.2 發布