TencentOStiny任務(wù)的基本概念和相關(guān)操作介紹

這篇文章主要介紹“TencentOS  tiny任務(wù)的基本概念和相關(guān)操作介紹”,在日常操作中,相信很多人在TencentOS  tiny任務(wù)的基本概念和相關(guān)操作介紹問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”TencentOS  tiny任務(wù)的基本概念和相關(guān)操作介紹”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

創(chuàng)新互聯(lián)公司專注于網(wǎng)站建設(shè)|成都網(wǎng)站改版|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計(jì)與制作經(jīng)驗(yàn),為許多企業(yè)提供了網(wǎng)站定制設(shè)計(jì)服務(wù),案例作品覆蓋成都酒樓設(shè)計(jì)等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身建設(shè)品質(zhì)網(wǎng)站。

任務(wù)的基本概念

從系統(tǒng)的角度看,任務(wù)是競(jìng)爭(zhēng)系統(tǒng)資源的最小運(yùn)行單元。TencentOS tiny是一個(gè)支持多任務(wù)的操作系統(tǒng),任務(wù)可以使用或等待CPU、使用內(nèi)存空間等系統(tǒng)資源,并獨(dú)立于其它任務(wù)運(yùn)行,理論上任何數(shù)量的任務(wù)都可以共享同一個(gè)優(yōu)先級(jí),這樣子處于就緒態(tài)的多個(gè)相同優(yōu)先級(jí)任務(wù)將會(huì)以時(shí)間片切換的方式共享處理器。

不過(guò)要注意的是:在TencentOS tiny中,不能創(chuàng)建與空閑任務(wù)相同優(yōu)先級(jí)的任務(wù)K_TASK_PRIO_IDLE,相同優(yōu)先級(jí)下的任務(wù)需要允許使用時(shí)間片調(diào)度,打開(kāi)TOS_CFG_ROUND_ROBIN_EN。

簡(jiǎn)而言之: TencentOS tiny的任務(wù)可認(rèn)為是一系列獨(dú)立任務(wù)的集合。每個(gè)任務(wù)在自己的環(huán)境中運(yùn)行。在任何時(shí)刻,只有一個(gè)任務(wù)得到運(yùn)行,由TencentOS tiny調(diào)度器決定運(yùn)行哪個(gè)任務(wù)。從宏觀看上去所有的任務(wù)都在同時(shí)在執(zhí)行。

TencentOS中的任務(wù)是搶占式調(diào)度機(jī)制,高優(yōu)先級(jí)的任務(wù)可打斷低優(yōu)先級(jí)任務(wù),低優(yōu)先級(jí)任務(wù)必須在高優(yōu)先級(jí)任務(wù)阻塞或結(jié)束后才能得到調(diào)度。同時(shí)TencentOS也支持時(shí)間片輪轉(zhuǎn)調(diào)度方式。

系統(tǒng)默認(rèn)可以支持10個(gè)優(yōu)先級(jí),0~TOS_CFG_TASK_PRIO_MAX,這個(gè)宏定義是可以修改的,優(yōu)先級(jí)數(shù)值越大的任務(wù)優(yōu)先級(jí)越低,(TOS_CFG_TASK_PRIO_MAX - (k_prio_t)1u)為最低優(yōu)先級(jí),分配給空閑任務(wù)使用。

#define K_TASK_PRIO_IDLE         (k_prio_t)(TOS_CFG_TASK_PRIO_MAX - (k_prio_t)1u)
#define K_TASK_PRIO_INVALID      (k_prio_t)(TOS_CFG_TASK_PRIO_MAX)

任務(wù)狀態(tài)

