免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

TencentOStiny消息隊列的說明以及消息隊列的相關操作介紹

這篇文章主要介紹“TencentOS  tiny消息隊列的說明以及消息隊列的相關操作介紹”,在日常操作中,相信很多人在TencentOS  tiny消息隊列的說明以及消息隊列的相關操作介紹問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”TencentOS  tiny消息隊列的說明以及消息隊列的相關操作介紹”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

成都創新互聯公司科技有限公司專業互聯網基礎服務商,為您提供綿陽服務器托管高防主機,成都IDC機房托管,成都主機托管等互聯網服務。

消息隊列

其實消息隊列是TencentOS tiny的一個基礎組件,作為隊列的底層。 所以在tos_config.h中會用以下宏定義:

#if (TOS_CFG_QUEUE_EN > 0u)
#define TOS_CFG_MSG_EN     1u
#else
#define TOS_CFG_MSG_EN     0u
#endif

系統消息池初始化

在系統初始化(tos_knl_init())的時候,系統就會將消息池進行初始化,其中, msgpool_init()函數就是用來初始化消息池的,該函數的定義位于 tos_msg.c文件中,函數的實現主要是通過一個for循環,將消息池k_msg_pool[TOS_CFG_MSG_POOL_SIZE]的成員變量進行初始化,初始化對應的列表節點,并且將它掛載到空閑消息列表上k_msg_freelist 初始化完成示意圖:(假設只有3個消息) TencentOS  tiny消息隊列的說明以及消息隊列的相關操作介紹

__KERNEL__ void msgpool_init(void)
{
    uint32_t i;

    for (i = 0; i < TOS_CFG_MSG_POOL_SIZE; ++i) {
        tos_list_init(&k_msg_pool[i].list);
        tos_list_add(&k_msg_pool[i].list, &k_msg_freelist);
    }
}
__API__ k_err_t tos_knl_init(void)
{
	···
	#if (TOS_CFG_MSG_EN) > 0
	    msgpool_init();
	#endif
	···
}

消息隊列創建

這個函數在隊列創建中會被調用,當然他也可以自己作為用戶API接口提供給用戶使用,而非僅僅是內核API接口。 這個函數的本質上就是初始化消息隊列中的消息列表queue_head。 初始化完成示意圖: TencentOS  tiny消息隊列的說明以及消息隊列的相關操作介紹

__API__ k_err_t tos_msg_queue_create(k_msg_queue_t *msg_queue)
{
    TOS_PTR_SANITY_CHECK(msg_queue);

#if TOS_CFG_OBJECT_VERIFY_EN > 0u
    knl_object_init(&msg_queue->knl_obj, KNL_OBJ_TYPE_MSG_QUEUE);
#endif

    tos_list_init(&msg_queue->queue_head);
    return K_ERR_NONE;
}

消息隊列銷毀

tos_msg_queue_destroy()函數用于銷毀一個消息隊列,當消息隊列不在使用是可以將其銷毀,銷毀的本質其實是將消息隊列控制塊的內容進行清除,首先判斷一下消息隊列控制塊的類型是KNL_OBJ_TYPE_MSG_QUEUE,這個函數只能銷毀隊列類型的控制塊。然后調用tos_msg_queue_flush()函數將隊列的消息列表的消息全部“清空”,“清空”的意思是將掛載到隊列上的消息釋放回消息池(如果消息隊列的消息列表存在消息,使用msgpool_free()函數釋放消息)。并且通過tos_list_init()函數將消息隊列的消息列表進行初始化,knl_object_deinit()函數是為了確保消息隊列已經被銷毀,此時消息隊列控制塊的pend_obj成員變量中的type 屬性標識為KNL_OBJ_TYPE_NONE

但是有一點要注意,因為隊列控制塊的RAM是由編譯器靜態分配的,所以即使是銷毀了隊列,這個內存也是沒辦法釋放的~

