【STM32】CubeMX(十一):FreeRTOS任務掛起與解掛

這篇文章是 STM32 HAL + FreeRTOS 下的任務掛起與恢復機制, 結合 CubeMX 圖示與代碼,構建了一個 FreeRTOS 控制示例。

本篇目標:

創建兩個任務:
一個控制藍燈閃爍(myTask01
另一個監控按鍵(StartTask),實現對藍燈任務的掛起與解掛功能

一、FreeRTOS 中任務掛起和恢復的機制

操作函數說明
掛起任務vTaskSuspend(TaskHandle_t xTaskToSuspend)將任務狀態置為掛起,調度器不再調度它
恢復任務vTaskResume(TaskHandle_t xTaskToResume)重新激活任務,使其進入就緒態
自我掛起vTaskSuspend(NULL)當前任務掛起自身
查詢狀態可用 eTaskGetState() 獲取任務狀態

🧩當前的任務設計邏輯

? 控制任務:StartDefaultTask
  • 使用 GPIO 輸入讀取按鍵(PC1)
  • 實現一次性按鍵觸發檢測(Trg 邊沿檢測)
  • 判斷標志位 TaskState 來控制掛起/恢復
  • 使用 vTaskSuspend() / vTaskResume() 控制藍燈任務
? 被控制任務:myTask01
  • 閃爍藍燈(PC8)
  • 每 500ms 翻轉一次
? 運行效果說明
操作					現象
上電后				藍燈開始閃爍
按下按鍵一次			藍燈停止閃爍,串口輸出 “Suspend”
再次按下按鍵			藍燈繼續閃爍,串口輸出 “Resume”

🛠?二、CubeMX 配置說明

? 1. 啟用 FreeRTOS 軟件包
見圖:通過 Software PacksX-CUBE-FREERTOS 添加 RTOS 支持。

? 2. 配置任務列表
Tasks and Queues 中設置兩個任務 StartTaskmyTask01

? 3. FreeRTOS 參數配置
啟用 USE_PREEMPTION、堆大小、棧大小等

在這里插入圖片描述

在這里插入圖片描述

請添加圖片描述

🧩三、代碼邏輯解析

? 1. 按鍵檢測(邊沿觸發)

unsigned char ReadData = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1)^0xFF;
Trg = ReadData & (ReadData ^ Cont);  // 上升沿檢測
Cont = ReadData;
  • Trg:觸發信號,僅在狀態變化的那一拍為 1
  • Cont:當前電平狀態

? 2. StartTask 任務控制邏輯

if( Trg == 1 ) // 按鍵按下
{TaskState = !TaskState;if ((myTask01Handle != NULL) && (TaskState == 0)){vTaskSuspend(myTask01Handle);printf("myTask01 is Suspend ! \r\n");}else if ((myTask01Handle != NULL) && (TaskState == 1)){vTaskResume(myTask01Handle);printf("myTask01 is Resume ! \r\n");}
}

🔹 說明:

  • Trg 是按鍵觸發標志,代表邊沿檢測
  • TaskState 作為狀態標記,記錄當前任務是否處于掛起狀態
  • vTaskSuspend() 真正將任務掛起
  • vTaskResume() 將任務恢復

? 3. myTask01 任務內容(藍燈閃爍)(控制 PC8)

void StartTask01(void const * argument)
{for(;;){HAL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin);osDelay(500);}
}
  • 每 500ms 閃爍一次
  • 被掛起時,FreeRTOS 不再調度此任務,效果就是“藍燈停止閃爍”

完整代碼