TencentOS tiny任務(wù)狀態(tài)有以下幾種。

  • 就緒態(tài)(K_TASK_STATE_READY):該任務(wù)在就緒列表中,就緒的任務(wù)已經(jīng)具備執(zhí)行的能力,只等待調(diào)度器進(jìn)行調(diào)度,新創(chuàng)建的任務(wù)會(huì)初始化為就緒態(tài)。

  • 運(yùn)行態(tài)(K_TASK_STATE_READY):該狀態(tài)表明任務(wù)正在執(zhí)行,此時(shí)它占用處理器,其實(shí)此時(shí)的任務(wù)還是處于就緒列表中的,TencentOS調(diào)度器選擇運(yùn)行的永遠(yuǎn)是處于最高優(yōu)先級(jí)的就緒態(tài)任務(wù),當(dāng)任務(wù)被運(yùn)行的一刻,它的任務(wù)狀態(tài)就變成了運(yùn)行態(tài)。

  • 睡眠態(tài)(K_TASK_STATE_SLEEP):如果任務(wù)當(dāng)前正在休眠讓出CPU使用權(quán),那么就可以說(shuō)這個(gè)任務(wù)處于休眠狀態(tài),該任務(wù)不在就緒列表中,此時(shí)任務(wù)處于睡眠列表中(或者叫延時(shí)列表)。

  • 等待態(tài)(K_TASK_STATE_PEND):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件等狀態(tài)。

  • 掛起態(tài)(K_TASK_STATE_SUSPENDED):任務(wù)被掛起,此時(shí)任務(wù)對(duì)調(diào)度器而言是不可見(jiàn)的。

  • 退出態(tài)(K_TASK_STATE_DELETED):該任務(wù)運(yùn)行結(jié)束,并且被刪除。

  • 等待超時(shí)狀態(tài)(K_TASK_STATE_PENDTIMEOUT):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件發(fā)生超時(shí)的狀態(tài)。

  • 睡眠掛起態(tài)(K_TASK_STATE_SLEEP_SUSPENDED):任務(wù)在睡眠中被掛起時(shí)的狀態(tài)。

  • 等待掛起態(tài)(K_TASK_STATE_PEND_SUSPENDED):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件時(shí)被掛起的狀態(tài)。

  • 等待超時(shí)掛起態(tài)(K_TASK_STATE_PENDTIMEOUT_SUSPENDED):任務(wù)正在等待信號(hào)量、隊(duì)列或者等待事件發(fā)生超時(shí),但此時(shí)任務(wù)已經(jīng)被掛起的狀態(tài)。

// ready to schedule
// a task's pend_list is in readyqueue
#define K_TASK_STATE_READY                (k_task_state_t)0x0000

// delayed, or pend for a timeout
// a task's tick_list is in k_tick_list
#define K_TASK_STATE_SLEEP                (k_task_state_t)0x0001

// pend for something
// a task's pend_list is in some pend object's list
#define K_TASK_STATE_PEND                 (k_task_state_t)0x0002

// suspended
#define K_TASK_STATE_SUSPENDED            (k_task_state_t)0x0004

// deleted
#define K_TASK_STATE_DELETED              (k_task_state_t)0x0008

// actually we don't really need those TASK_STATE below, if you understand the task state deeply, the code can be much more elegant. 

// we are pending, also we are waitting for a timeout(eg. tos_sem_pend with a valid timeout, not TOS_TIME_FOREVER)
// both a task's tick_list and pend_list is not empty
#define K_TASK_STATE_PENDTIMEOUT                      (k_task_state_t)(K_TASK_STATE_PEND | K_TASK_STATE_SLEEP)

// suspended when sleeping
#define K_TASK_STATE_SLEEP_SUSPENDED                  (k_task_state_t)(K_TASK_STATE_SLEEP | K_TASK_STATE_SUSPENDED)

// suspened when pending
#define K_TASK_STATE_PEND_SUSPENDED                   (k_task_state_t)(K_TASK_STATE_PEND | K_TASK_STATE_SUSPENDED)

// suspended when pendtimeout
#define K_TASK_STATE_PENDTIMEOUT_SUSPENDED            (k_task_state_t)(K_TASK_STATE_PENDTIMEOUT | K_TASK_STATE_SUSPENDED)

TencentOS中維護(hù)任務(wù)的數(shù)據(jù)結(jié)構(gòu)

就緒列表

TencentOS tiny維護(hù)一條就緒列表,用于掛載系統(tǒng)中的所有處于就緒態(tài)的任務(wù),他是readyqueue_t 類型的列表,其成員變量如下:

readyqueue_t        k_rdyq;

typedef struct readyqueue_st {
    k_list_t    task_list_head[TOS_CFG_TASK_PRIO_MAX];
    uint32_t    prio_mask[K_PRIO_TBL_SIZE];
    k_prio_t    highest_prio;
} readyqueue_t;