__API__ k_err_t tos_msg_queue_destroy(k_msg_queue_t *msg_queue)
{
    TOS_PTR_SANITY_CHECK(msg_queue);

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

    tos_msg_queue_flush(msg_queue);
    tos_list_init(&msg_queue->queue_head);

#if TOS_CFG_OBJECT_VERIFY_EN > 0u
    knl_object_deinit(&msg_queue->knl_obj);
#endif

    return K_ERR_NONE;
}
__API__ void tos_msg_queue_flush(k_msg_queue_t *msg_queue)
{
    TOS_CPU_CPSR_ALLOC();
    k_list_t *curr, *next;

    TOS_CPU_INT_DISABLE();

    TOS_LIST_FOR_EACH_SAFE(curr, next, &msg_queue->queue_head) {
        msgpool_free(TOS_LIST_ENTRY(curr, k_msg_t, list));
    }

    TOS_CPU_INT_ENABLE();
}

從消息隊列獲取消息

tos_msg_queue_get()函數用于從消息隊列中獲取消息,獲取到的消息通過msg_addr參數返回,獲取到消息的大小通過msg_size參數返回給用戶,當獲取成功是返回K_ERR_NONE,否則返回對應的錯誤代碼。 這個從消息隊列中獲取消息的函數是不會產生阻塞的,如果有消息則獲取成功,否則就獲取失敗,它的實現過程如下: TOS_CFG_OBJECT_VERIFY_EN 宏定義使能了,就調用knl_object_verify()函數確保是從消息隊列中獲取消息,然后通過TOS_LIST_FIRST_ENTRY_OR_NULL判斷一下是消息隊列的消息列表否存在消息,如果不存在則返回K_ERR_MSG_QUEUE_EMPTY表示消息隊列是空的,反正將獲取成功,獲取成功后需要使用msgpool_free()函數將消息釋放回消息池。

__API__ k_err_t tos_msg_queue_get(k_msg_queue_t *msg_queue, void **msg_addr, size_t *msg_size)
{
    TOS_CPU_CPSR_ALLOC();
    k_msg_t *msg;

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

    TOS_CPU_INT_DISABLE();

    msg = TOS_LIST_FIRST_ENTRY_OR_NULL(&msg_queue->queue_head, k_msg_t, list);
    if (!msg) {
        TOS_CPU_INT_ENABLE();
        return K_ERR_MSG_QUEUE_EMPTY;
    }

    *msg_addr = msg->msg_addr;
    *msg_size = msg->msg_size;
    msgpool_free(msg);

    TOS_CPU_INT_ENABLE();

    return K_ERR_NONE;
}

向消息隊列寫入消息

當發送消息時,TencentOS tiny會從消息池(空閑消息列表)中取出一個空閑消息,掛載到消息隊列的消息列表中,可以通過opt參數選擇掛載到消息列表的末尾或者是頭部,因此消息隊列的寫入是支持FIFOLIFO方式的,msg_queue是要寫入消息的消息隊列控制塊,msg_addrmsg_size則是要寫入消息的地址與大小。

寫入消息的過程非常簡單,直接通過msgpool_alloc()函數從消息池取出一個空閑消息,如果系統不存在空閑的消息,則直接返回錯誤代碼K_ERR_MSG_QUEUE_FULL表示系統可用的消息已經被使用完。如果取出空閑消息成功則將要寫入的消息地址與大小記錄到消息池的msg_addrmsg_size 成員變量中,然后通過opt參數選擇將消息掛載到消息列表的位置(頭部或者是尾部)。

__API__ k_err_t tos_msg_queue_put(k_msg_queue_t *msg_queue, void *msg_addr, size_t msg_size, k_opt_t opt)
{
    TOS_CPU_CPSR_ALLOC();
    k_msg_t *msg;

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

    TOS_CPU_INT_DISABLE();

    msg = msgpool_alloc();
    if (!msg) {
        TOS_CPU_INT_ENABLE();
        return K_ERR_MSG_QUEUE_FULL;
    }

    msg->msg_addr = msg_addr;
    msg->msg_size = msg_size;

    if (opt & TOS_OPT_MSG_PUT_LIFO) {
        tos_list_add(&msg->list, &msg_queue->queue_head);
    } else {
        tos_list_add_tail(&msg->list, &msg_queue->queue_head);
    }

    TOS_CPU_INT_ENABLE();

    return K_ERR_NONE;
}