📄 main.c

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */HAL_UARTEx_ReceiveToIdle_IT(  &huart1 , U1RxData, U1RxDataSize);/* USER CODE END 2 *//* Call init function for freertos objects (in freertos.c) */MX_FREERTOS_Init();/* Start scheduler */osKernelStart();/* We should never get here as control is now taken by the scheduler *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  Period elapsed callback in non blocking mode* @note   This function is called  when TIM6 interrupt took place, inside* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment* a global variable "uwTick" used as application time base.* @param  htim : TIM handle* @retval None*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* USER CODE BEGIN Callback 0 *//* USER CODE END Callback 0 */if (htim->Instance == TIM6) {HAL_IncTick();}/* USER CODE BEGIN Callback 1 *//* USER CODE END Callback 1 */
}/*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

📄 freertos.c

/* USER CODE BEGIN Header */
/********************************************************************************* File Name          : freertos.c* Description        : Code for freertos applications******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usart.h"/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables *//* USER CODE END Variables */
osThreadId StartTaskHandle;
osThreadId myTask01Handle;/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes *//* USER CODE END FunctionPrototypes */void StartDefaultTask(void const * argument);
void StartTask01(void const * argument);void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) *//* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;*ppxIdleTaskStackBuffer = &xIdleStack[0];*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;/* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY *//*** @brief  FreeRTOS initialization* @param  None* @retval None*/
void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init *//* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* definition and creation of StartTask */osThreadDef(StartTask, StartDefaultTask, osPriorityNormal, 0, 128);StartTaskHandle = osThreadCreate(osThread(StartTask), NULL);/* definition and creation of myTask01 */osThreadDef(myTask01, StartTask01, osPriorityIdle, 0, 128);myTask01Handle = osThreadCreate(osThread(myTask01), NULL);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS */}/* USER CODE BEGIN Header_StartDefaultTask */
/*** @brief  Function implementing the StartTask thread.* @param  argument: Not used* @retval None*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{/* USER CODE BEGIN StartDefaultTask */
//	static	uint16_t KeyTime  = 0;
//	static	bool KeyFlag  = 0;static	unsigned char Trg = 0,Trg_last = 0;static	unsigned char Cont = 0xFF,Cont_last = 0xFF;bool TaskState = 0;/* Infinite loop */for(;;){unsigned char ReadData = HAL_GPIO_ReadPin( GPIOC, GPIO_PIN_1)^0xff;   // 1Trg = ReadData & (ReadData ^ Cont);      															// 2Cont = ReadData; if(Trg != Trg_last){Trg_last = Trg;printf("Trg = %d \r\n",Trg);}if(Cont != Cont_last){Cont_last = Cont;printf("Cont = %d \r\n",Cont);}if( Trg == 1){TaskState = !TaskState;if((myTask01Handle != NULL) && (TaskState == 0)){vTaskSuspend( myTask01Handle );printf("myTask01 is Suspend ! \r\n");}if((myTask01Handle != NULL) && (TaskState == 1)){vTaskResume( myTask01Handle );printf("myTask01 is Resume ! \r\n");}}osDelay(1);}/* USER CODE END StartDefaultTask */
}/* USER CODE BEGIN Header_StartTask01 */
/**
* @brief Function implementing the myTask01 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask01 */
void StartTask01(void const * argument)
{/* USER CODE BEGIN StartTask01 *//* Infinite loop */for(;;){HAL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin);osDelay(500);}/* USER CODE END StartTask01 */
}/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application *//* USER CODE END Application */

串口調試效果驗證

Cont = 254
Trg = 1
Cont = 255
myTask01 is Resume !Trg = 1
myTask01 is Suspend !Trg = 1
myTask01 is Resume !

在這里插入圖片描述
? 表示按下按鍵 → 藍燈任務切換狀態 → 串口實時反饋。

實驗效果

操作現象
上電后藍燈開始閃爍
按一次按鍵藍燈停止閃爍,串口輸出:Suspend
再按一次藍燈恢復閃爍,串口輸出:Resume

調試中可能出現的問題

問題					排查點
藍燈不閃				myTask01 沒創建成功?GPIO初始化錯誤?
按鍵無效				檢查引腳是否浮空?是否加了外部上拉?
無串口輸出			UART 是否初始化?是否重定向 printf?
藍燈不停切換狀態		是否做了按鍵消抖?是否誤觸發?

我們還可以在此基礎之上,加入按鍵消抖定時器避免連續觸發; 使用中斷 + 信號量控制,提高效率,避免輪詢;增加多任務共享控制,控制多個任務掛起/恢復;還可以新增 OLED 顯示任務狀態,更直觀展示任務運行。

