天天看點

ThreadX(九)------消息隊列Queue

消息隊列Queue

    • API
      • tx_queue_create
      • tx_queue_delete
      • x_queue_flush
      • tx_queue_front_send
      • tx_queue_receive
      • tx_queue_send
      • tx_queue_send_notify
    • Queue_demo

API

  • tx_queue_create
  • tx_queue_delete
  • tx_queue_flush
  • tx_queue_front_send
  • tx_queue_receive
  • tx_queue_send_notify

tx_queue_create

UINT tx_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr,
    UINT message_size,
    VOID *queue_start, ULONG queue_size);
           

參數

  • queue_ptr 指向消息隊列控件塊的指針。
  • name_ptr 指向消息隊列的名稱的指針。
  • message_size 指定隊列中每條消息的大小。消息大小範圍從 1 個 32 位單詞到 16 個 32 位單詞。有效消息大小選項是 1 到 16 的數值(含)。
  • queue_start 消息隊列的起始位址。起始位址必須與 ULONG 資料類型的大小對齊。
  • queue_size 消息隊列可用的位元組總數。

傳回值

  • TX_SUCCESS (0x00) 成功建立消息隊列。
  • TX_QUEUE_ERROR (0x09) 無效消息隊列指針。指針為 NULL 或隊列已建立。
  • TX_PTR_ERROR (0x03) 消息隊列的無效起始位址。
  • TX_SIZE_ERROR (0x05) 消息隊列的大小無效。
  • TX_CALLER_ERROR服務(0x13)無效調用。

tx_queue_delete

參數

  • queue_ptr 指向以前建立的消息隊列的指針。

傳回值

  • TX_SUCCESS (0x00) 成功删除消息隊列。
  • TX_QUEUE_ERROR (0x09) 無效消息隊列指針。
  • TX_CALLER_ERROR服務(0x13)無效調用。

x_queue_flush

參數

  • queue_ptr 指向以前建立的消息隊列的指針。

傳回值

  • TX_SUCCESS (0x00) 成功消息隊列重新整理。
  • TX_QUEUE_ERROR (0x09) 無效消息隊列指針。

tx_queue_front_send

UINT tx_queue_front_send(TX_QUEUE *queue_ptr,
    VOID *source_ptr, ULONG wait_option);
           

參數

  • queue_ptr 指向消息隊列控件塊的指針。
  • source_ptr 指向消息的指針。
  • wait_option 定義如果消息隊列已滿,服務的行為方式。等待選項的定義如下:
  1. TX_NO_WAIT (0x00000000) - TX_NO_WAIT,無論它是否成功,都會立即從該服務傳回。如果從非線程調用服務,則這是唯一有效的選項;例如,初始化、計時器或 ISR。
  2. TX_WAIT_FOREVER (0xFFFF) - TX_WAIT_FOREVER,這将導緻調用線程無限期挂起,直到隊列中存在空間。
  3. 逾時值 (0x0000001 到 0xFFFFFFFE) - 選擇數值 (1-0xFFFFFFFE) 指定在等待隊列中的房間時保持挂起的計時器刻度的最大數量。

傳回值

  • TX_SUCCESS (0x00) 成功發送消息。
  • TX_DELETED時,已删除消息隊列 (0x01) 消息隊列。
  • TX_QUEUE_FULL (0x0B) 服務無法發送消息,因為隊列在指定等待的持續時間内已滿。
  • TX_WAIT_ABORTED (0x1A) 挂起被另一個線程、計時器或 ISR 中止。
  • TX_QUEUE_ERROR (0x09) 無效消息隊列指針。
  • TX_PTR_ERROR (0x03) 消息的無效源指針。
  • TX_WAIT_ERROR (0x04) 在非線程的TX_NO_WAIT上指定了除其他帳戶以外的等待選項。

tx_queue_receive

UINT tx_queue_receive(TX_QUEUE *queue_ptr,
    VOID *destination_ptr, ULONG wait_option);
           

參數

  • queue_ptr 指向以前建立的消息隊列。
  • destination_ptr 複制郵件的位置。
  • wait_option 定義如果消息隊列為空,服務的行為方式。等待選項的定義如下:
  1. TX_NO_WAIT (0x00000000) - TX_NO_WAIT,無論它是否成功,都會立即從該服務傳回。如果從非線程調用服務,則這是唯一有效的選項;例如,初始化、計時器或 ISR。
  2. TX_WAIT_FOREVER (0xFFFF) - TX_WAIT_FOREVER調用線程将無限期挂起,直到消息可用。
  3. 逾時值 (0x0000001 到 0xFFFFFFFE) - 選擇數值 (1-0xFFFFFFFE) 指定在等待消息時保持挂起計時器刻度的最大數量。

