這篇文章主要介紹“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個消息)
__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
。 初始化完成示意圖:
__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
參數選擇掛載到消息列表的末尾或者是頭部,因此消息隊列的寫入是支持FIFO
與LIFO
方式的,msg_queue
是要寫入消息的消息隊列控制塊,msg_addr
、msg_size
則是要寫入消息的地址與大小。
寫入消息的過程非常簡單,直接通過msgpool_alloc()
函數從消息池取出一個空閑消息,如果系統不存在空閑的消息,則直接返回錯誤代碼K_ERR_MSG_QUEUE_FULL
表示系統可用的消息已經被使用完。如果取出空閑消息成功則將要寫入的消息地址與大小記錄到消息池的msg_addr
與 msg_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消息隊列的說明以及消息隊列的相關操作介紹”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注創新互聯網站,小編會繼續努力為大家帶來更多實用的文章!
分享題目:TencentOStiny消息隊列的說明以及消息隊列的相關操作介紹
標題來源:http://m.newbst.com/article4/gscpie.html
成都網站建設公司_創新互聯,為您提供動態網站、外貿建站、品牌網站制作、企業網站制作、品牌網站設計、ChatGPT
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