以上。利用 HAL 庫 + FreeRTOS,結合 vTaskSuspend vTaskResume 任務掛起與解掛,可以非常靈活地控制任務運行狀態,實現任務級能耗管理、資源調度和交互控制等高級功能。

以上,歡迎有從事同行業的電子信息工程、互聯網通信、嵌入式開發的朋友共同探討與提問,我可以提供實戰演示或模板庫。希望內容能夠對你產生幫助!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94434.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94434.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94434.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

圖片預加載:提升Web性能的關鍵

🤍 前端開發工程師、技術日更博主、已過CET6 🍨 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 🕠 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 🍚 藍橋云課簽約作者、…

大模型壓縮三劍客:量化、剪枝與知識蒸餾全解析

在人工智能飛速發展的今天,大語言模型(LLM)如通義千問、GPT 等已成為推動智能應用的核心引擎。然而,這些模型動輒數十億甚至上千億參數,帶來了高昂的計算成本和部署門檻。如何在不顯著犧牲性能的前提下,讓大…

Seaborn數據可視化實戰:Seaborn基礎圖表繪制入門

基礎圖表繪制:Seaborn入門教程 學習目標 通過本課程的學習,你將掌握如何使用Seaborn庫繪制基礎圖表,包括條形圖、折線圖和散點圖。你將了解Seaborn的基本函數和參數設置,以及如何通過調整這些參數來優化圖表的視覺效果。 相關知識…

阿里開源通義萬相Wan2.2:視頻生成技術的革命性突破

在人工智能視頻生成領域,阿里云通義實驗室于2025年7月重磅開源了新一代視頻生成大模型 Wan2.2,其核心亮點包括人體動作生成的極致精度、電影級美學表達以及高效的資源利用效率,標志著視頻生成技術邁入了一個全新的階段。 一、核心功能:三大模型,覆蓋全場景視頻生成 Wan2.…

說說你對Integer緩存的理解?

大家好,我是鋒哥。今天分享關于【說說你對Integer緩存的理解?】面試題。希望對大家有幫助; 說說你對Integer緩存的理解? 超硬核AI學習資料,現在永久免費了! Integer 緩存是 Java 中一個優化機制,它主要通過緩存一部…

高速CANFD收發器ASM1042在割草機器人輪轂電機通信系統中的適配性研究

摘要割草機器人輪轂電機的通信系統對其實現自主控制和高效作業至關重要。本文旨在研究國科安芯推出的高速CANFD收發器芯片ASM1042是否能夠滿足割草機器人輪轂電機通信系統的復雜需求。通過詳細分析輪轂電機通信系統的性能要求,以及ASM1042的電氣、功能和環境特性&am…

MTK Linux DRM分析(十二)- KMS Panel框架層(drm_panel.c、drm_mipi_dbi.c、drm_mipi_dsi.c)

一、簡介 三個代碼文件(drm_mipi_dbi.c、drm_panel.c、drm_mipi_dsi.c)的分析。這些文件都是Linux內核DRM(Direct Rendering Manager)子系統的組成部分,主要用于支持顯示面板,特別是通過MIPI(Mobile Industry Processor Interface)接口的顯示設備。它們提供了顯示驅動…

合合信息acge模型獲C-MTEB第一,文本向量化迎來新突破

前言: 在當今時代,大型語言模型以其驚人的發展速度和廣泛的應用前景,正成為全球科技界的矚目焦點。這些模型的強大能力,源自于背后默默支撐它們的Embedding技術——一種將語言轉化為機器可理解的數值向量的關鍵技術。隨著大型語言…

26.內置構造函數

2.內置構造函數2.1Object2.2Array2.3String2.4number

tauri配置允許執行eval腳本,在打包cocos游戲web/phone移動端的時候一定要配置

解決辦法:在tauriconfig中配置"csp": "default-src self asset: unsafe-inline customprotocol://* http://localhost:* ws:localhost:* unsafe-eval ipc: http://ipc.localhost; script-src unsafe-eval self https://www.googletagmanager.com uns…

K 均值聚類算法學習總結

