手機、電腦多核的CPU你可能經常看見,但多核的單片機相對來說就不那么常見了。隨著需求的增加、技術的進步,單片機已不再局限于單核了,因此,近幾年陸續出現了雙核的單片機了。 你可能會好奇,雙核單片機之間怎么通信?其實,通信的方式和方法有很多種。本文就給大家描述一下:使用FreeRTOS消息緩沖區,實現簡單的非對稱多處理(AMP)核心到核心通信,結合STM32H7(M4和M7) 雙核處理器為例。
(資料圖片僅供參考)
概述
實現STM32H7雙核之間通信是FreeRTOS官方提供的一個方案,是基于FreeRTOS消息緩沖區,該消息緩沖區是無鎖循環緩沖區,可以將大小不同的數據包從單個發送方傳遞到單個接收方。 說明,該消息緩沖區僅提供數據的傳輸,不提供通信相關協議處理。
基本原理
實現雙核之間通信基本原理:發送和接收任務位于非對稱多處理器(AMP)配置中的多核微控制器(MCU)的不同內核上,這意味著每個內核都運行自己的FreeRTOS程序。 同時,一個內核在另一個內核中具有生成中斷的能力,以及兩個內核都有訪問的內存區域(共享內存)。消息緩沖區以每個內核上運行在應用程序已知的地址置在共享內存中,如下圖: 理想情況下,還將有一個內存保護單元(MPU),以確保只能通過內核的消息緩沖區API來訪問消息緩沖區,并最好將共享內存標記為不可被其他程序占用。
單消息代碼描述
這里官方提供了實現該方案的基礎代碼(僅供參考)。 將數據發送到流緩沖區的代碼:
xMessageBufferSend(){ /* If a time out is specified and there isn"t enough space in the message buffer to send the data, then enter the blocked state to wait for more space. */ if( time out != 0 ) { while( there is insufficient space in the buffer && not timed out waiting ) { Enter the blocked state to wait for space in the buffer } } if( there is enough space in the buffer ) { write data to buffer sbSEND_COMPLETED() }}從流緩沖區讀取數據的代碼:xMessageBufferReceive(){ /* If a time out is specified and the buffer doesn"t contain any data that canbe read, then enter the blocked state to wait for the buffer to contain data. */ if( time out != 0 ) { while( there is no data in the buffer && not timed out waiting ) { Enter the blocked state to wait for data } } if( there is data in the buffer ) { read data from buffer sbRECEIVE_COMPLETED() }}如果任務在xMessageBufferReceive()中進入阻塞狀態以等待緩沖區包含數據,則將數據發送到緩沖區必須取消阻塞該任務,以便它可以完成其操作。 當xMessageBufferSend()調用sbSEND_COMPLETED()時,任務將不受阻礙。 ISR通過將消息緩沖區的句柄作為參數傳遞給xMessageBufferSendCompletedFromISR()函數來解除對任務的阻塞。 如圖箭頭所示,其中發送和接收任務位于不同的MCU內核上:1.接收任務嘗試從空的消息緩沖區中讀取數據,并進入阻止狀態以等待數據到達。2.發送任務將數據寫入消息緩沖區。3.sbSEND_COMPLETED()在正在執行接收任務的內核中觸發一個中斷。4.中斷服務例程調用xMessageBufferSendCompletedFromISR()來解除阻止接收任務,該任務現在可以從緩沖區讀取,因為緩沖區不再為空。 多消息代碼描述
當只有一個消息緩沖區時,很容易將消息緩沖區的句柄傳遞到xMessageBufferSendCompletedFromISR()中。 但是要考慮有兩個或更多消息緩沖區的情況,ISR必須首先確定哪個消息緩沖區包含數據。如果消息緩沖區的數量很少,則有幾種方法可以實現:
如果硬件允許,則每個消息緩沖區可以使用不同的中斷線,從而使中斷服務程序和消息緩沖區之間保持一對一的映射。
中斷服務例程可以簡單地查詢每個消息緩沖區以查看其是否包含數據。
可以通過傳遞元數據(消息是什么,消息的預期接收者是什么等等)以及實際數據的單個消息緩沖區來代替多個消息緩沖區。
但是,如果存在大量或未知的消息緩沖區,則這些技術效率不高。 在這種情況下,可伸縮的解決方案是引入單獨的控制消息緩沖區。如下面的代碼所示,sbSEND_COMPLETED()使用控制消息緩沖區將包含數據的消息緩沖區的句柄傳遞到中斷服務例程中。 使用sbSEND_COMPLETED()的實現:
/* Added to FreeRTOSConfig.h to override the default implementation. */#define sbSEND_COMPLETED( pxStreamBuffer ) vGenerateCoreToCoreInterrupt( pxStreamBuffer )/* Implemented in a C file. */void vGenerateCoreToCoreInterrupt( MessageBufferHandle_t xUpdatedBuffer ){size_t BytesWritten. /* Called by the implementation of sbSEND_COMPLETED() in FreeRTOSConfig.h. If this function was called because data was written to any message buffer other than the control message buffer then write the handle of the message buffer that contains data to the control message buffer, then raise an interrupt in the other core. If this function was called because data was written to the control message buffer then do nothing. */ if( xUpdatedBuffer != xControlMessageBuffer ) { BytesWritten = xMessageBufferSend( xControlMessageBuffer, &xUpdatedBuffer, sizeof( xUpdatedBuffer ), 0 ); /* If the bytes could not be written then the control message buffer is too small! */ configASSERT( BytesWritten == sizeof( xUpdatedBuffer ); /* Generate interrupt in the other core (pseudocode). */ GenerateInterrupt(); }}然后,ISR讀取控制消息緩沖區以獲得句柄,將句柄作為參數傳遞到xMessageBufferSendCompletedFromISR()中:void InterruptServiceRoutine( void ){MessageBufferHandle_t xUpdatedMessageBuffer;BaseType_t xHigherPriorityTaskWoken = pdFALSE; /* Receive the handle of the message buffer that contains data from the control message buffer. Ensure to drain the buffer before returning. */ while( xMessageBufferReceiveFromISR( xControlMessageBuffer, &xUpdatedMessageBuffer, sizeof( xUpdatedMessageBuffer ), &xHigherPriorityTaskWoken ) == sizeof( xUpdatedMessageBuffer ) ) { /* Call the API function that sends a notification to any task that is blocked on the xUpdatedMessageBuffer message buffer waiting for data to arrive. */ xMessageBufferSendCompletedFromISR( xUpdatedMessageBuffer, &xHigherPriorityTaskWoken ); } /* Normal FreeRTOS "yield from interrupt" semantics, where xHigherPriorityTaskWoken is initialised to pdFALSE and will then get set to pdTRUE if the interrupt unblocks a task that has a priority above that of the currently executing task. */ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );}如圖,使用控制消息緩沖區時的順序:1.接收任務嘗試從空的消息緩沖區中讀取數據,并進入阻止狀態以等待數據到達。2.發送任務將數據寫入消息緩沖區。3.sbSEND_COMPLETED()將現在包含數據的消息緩沖區的句柄發送到控制消息緩沖區。4.sbSEND_COMPLETED()在正在執行接收任務的內核中觸發一個中斷。5.中斷服務例程從控制消息緩沖區中讀取包含數據的消息緩沖區的句柄,然后將該句柄傳遞給xMessageBufferSendCompletedFromISR()API函數以取消阻止接收任務,該任務現在可以從緩沖區讀取,因為緩沖區不再存在空的。 當然,以上僅提供基礎原理和方法,具體實現需結合項目實際情況。更多相關內容,請參看官方相關資料。審核編輯:湯梓紅 標簽:
- 淮劇《小白楊》深情上演 致敬一代代援疆人的“精神豐碑”
- 寧德時代出資20億元在洛陽成立新公司 經營范圍含電池制造等業務_即時焦點
- 小法:我尊重圖多爾但他不尊重我,溫格觀戰是我給他買的票_今日快看
- 農發行湖南省分行違反金融統計規定被警告并罰款135.4萬元 速讀
- 黃曉明回應為新戲增肥30斤:這是我人生中最快樂的時光 觀速訊
- 每日動態!國家統計局:9月份社會消費品零售總額增長3.0%
- 中國之變|這五年,數字化點亮新生活-每日觀點
- 大行評級丨里昂:上調臺積電目標價至2000新臺幣 維持“高度確信跑贏大市”評級_每日時訊
- 熱消息:內蒙古赤峰農村牧區產權流轉服務中心完成首單交易
- 熱資訊!贛C支持湘C!宜春“老表”跨城應援
- 丹尼-格林:姚明如不傷難以想象,文班或能成為他本該成為的人
- 房產投資的風險與收益權衡?
- 鼎佳精密:10月17日獲融資買入291.41萬元_快資訊
- 財報速遞:達瑞電子2025年前三季度凈利潤2.31億元 每日動態
- 廣州湛建建材有限公司成立 注冊資本10萬人民幣|焦點快播
- 今日熱搜:時空科技擬“跨界”收購 切入半導體存儲賽道
- 當前聚焦:佑駕創新中標1185萬元車路云一體化城市交通融合感知項目
- 中原證券擬實施2025年半年度權益分派,共計派發現金紅利3714.31萬元-當前熱議
- 每日視點!主場戰三鎮賽前,大連英博為隊史首位外援羅伯森舉辦退役儀式
- 祥生醫療前三季度營業收入3.43億元,同比下降5.27%
- 江蘇最低工資標準公布
- 首佳科技于10月17日耗資56萬港元回購70萬股-每日消息
- 靳東:延安的變化讓人刮目相看_焦點簡訊
- 當前關注:凡人微光|這座城的精神,正年輕!
- 又見中小銀行密集調降存款利率-簡訊
- 前沿熱點:思源電氣前三季度凈利21.91億元,同比增長46.94%
- 今日快看!劉浩存談藝術的生命力
- 要聞:呂瑞浩公參會見上海市疾控局團組
- 光庭信息:2025年前三季度凈利潤4477.54萬元 同比增長308.53%_最新資訊
- 拿起手機就能免費聽講座、看展覽 “十四五”期間多彩文化點亮生活