task_list_head是列表類型k_list_t的數(shù)組,TencentOS tiny為每個(gè)優(yōu)先級(jí)的任務(wù)都分配一個(gè)列表,系統(tǒng)支持最大優(yōu)先級(jí)為TOS_CFG_TASK_PRIO_MAX prio_mask則是優(yōu)先級(jí)掩碼數(shù)組,它是一個(gè)類型為32位變量的數(shù)組,數(shù)組成員個(gè)數(shù)由TOS_CFG_TASK_PRIO_MAX決定:

#define K_PRIO_TBL_SIZE         ((TOS_CFG_TASK_PRIO_MAX + 31) / 32)

當(dāng)TOS_CFG_TASK_PRIO_MAX不超過(guò)32時(shí)數(shù)組成員變量只有一個(gè),就是32位的變量數(shù)值,那么該變量的每一位代表一個(gè)優(yōu)先級(jí)。比如當(dāng)TOS_CFG_TASK_PRIO_MAX為64時(shí),prio_mask[0]變量的每一位(bit)代表0-31優(yōu)先級(jí),而prio_mask[1]變量的每一位代表32-63優(yōu)先級(jí)。

highest_prio則是記錄當(dāng)前優(yōu)先級(jí)列表的最高優(yōu)先級(jí),方便索引task_list_head。

延時(shí)列表

與系統(tǒng)時(shí)間相關(guān)的任務(wù)都會(huì)被掛載到這個(gè)列表中,可能是睡眠、有期限地等待信號(hào)量、事件、消息隊(duì)列等情況~

k_list_t             k_tick_list;

任務(wù)控制塊

在多任務(wù)系統(tǒng)中,任務(wù)的執(zhí)行是由系統(tǒng)調(diào)度的。系統(tǒng)為了順利的調(diào)度任務(wù),為每個(gè)任務(wù)都額外定義了一個(gè)任務(wù)控制塊,這個(gè)任務(wù)控制塊就相當(dāng)于任務(wù)的身份證,里面存有任務(wù)的所有信息,比如任務(wù)的棧指針,任務(wù)名稱,任務(wù)的形參等。有了這個(gè)任務(wù)控制塊之后,以后系統(tǒng)對(duì)任務(wù)的全部操作都可以通過(guò)這個(gè)任務(wù)控制塊來(lái)實(shí)現(xiàn)。 TencentOS 任務(wù)控制塊如下:

typedef struct k_task_st {
    k_stack_t          *sp;                 /**< 任務(wù)棧指針,用于切換上下文*/

#if TOS_CFG_OBJECT_VERIFY_EN > 0u
    knl_obj_t           knl_obj;            /**< 只是為了驗(yàn)證,測(cè)試當(dāng)前對(duì)象是否真的是一項(xiàng)任務(wù)。*/
#endif

    char               *name;               /**< 任務(wù)名稱 */
    k_task_entry_t      entry;              /**< 任務(wù)主體 */
    void               *arg;                /**< 任務(wù)主體形參 */
    k_task_state_t      state;              /**< 任務(wù)狀態(tài) */
    k_prio_t            prio;               /**< 任務(wù)優(yōu)先級(jí) */

    k_stack_t          *stk_base;           /**< 任務(wù)?;刂?nbsp;*/
    size_t              stk_size;           /**< 任務(wù)棧大小 */

    k_tick_t            tick_expires;       /**< 任務(wù)阻塞的時(shí)間 */

    k_list_t            tick_list;          /**< 延時(shí)列表 */
    k_list_t            pend_list;          /**< 就緒、等待列表 */

#if TOS_CFG_MUTEX_EN > 0u
    k_list_t            mutex_own_list;     /**< 任務(wù)擁有的互斥量 */
    k_prio_t            prio_pending;       /*< 用于記錄持有互斥量的任務(wù)初始優(yōu)先級(jí),在優(yōu)先級(jí)繼承中使用 */
#endif

    pend_obj_t         *pending_obj;       /**< 記錄任務(wù)此時(shí)掛載到的列表 */
    pend_state_t        pend_state;         /**< 等待被喚醒的原因(狀態(tài)) */

#if TOS_CFG_ROUND_ROBIN_EN > 0u
    k_timeslice_t       timeslice_reload;   /**< 時(shí)間片初始值(重裝載值) */
    k_timeslice_t       timeslice;          /**< 剩余時(shí)間片 */
#endif

#if TOS_CFG_MSG_EN > 0u
    void               *msg_addr;           /**< 保存接收到的消息 */
    size_t              msg_size;			/**< 保存接收到的消息大小 */
#endif

#if TOS_CFG_EVENT_EN > 0u
    k_opt_t             opt_event_pend;     /**< 等待事件的的操作類型:TOS_OPT_EVENT_PEND_ANY 、 TOS_OPT_EVENT_PEND_ALL */
    k_event_flag_t      flag_expect;        /**< 期待發(fā)生的事件 */
    k_event_flag_t     *flag_match;         /**< 等待到的事件 */
#endif
} k_task_t;