傳回值

  • TX_SUCCESS (0x00) 成功檢索消息。
  • TX_DELETED時,已删除消息隊列 (0x01) 消息隊列。
  • TX_QUEUE_EMPTY (0x0A) 服務無法檢索消息,因為隊列在指定等待的持續時間内為空。
  • TX_WAIT_ABORTED (0x1A) 挂起被另一個線程、計時器或 ISR 中止。
  • TX_QUEUE_ERROR (0x09) 無效消息隊列指針。
  • TX_PTR_ERROR (0x03) 消息的無效目标指針。
  • TX_WAIT_ERROR (0x04) 在從非TX_NO_WAIT的呼叫上指定的等待選項(非線程) 以外的等待選項。

tx_queue_send

UINT tx_queue_send(TX_QUEUE *queue_ptr,
    VOID *source_ptr, ULONG wait_option);
           

參數

  • queue_ptr 指向以前建立的消息隊列。
  • source_ptr 指向消息的指針。
  • wait_option 定義如果消息隊列已滿,服務的行為方式。等待選項的定義如下:
  1. TX_NO_WAIT (0x00000000) - TX_NO_WAIT,無論它是否成功,都會立即從該服務傳回。如果從非線程調用服務,則這是唯一有效的選項;例如,初始化、計時器或 ISR。
  2. TX_WAIT_FOREVER (0xFFFF) - TX_WAIT_FOREVER,這将導緻調用線程無限期挂起,直到隊列中存在空間。
  3. 逾時值 (0x0000001 到 0xFFFFFFFE) - 選擇數值 (1-0xFFFFFFFE) 指定在等待隊列中的房間時保持挂起的計時器刻度的最大數量。

傳回值

  • TX_SUCCESS (0x00) 成功發送消息。
  • TX_DELETED時,已删除消息隊列 (0x01) 消息隊列。
  • TX_QUEUE_FULL (0x0B) 服務無法發送消息,因為隊列在指定等待的持續時間内已滿。
  • TX_WAIT_ABORTED (0x1A) 挂起被另一個線程、計時器或 ISR 中止。
  • TX_QUEUE_ERROR (0x09) 無效消息隊列指針。
  • TX_PTR_ERROR (0x03) 消息的無效源指針。
  • TX_WAIT_ERROR (0x04) 在從非TX_NO_WAIT的呼叫上指定的等待選項(非線程) 以外的等待選項。

tx_queue_send_notify

UINT tx_queue_send_notify(TX_QUEUE *queue_ptr,
    VOID (*queue_send_notify)(TX_QUEUE *));
           

參數

  • queue_ptr 指向以前建立的隊列的指針。
  • queue_send_notify 指向應用程式的隊列發送通知函數的指針。如果此值為TX_NULL,則禁用通知。

傳回值

  • TX_SUCCESS (0x00) 成功注冊隊列發送通知。
  • TX_QUEUE_ERROR (0x09) 無效隊列指針。
  • TX_FEATURE_NOT_ENABLED (0xFF) 系統已編譯,并禁用了通知功能。

Queue_demo

/*
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 * Queue_demo.c
 * Change Logs:
 * Date           Author       Notes
 * 2020年8月28日     	  henji      the first version
 */

/* USER CODE BEGIN Includes */
#include "tx_api.h"
#include "stdio.h"


/* USER CODE BEGIN PV */
TX_THREAD MyThread_1;
TX_THREAD MyThread_2;


/*線程棧大小*/
#define DEMO_STACK_SIZE 1024
/*記憶體池總大小*/
#define DEMO_BYTE_POOL_SIZE 1024*5
/*記憶體塊池總大小*/
#define DEMO_BLOCK_POOL_SIZE 100
/*記憶體位元組池控制塊*/
TX_BYTE_POOL byte_pool_0;

/* 指向記憶體的指針 */
UCHAR *memory_ptr;

/* 消息隊列 */
TX_QUEUE my_queue;

/* Tracex使用 */
/*跟蹤緩沖區的記憶體大小*/
#define trace_buffer_size 64000
/*要保留在跟蹤系統資料庫中的應用程式ThreadX對象的數量*/
#define registry_entries 40
UCHAR trace_buffer_start[trace_buffer_size];
UINT trace_status;
/* USER CODE END PV */

int main(void)
{
	/* USER CODE BEGIN 2 */

	tx_kernel_enter(); //threadx 入口

	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1);
}

void MyThread_1_entry(ULONG entry_input)
{
    ULONG status;
	INT thread_1_send = 'A';
	INT special_send = 'Z';
	CHAR buf_send[19];
	while (1)
	{

		/* 緊急消息 */
		if(thread_1_send == 'C')
		{
			status = tx_queue_front_send(&my_queue,      //消息隊列控制塊
								         &special_send, //發送消息内容指針
									     TX_WAIT_FOREVER //無限等待
									     );
					if(status == TX_SUCCESS)
					{
						sprintf(buf_send,"special_send %c ",special_send);
						HAL_UART_Transmit(&huart1, (uint8_t*)buf_send, sizeof(buf_send), HAL_MAX_DELAY);
					}

		}
		else if(thread_1_send == 'I')
		{
			/* 到 'I' 的時候就結束程序  */
			tx_thread_terminate(&MyThread_1);
		}
		else
		{
			status = tx_queue_send(&my_queue,      //消息隊列控制塊
								   &thread_1_send, //發送消息内容指針
								   TX_WAIT_FOREVER //無限等待
								   );
					if(status == TX_SUCCESS)
					{
						sprintf(buf_send,"thread_1_send %c ",thread_1_send);
						HAL_UART_Transmit(&huart1, (uint8_t*)buf_send, sizeof(buf_send), HAL_MAX_DELAY);
					}
		}

		thread_1_send++;

		tx_thread_sleep(500);
	}
}