實驗測試代碼

#include "stm32f10x.h"
#include "bsp_usart.h"
#include "tos.h"


k_msg_queue_t test_msg_queue_00;

k_task_t task1;
k_task_t task2;
k_stack_t task_stack1[1024];
k_stack_t task_stack2[1024];


void test_task1(void *Parameter)
{
    k_err_t err;
    int i = 0;
    int msg_received;
    size_t msg_size = 0;
    
    while(1)
    {
        printf("queue pend\r\n");
        for (i = 0; i < 3; ++i) 
        {
            err = tos_msg_queue_get(&test_msg_queue_00, (void **)&msg_received, &msg_size);
            if (err == K_ERR_NONE)
                printf("msg queue get is %d \r\n",msg_received);
            
            if (err == K_ERR_PEND_DESTROY)
            {
                printf("queue is destroy\r\n");
                tos_task_delay(TOS_TIME_FOREVER - 1);
            }
        }
        tos_task_delay(1000); 
    }
}

void test_task2(void *Parameter)
{
    k_err_t err;
    
    int i = 0;
    uint32_t msgs[3] = { 1, 2, 3 };

    printf("task2 running\r\n");

    while(1)
    { 
        for (i = 0; i < 3; ++i) 
        {
            err = tos_msg_queue_put(&test_msg_queue_00, (void *)(msgs[i]), sizeof(uint32_t), TOS_OPT_MSG_PUT_FIFO);
            if (err != K_ERR_NONE)
                printf("msg queue put fail! code : %d \r\n",err);
        }
        
        tos_task_delay(1000);       
    }
}
/**
  * @brief  主函數
  * @param  無
  * @retval 無
  */
int main(void)
{
    k_err_t err;
    
    /*初始化USART 配置模式為 115200 8-N-1,中斷接收*/
    USART_Config();

    printf("Welcome to TencentOS tiny\r\n");

    tos_knl_init(); // TOS Tiny kernel initialize
    
    tos_robin_config(TOS_ROBIN_STATE_ENABLED, (k_timeslice_t)500u);
    
    printf("create test_queue_00\r\n");
    err = tos_msg_queue_create(&test_msg_queue_00);
    if(err != K_ERR_NONE)
        printf("TencentOS Create test_msg_queue_00 fail! code : %d \r\n",err);
    
    printf("create task1\r\n");
    err = tos_task_create(&task1, 
                          "task1", 
                          test_task1,
                          NULL, 
                          3, 
                          task_stack1,
                          1024,
                          20);
    if(err != K_ERR_NONE)
        printf("TencentOS Create task1 fail! code : %d \r\n",err);
    
    printf("create task2\r\n");
    err = tos_task_create(&task2, 
                          "task2", 
                          test_task2,
                          NULL, 
                          4, 
                          task_stack2,
                          1024,
                          20);
    if(err != K_ERR_NONE)
        printf("TencentOS Create task2 fail! code : %d \r\n",err);
    
    tos_knl_start(); // Start TOS Tiny

}

現象

TencentOS  tiny消息隊列的說明以及消息隊列的相關操作介紹

到此,關于“TencentOS  tiny消息隊列的說明以及消息隊列的相關操作介紹”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注創新互聯網站,小編會繼續努力為大家帶來更多實用的文章!

分享題目:TencentOStiny消息隊列的說明以及消息隊列的相關操作介紹
標題來源:http://m.newbst.com/article4/gscpie.html

成都網站建設公司_創新互聯,為您提供動態網站外貿建站品牌網站制作企業網站制作品牌網站設計ChatGPT

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都seo排名網站優化