創(chuàng)建任務(wù)

在TencentOS tiny中,凡是使用__API__ 修飾的函數(shù)都是提供給用戶使用的,而使用__KERNEL__修飾的代碼則是給內(nèi)核使用的。 TencentOS的創(chuàng)建任務(wù)函數(shù)有好幾個(gè)參數(shù): |參數(shù)| 含義 | |--|--| |task | 任務(wù)控制塊 | |name | 任務(wù)名字 | |entry | 任務(wù)主體 | |arg | 任務(wù)形參 | |prio | 優(yōu)先級(jí) | |stk_base | 任務(wù)?;刂?| |stk_size | 任務(wù)棧大小 | |timeslice | 時(shí)間片 |

參數(shù)詳解(來(lái)源TencentOS tiny開(kāi)發(fā)指南):

  • task

    這是一個(gè)k_task_t類型的指針,k_task_t是內(nèi)核的任務(wù)結(jié)構(gòu)體類型。注意:task指針,應(yīng)該指向生命周期大于待創(chuàng)建任務(wù)體生命周期的k_task_t類型變量,如果該指針指向的變量生命周期比待創(chuàng)建的任務(wù)體生命周期短,譬如可能是一個(gè)生命周期極端的函數(shù)棧上變量,可能會(huì)出現(xiàn)任務(wù)體還在運(yùn)行而k_task_t變量已被銷毀,會(huì)導(dǎo)致系統(tǒng)調(diào)度出現(xiàn)不可預(yù)知問(wèn)題。

  • name

    指向任務(wù)名字符串的指針。注意:同task,該指針指向的字符串生命周期應(yīng)該大于待創(chuàng)建的任務(wù)體生命周期,一般來(lái)說(shuō),傳入字符串常量指針即可。

  • entry

    任務(wù)體運(yùn)行的函數(shù)入口。當(dāng)任務(wù)創(chuàng)建完畢進(jìn)入運(yùn)行狀態(tài)后,entry是任務(wù)執(zhí)行的入口,用戶可以在此函數(shù)中編寫業(yè)務(wù)邏輯。

  • arg

    傳遞給任務(wù)入口函數(shù)的參數(shù)。

  • prio

    任務(wù)優(yōu)先級(jí)。prio的數(shù)值越小,優(yōu)先級(jí)越高。用戶可以在tos_config.h中,通過(guò)TOS_CFG_TASK_PRIO_MAX來(lái)配置任務(wù)優(yōu)先級(jí)的最大數(shù)值,在內(nèi)核的實(shí)現(xiàn)中,idle任務(wù)的優(yōu)先級(jí)會(huì)被分配為TOS_CFG_TASK_PRIO_MAX - 1,此優(yōu)先級(jí)只能被idle任務(wù)使用。因此對(duì)于一個(gè)用戶創(chuàng)建的任務(wù)來(lái)說(shuō),合理的優(yōu)先級(jí)范圍應(yīng)該為[0, TOS_CFG_TASK_PRIO_MAX - 2]。另外TOS_CFG_TASK_PRIO_MAX的配置值必需大于等于8。

  • stk_base

    任務(wù)在運(yùn)行時(shí)使用的棧空間的起始地址。注意:同task,該指針指向的內(nèi)存空間的生命周期應(yīng)該大于待創(chuàng)建的任務(wù)體生命周期。stk_base是k_stack_t類型的數(shù)組起始地址。

  • stk_size

    任務(wù)的棧空間大小。注意:因?yàn)閟tk_base是k_stack_t類型的數(shù)組指針,因此實(shí)際棧空間所占內(nèi)存大小為stk_size * sizeof(k_stack_t)。

  • timeslice

    時(shí)間片輪轉(zhuǎn)機(jī)制下當(dāng)前任務(wù)的時(shí)間片大小。當(dāng)timeslice為0時(shí),任務(wù)調(diào)度時(shí)間片會(huì)被設(shè)置為默認(rèn)大小(TOS_CFG_CPU_TICK_PER_SECOND / 10),系統(tǒng)時(shí)鐘滴答(systick)數(shù) / 10。