void MyThread_2_entry(ULONG entry_input)
{
	    ULONG status;
		INT thread_2_received;
		CHAR buf_rec[21];
		while (1)
		{
			status = tx_queue_receive(&my_queue, //消息隊列控制塊
								      &thread_2_received,//發送消息内容指針
					                  TX_WAIT_FOREVER //無限等待
					              );
			if(status == TX_SUCCESS)
			{
				sprintf(buf_rec,"thread_2_received %c ",thread_2_received);
				HAL_UART_Transmit(&huart1, (uint8_t*)buf_rec, sizeof(buf_rec), HAL_MAX_DELAY);
			}
			tx_thread_sleep(2000);

		}

}

void tx_application_define(void *first_unused_memory)
{
	/*使能追蹤*/
	trace_status = tx_trace_enable(&trace_buffer_start, trace_buffer_size,registry_entries);

	/*建立一個記憶體池用于配置設定線程棧*/
	tx_byte_pool_create(&byte_pool_0, 		//記憶體池的指針
			"byte pool 0",//名稱
			first_unused_memory,//配置設定記憶體位址
			DEMO_BYTE_POOL_SIZE//配置設定記憶體池大小
			);

	/*配置設定一個棧空間用于線程1*/
	tx_byte_allocate(&byte_pool_0,		   //記憶體池的指針
			(VOID**) &memory_ptr,		   //指向目标記憶體指針的指針
			DEMO_STACK_SIZE,     //配置設定棧大小
			TX_NO_WAIT		   //無論它是否成功,都會立即從該服務傳回
			);
	/*線程1*/
	tx_thread_create(&MyThread_1,	//線程控制塊指針
			"MyThread_1",//線程名字
			MyThread_1_entry,//線程入口函數
			0,//線程入口參數
			memory_ptr,//線程的起始位址
			DEMO_STACK_SIZE,//線程棧大小 K
			1,//優先級1 (0~TX_MAX_PRIORITES-1)0  表示最高優先級
			1,//禁用搶占的最高優先級
			TX_NO_TIME_SLICE,//時間切片值範圍為 1 ~ 0xFFFF(TX_NO_TIME_SLICE = 0)
			TX_AUTO_START//線程自動啟動
			);
	/*配置設定一個棧空間用于線程2*/
	tx_byte_allocate(&byte_pool_0,		   //記憶體池的指針
			(VOID**) &memory_ptr,		   //指向目标記憶體指針的指針
			DEMO_STACK_SIZE,     //配置設定棧大小
			TX_NO_WAIT		   //無論它是否成功,都會立即從該服務傳回
			);
	/*線程2*/
	tx_thread_create(&MyThread_2,	//線程控制塊指針
			"MyThread_2",//線程名字
			MyThread_2_entry,//線程入口函數
			0,//線程入口參數
			memory_ptr,//線程的起始位址
			DEMO_STACK_SIZE,//線程棧大小 K
			3,//優先級3 (0~TX_MAX_PRIORITES-1)0  表示最高優先級
			3,//禁用搶占的最高優先級
			TX_NO_TIME_SLICE,//時間切片值範圍為 1 ~ 0xFFFF(TX_NO_TIME_SLICE = 0)
			TX_AUTO_START//線程自動啟動
			);

	/*配置設定一個空間用于消息隊列*/
		tx_byte_allocate(&byte_pool_0,//記憶體池的指針
				(VOID**) &memory_ptr, //指向目标記憶體指針的指針
				100,   //配置設定消息隊列大小 100位元組
				TX_NO_WAIT //無論它是否成功,都會立即從該服務傳回
				);
		/* 建立消息隊列 */
		tx_queue_create(&my_queue, //消息隊列控制塊
				"my_queue",		   //消息隊列名稱
				4,				   //每一個消息大小
				memory_ptr,		   //消息隊列位址
				100				   //總大小100
				);


}
/* USER CODE END 4 */

           

thread_1 發送 ‘A’ —> ‘H’ 500 ticks

thread_1 發送 ‘C’ 的時候轉變位緊急消息

thread_1 發送 ‘I’ 的時候終止程序

thread_2 接受 2000 ticks

ThreadX(九)------消息隊列Queue
ThreadX(九)------消息隊列Queue
ThreadX(九)------消息隊列Queue

繼續閱讀