一、聚類算法基礎認知 核心概念:聚類屬于無監督學習,核心是把 “相似的樣本” 自動分到同一組(簇),不需要預先標注的標簽。主要挑戰是怎么定義 “相似性”、評估聚類效果以及確定最好的聚類數量。 距離度量&#xff1a…

基于Spring Cloud Gateway動態路由與灰度發布方案對比與實踐指導

基于Spring Cloud Gateway動態路由與灰度發布方案對比與實踐指導 一、問題背景介紹 在微服務架構中,API網關負責統一入口、路由分發與權限校驗功能。隨著業務需求的不斷演進,如何靈活地實現路由動態更新、版本灰度發布以及流量打點就成為運維和開發團隊的…

MySQL InnoDB Buffer Pool詳解:原理、配置與性能優化

1. 為什么需要 Buffer Pool?1.1 數據庫性能瓶頸分析在 MySQL 的運行過程中,最核心的性能瓶頸來自磁盤 IO。磁盤訪問延遲:一次機械硬盤 IO 操作可能需要數毫秒,即使是 SSD,訪問延遲也在幾十微秒量級。內存訪問延遲&…

ArcGIS Pro 安裝路徑避坑指南:從崩潰根源到規范實操(附問題修復方案)

作為 GIS 從業者,你是否遇到過這些糟心場景:ArcGIS Pro 雙擊啟動無響應、運行中突然彈出 “Runtime Error” 崩潰、加載矢量數據時提示 “找不到指定文件”?排查半天后發現,這些問題的 “元兇” 竟藏在安裝路徑里 —— 中文路徑或…

Python 實戰:內網滲透中的信息收集自動化腳本(2)

用途限制聲明,本文僅用于網絡安全技術研究、教育與知識分享。文中涉及的滲透測試方法與工具,嚴禁用于未經授權的網絡攻擊、數據竊取或任何違法活動。任何因不當使用本文內容導致的法律后果,作者及發布平臺不承擔任何責任。滲透測試涉及復雜技…

批量轉雙層PDF軟件:高效轉換,提升文檔管理效率

在文檔管理和信息檢索中,雙層PDF文件因其獨特的結構而備受青睞。雙層PDF文件不僅保留了原始文檔的外觀,還增加了對文檔內容進行搜索和選擇的功能,極大地提高了文檔管理和信息檢索的效率。批量轉雙層PDF軟件正是為了解決這一需求而設計的&…

rust語言 (1.88) egui (0.32.1) 學習筆記(逐行注釋)(七) 鼠標在控件上懸浮時的提示

文本提示on_hover_text ui.label("標簽").on_hover_text("這是一個標簽"); ui.text_edit_singleline(&mut edittext).on_hover_text("這是輸入框"); if ui.button("提交").on_hover_text("這是一個按鈕").clicked(){}提…

【NVIDIA-B200】生產報錯 Test CUDA failure common.cu:1035 ‘system not yet initialized‘

目錄 1. 檢查 NVIDIA 驅動狀態 2. 驗證 CUDA 安裝情況 3. 檢查相關服務運行狀態(多 GPU 場景關鍵) 4. 用簡單 CUDA 程序驗證基礎功能 5. 重啟系統 6. 排查硬件相關問題 7.實際生產解決步驟 報錯日志: # Collective test starting: all_reduce_perf # nThread 1 nGpu…

ansible playbook 實戰案例roles | 實現基于nfs的日志歸檔

文章目錄一、核心功能描述二、roles內容2.1 文件結構2.2 tasks文件內容2.3 files文件內容免費個人運維知識庫,歡迎您的訂閱:literator_ray.flowus.cn 一、核心功能描述 這個 Ansible Role 的核心功能是:?實現自動化日志歸檔系統&#xff0c…

RabbitMQ:技巧匯總

目錄一、基礎知識1.1、RabbitMQ:Windows版本安裝部署1.2、RabbitMQ:Linux版本安裝部署1.3、RabbitMQ:數據隔離1.4、RabbitMQ:交換機(Exchange)1.5、RabbitMQ:SpringAMQP入門案例1.6、RabbitMQ&a…