創(chuàng)建任務(wù)的實(shí)現(xiàn)如下:首先對(duì)參數(shù)進(jìn)行檢查,還要再提一下:在TencentOS中,不能創(chuàng)建與空閑任務(wù)相同優(yōu)先級(jí)的任務(wù)K_TASK_PRIO_IDLE。然后調(diào)用cpu_task_stk_init函數(shù)將任務(wù)棧進(jìn)行初始化,并且將傳入的參數(shù)記錄到任務(wù)控制塊中。如果打開(kāi)了TOS_CFG_ROUND_ROBIN_EN 宏定義,則表示支持時(shí)間片調(diào)度,則需要配置時(shí)間片相關(guān)的信息timeslice 到任務(wù)控制塊中。然后調(diào)用task_state_set_ready函數(shù)將新創(chuàng)建的任務(wù)設(shè)置為就緒態(tài)K_TASK_STATE_READY,再調(diào)用readyqueue_add_tail函數(shù)將任務(wù)插入就緒列表k_rdyq中。如果調(diào)度器運(yùn)行起來(lái)了,則進(jìn)行一次任務(wù)調(diào)度。

個(gè)人感覺(jué)吧,沒(méi)有從堆中動(dòng)態(tài)分配還是有點(diǎn)小小的遺憾,我更喜歡簡(jiǎn)單的函數(shù)接口~!

代碼如下:

__API__ k_err_t tos_task_create(k_task_t *task,
                                char *name,
                                k_task_entry_t entry,
                                void *arg,
                                k_prio_t prio,
                                k_stack_t *stk_base,
                                size_t stk_size,
                                k_timeslice_t timeslice)
{
    TOS_CPU_CPSR_ALLOC();

    TOS_IN_IRQ_CHECK();

    TOS_PTR_SANITY_CHECK(task);
    TOS_PTR_SANITY_CHECK(entry);
    TOS_PTR_SANITY_CHECK(stk_base);

    if (unlikely(stk_size < sizeof(cpu_context_t))) {
        return K_ERR_TASK_STK_SIZE_INVALID;
    }

    if (unlikely(prio == K_TASK_PRIO_IDLE && !knl_is_idle(task))) {
        return K_ERR_TASK_PRIO_INVALID;
    }

    if (unlikely(prio > K_TASK_PRIO_IDLE)) {
        return K_ERR_TASK_PRIO_INVALID;
    }

    task_reset(task);
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
    knl_object_init(&task->knl_obj, KNL_OBJ_TYPE_TASK);
#endif

    task->sp        = cpu_task_stk_init((void *)entry, arg, (void *)task_exit, stk_base, stk_size);
    task->entry     = entry;
    task->arg       = arg;
    task->name      = name;
    task->prio      = prio;
    task->stk_base  = stk_base;
    task->stk_size  = stk_size;

#if TOS_CFG_ROUND_ROBIN_EN > 0u
    task->timeslice_reload = timeslice;

    if (timeslice == (k_timeslice_t)0u) {
        task->timeslice = k_robin_default_timeslice;
    } else {
        task->timeslice = timeslice;
    }
#endif

    TOS_CPU_INT_DISABLE();
    task_state_set_ready(task);
    readyqueue_add_tail(task);
    TOS_CPU_INT_ENABLE();

    if (tos_knl_is_running()) {
        knl_sched();
    }

    return K_ERR_NONE;
}

任務(wù)銷毀

這個(gè)函數(shù)十分簡(jiǎn)單,根據(jù)傳遞進(jìn)來(lái)的任務(wù)控制塊銷毀任務(wù),也可以傳遞進(jìn)NULL表示銷毀當(dāng)前運(yùn)行的任務(wù)。但是不允許銷毀空閑任務(wù)k_idle_task,當(dāng)調(diào)度器被鎖住時(shí)不能銷毀自身,會(huì)返回K_ERR_SCHED_LOCKED錯(cuò)誤代碼。如果使用了互斥量,當(dāng)任務(wù)被銷毀時(shí)會(huì)釋放掉互斥量,并且根據(jù)任務(wù)所處的狀態(tài)進(jìn)行銷毀,比如任務(wù)處于就緒態(tài)、延時(shí)態(tài)、等待態(tài),則會(huì)從對(duì)應(yīng)的狀態(tài)列表中移除。 代碼實(shí)現(xiàn)如下:

__API__ k_err_t tos_task_destroy(k_task_t *task)
{
    TOS_CPU_CPSR_ALLOC();

    TOS_IN_IRQ_CHECK();

    if (unlikely(!task)) {
        task = k_curr_task;
    }

#if TOS_CFG_OBJECT_VERIFY_EN > 0u
    if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
        return K_ERR_OBJ_INVALID;
    }
#endif

    if (knl_is_idle(task)) {
        return K_ERR_TASK_DESTROY_IDLE;
    }

    if (knl_is_self(task) && knl_is_sched_locked()) {
        return K_ERR_SCHED_LOCKED;
    }

    TOS_CPU_INT_DISABLE();

#if TOS_CFG_MUTEX_EN > 0u
    // when we die, wakeup all the people in this land.
    if (!tos_list_empty(&task->mutex_own_list)) {
        task_mutex_release(task);
    }
#endif

    if (task_state_is_ready(task)) { // that's simple, good kid
        readyqueue_remove(task);
    }
    if (task_state_is_sleeping(task)) {
        tick_list_remove(task);
    }
    if (task_state_is_pending(task)) {
        pend_list_remove(task);
    }

    task_reset(task);
    task_state_set_deleted(task);

    TOS_CPU_INT_ENABLE();
    knl_sched();

    return K_ERR_NONE;
}

任務(wù)睡眠

任務(wù)睡眠非常簡(jiǎn)單,主要的思路就是將任務(wù)從就緒列表移除,然后添加到延時(shí)列表中k_tick_list,如果調(diào)度器被鎖,直接返回錯(cuò)誤代碼K_ERR_SCHED_LOCKED,如果睡眠時(shí)間為0,則調(diào)用tos_task_yield函數(shù)發(fā)起一次任務(wù)調(diào)度;調(diào)用tick_list_add函數(shù)將任務(wù)插入延時(shí)列表中,睡眠的時(shí)間delay是由用戶指定的。不過(guò)需要注意的是如果任務(wù)睡眠的時(shí)間是永久睡眠TOS_TIME_FOREVER,將返回錯(cuò)誤代碼K_ERR_DELAY_FOREVER,這是因?yàn)槿蝿?wù)睡眠是主動(dòng)行為,如果永久睡眠了,將沒(méi)法主動(dòng)喚醒,而任務(wù)等待事件、信號(hào)量、消息隊(duì)列等行為是被動(dòng)行為,可以是永久等待,一旦事件發(fā)生了、信號(hào)量唄釋放、消息隊(duì)列不為空時(shí)任務(wù)就會(huì)被喚醒,這是被動(dòng)行為,這兩點(diǎn)需要區(qū)分開(kāi)來(lái)。最后調(diào)用readyqueue_remove函數(shù)將任務(wù)從就緒列表中移除,然后調(diào)用knl_sched函數(shù)發(fā)起一次任務(wù)調(diào)度,就能切換另一個(gè)任務(wù)。 任務(wù)睡眠的代碼如下:

__API__ k_err_t tos_task_delay(k_tick_t delay)
{
    TOS_CPU_CPSR_ALLOC();

    TOS_IN_IRQ_CHECK();

    if (knl_is_sched_locked()) {
        return K_ERR_SCHED_LOCKED;
    }

    if (unlikely(delay == (k_tick_t)0u)) {
        tos_task_yield();
        return K_ERR_NONE;
    }

    TOS_CPU_INT_DISABLE();

    if (tick_list_add(k_curr_task, delay) != K_ERR_NONE) {
        TOS_CPU_INT_ENABLE();
        return K_ERR_DELAY_FOREVER;
    }

    readyqueue_remove(k_curr_task);

    TOS_CPU_INT_ENABLE();
    knl_sched();

    return K_ERR_NONE;
}

到此,關(guān)于“TencentOS  tiny任務(wù)的基本概念和相關(guān)操作介紹”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

分享名稱:TencentOStiny任務(wù)的基本概念和相關(guān)操作介紹
路徑分享:http://muchs.cn/article22/gedpjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站收錄關(guān)鍵詞優(yōu)化、小程序開(kāi)發(fā)網(wǎng)站策劃、網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司