RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RTOS實現(xiàn)雙核MCU消息通信

strongerHuang ? 來源:strongerHuang ? 2023-06-07 14:48 ? 次閱讀

手機電腦多核的CPU你可能經(jīng)??匆姡嗪说?a target="_blank">單片機相對來說就不那么常見了。隨著需求的增加、技術(shù)的進步,單片機已不再局限于單核了,因此,近幾年陸續(xù)出現(xiàn)了雙核的單片機了。 你可能會好奇,雙核單片機之間怎么通信?其實,通信的方式和方法有很多種。本文就給大家描述一下:使用FreeRTOS消息緩沖區(qū),實現(xiàn)簡單的非對稱多處理(AMP)核心到核心通信,結(jié)合STM32H7(M4和M7) 雙核處理器為例。

分享正文之前推薦一個嵌入式招聘信息的平臺:

概述

實現(xiàn)STM32H7雙核之間通信是FreeRTOS官方提供的一個方案,是基于FreeRTOS消息緩沖區(qū),該消息緩沖區(qū)是無鎖循環(huán)緩沖區(qū),可以將大小不同的數(shù)據(jù)包從單個發(fā)送方傳遞到單個接收方。 說明,該消息緩沖區(qū)僅提供數(shù)據(jù)的傳輸,不提供通信相關(guān)協(xié)議處理。

基本原理

實現(xiàn)雙核之間通信基本原理:發(fā)送和接收任務(wù)位于非對稱多處理器(AMP)配置中的多核微控制器MCU)的不同內(nèi)核上,這意味著每個內(nèi)核都運行自己的FreeRTOS程序。 同時,一個內(nèi)核在另一個內(nèi)核中具有生成中斷的能力,以及兩個內(nèi)核都有訪問的內(nèi)存區(qū)域(共享內(nèi)存)。消息緩沖區(qū)以每個內(nèi)核上運行在應(yīng)用程序已知的地址置在共享內(nèi)存中,如下圖:cb6c46fc-04fe-11ee-90ce-dac502259ad0.png ?理想情況下,還將有一個內(nèi)存保護單元(MPU),以確保只能通過內(nèi)核的消息緩沖區(qū)API來訪問消息緩沖區(qū),并最好將共享內(nèi)存標(biāo)記為不可被其他程序占用。

單消息代碼描述

這里官方提供了實現(xiàn)該方案的基礎(chǔ)代碼(僅供參考)。 將數(shù)據(jù)發(fā)送到流緩沖區(qū)的代碼:
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()
    }
}
從流緩沖區(qū)讀取數(shù)據(jù)的代碼:
xMessageBufferReceive()
{
    /* If a time out is specified and the buffer doesn't
    contain any data that can be 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()
    }
}
如果任務(wù)在xMessageBufferReceive()中進入阻塞狀態(tài)以等待緩沖區(qū)包含數(shù)據(jù),則將數(shù)據(jù)發(fā)送到緩沖區(qū)必須取消阻塞該任務(wù),以便它可以完成其操作。 當(dāng)xMessageBufferSend()調(diào)用sbSEND_COMPLETED()時,任務(wù)將不受阻礙。cb8bba1e-04fe-11ee-90ce-dac502259ad0.png ?ISR通過將消息緩沖區(qū)的句柄作為參數(shù)傳遞給xMessageBufferSendCompletedFromISR()函數(shù)來解除對任務(wù)的阻塞。 如圖箭頭所示,其中發(fā)送和接收任務(wù)位于不同的MCU內(nèi)核上:1.接收任務(wù)嘗試從空的消息緩沖區(qū)中讀取數(shù)據(jù),并進入阻止?fàn)顟B(tài)以等待數(shù)據(jù)到達(dá)。2.發(fā)送任務(wù)將數(shù)據(jù)寫入消息緩沖區(qū)。3.sbSEND_COMPLETED()在正在執(zhí)行接收任務(wù)的內(nèi)核中觸發(fā)一個中斷。4.中斷服務(wù)例程調(diào)用xMessageBufferSendCompletedFromISR()來解除阻止接收任務(wù),該任務(wù)現(xiàn)在可以從緩沖區(qū)讀取,因為緩沖區(qū)不再為空。

多消息代碼描述

當(dāng)只有一個消息緩沖區(qū)時,很容易將消息緩沖區(qū)的句柄傳遞到xMessageBufferSendCompletedFromISR()中。 但是要考慮有兩個或更多消息緩沖區(qū)的情況,ISR必須首先確定哪個消息緩沖區(qū)包含數(shù)據(jù)。如果消息緩沖區(qū)的數(shù)量很少,則有幾種方法可以實現(xiàn):
  • 如果硬件允許,則每個消息緩沖區(qū)可以使用不同的中斷線,從而使中斷服務(wù)程序和消息緩沖區(qū)之間保持一對一的映射。
  • 中斷服務(wù)例程可以簡單地查詢每個消息緩沖區(qū)以查看其是否包含數(shù)據(jù)。
  • 可以通過傳遞元數(shù)據(jù)(消息是什么,消息的預(yù)期接收者是什么等等)以及實際數(shù)據(jù)的單個消息緩沖區(qū)來代替多個消息緩沖區(qū)。
但是,如果存在大量或未知的消息緩沖區(qū),則這些技術(shù)效率不高。 在這種情況下,可伸縮的解決方案是引入單獨的控制消息緩沖區(qū)。如下面的代碼所示,sbSEND_COMPLETED()使用控制消息緩沖區(qū)將包含數(shù)據(jù)的消息緩沖區(qū)的句柄傳遞到中斷服務(wù)例程中。 使用sbSEND_COMPLETED()的實現(xiàn):
/* 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讀取控制消息緩沖區(qū)以獲得句柄,將句柄作為參數(shù)傳遞到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 );
}
cb941420-04fe-11ee-90ce-dac502259ad0.png如圖,使用控制消息緩沖區(qū)時的順序:1.接收任務(wù)嘗試從空的消息緩沖區(qū)中讀取數(shù)據(jù),并進入阻止?fàn)顟B(tài)以等待數(shù)據(jù)到達(dá)。2.發(fā)送任務(wù)將數(shù)據(jù)寫入消息緩沖區(qū)。3.sbSEND_COMPLETED()將現(xiàn)在包含數(shù)據(jù)的消息緩沖區(qū)的句柄發(fā)送到控制消息緩沖區(qū)。4.sbSEND_COMPLETED()在正在執(zhí)行接收任務(wù)的內(nèi)核中觸發(fā)一個中斷。5.中斷服務(wù)例程從控制消息緩沖區(qū)中讀取包含數(shù)據(jù)的消息緩沖區(qū)的句柄,然后將該句柄傳遞給xMessageBufferSendCompletedFromISR()API函數(shù)以取消阻止接收任務(wù),該任務(wù)現(xiàn)在可以從緩沖區(qū)讀取,因為緩沖區(qū)不再存在空的。 當(dāng)然,以上僅提供基礎(chǔ)原理和方法,具體實現(xiàn)需結(jié)合項目實際情況。更多相關(guān)內(nèi)容,請參看官方相關(guān)資料。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    17123

    瀏覽量

    350982
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10854

    瀏覽量

    211578
  • RTOS
    +關(guān)注

    關(guān)注

    22

    文章

    811

    瀏覽量

    119593

原文標(biāo)題:RTOS實現(xiàn)雙核MCU消息通信

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    RTOS實現(xiàn)MCU消息通信

    之間怎么通信?其實,通信的方式和方法有很多種。本文就給大家描述一下:使用FreeRTOS消息緩沖區(qū),實現(xiàn)簡單的非對稱多處理(AMP)核心到核心通信,結(jié)合STM32H7(M4和M7)
    發(fā)表于 06-07 14:45 ?1181次閱讀
    <b class='flag-5'>RTOS</b><b class='flag-5'>實現(xiàn)</b><b class='flag-5'>雙</b><b class='flag-5'>核</b><b class='flag-5'>MCU</b>消息<b class='flag-5'>通信</b>

    非對稱MCU基礎(chǔ)知識及通信

    來源 網(wǎng)絡(luò)本文從對比兩顆分立MCU與單芯片MCU開始(以LPC4350為例),展開介紹了非對稱
    發(fā)表于 05-15 14:26

    OMAPL138的通信組件DSPLINK開發(fā)和通信演示教程

    共享一個OMAPL138的通信組件DSPLINK開發(fā)和通信演示教程,希望大家頂頂??!
    發(fā)表于 06-21 17:09

    基于MCU提高系統(tǒng)性能

    MCU 內(nèi)核的資源和不同任務(wù)所需要的運行時間,需要更多的測試時間,因此不利于擴展和產(chǎn)品維護。面對種種不足,異構(gòu)架構(gòu)應(yīng)運而生,可以很好解決上述問題。事實上,非對稱
    發(fā)表于 07-04 07:49

    非對稱MCU的基礎(chǔ)知識與重要特點

    本文從對比兩顆分立MCU與單芯片MCU開始(以LPC4350為例),展開介紹了非對稱
    發(fā)表于 11-01 06:29

    MCU Pico的相關(guān)資料分享

    樹莓派不講武德,自研MCU Pico,STM32哭暈在廁所!重磅,樹莓派再出Pico自研MCU
    發(fā)表于 11-04 08:51

    如何用一個比較簡單SMP的example來體現(xiàn)的處理能力比單核強呢?

    qemu-vexpress-a9 這個平臺上實現(xiàn)一下。或者換個問題:在MCU的大部分應(yīng)用場景下(排除MPU),大家都是如何看待,什么情況下必須上
    發(fā)表于 03-13 15:17

    請問之間如何通信?

    請問之間如何通信? 怎么處理核對外設(shè)資源出現(xiàn)競爭的問題?
    發(fā)表于 05-26 06:37

    DSP MCU,什么是SP MCU

    DSP MCU,什么是SP MCU 各種數(shù)字消費產(chǎn)品特別是便攜式數(shù)字產(chǎn)品的功能已由單一
    發(fā)表于 03-26 15:00 ?1022次閱讀

    非對稱MCU基礎(chǔ)知識及通信

    本文從對比兩顆分立MCU與單芯片MCU開始(以LPC4350為例),展開介紹了非對稱
    發(fā)表于 03-26 15:31 ?3667次閱讀
    非對稱<b class='flag-5'>雙</b><b class='flag-5'>核</b><b class='flag-5'>MCU</b>基礎(chǔ)知識及<b class='flag-5'>核</b>間<b class='flag-5'>通信</b>

    應(yīng)用非對稱MCU增強系統(tǒng)性能

    本文從對比兩顆分立MCU與單芯片MCU開始(以LPC4350為例),展開介紹了非對稱
    發(fā)表于 04-11 10:05 ?1043次閱讀
    應(yīng)用非對稱<b class='flag-5'>雙</b><b class='flag-5'>核</b><b class='flag-5'>MCU</b>增強系統(tǒng)性能

    非對稱MCU基礎(chǔ)知識及通信

    本文從對比兩顆分立MCU與單芯片MCU開始(以LPC4350為例),展開介紹了非對稱
    的頭像 發(fā)表于 03-13 15:47 ?5188次閱讀
    非對稱<b class='flag-5'>雙</b><b class='flag-5'>核</b><b class='flag-5'>MCU</b>基礎(chǔ)知識及<b class='flag-5'>核</b>間<b class='flag-5'>通信</b>

    非對稱MCU基礎(chǔ)知識及通信

    本文從對比兩顆分立MCU與單芯片MCU開始(以LPC4350為例),展開介紹了非對稱
    發(fā)表于 10-26 09:21 ?11次下載
    非對稱<b class='flag-5'>雙</b><b class='flag-5'>核</b><b class='flag-5'>MCU</b>基礎(chǔ)知識及<b class='flag-5'>核</b>間<b class='flag-5'>通信</b>

    先楫HPM6000系列MCU怎么玩?

    多核的微控制器(MCU)向來是設(shè)計上的一大挑戰(zhàn),尤其是多核異構(gòu)的設(shè)計。而MCU作為其中的精簡版本,憑借其超強的處理性能和便捷開發(fā)的特性,很快受到業(yè)界的好評。先楫半導(dǎo)體先后推出了幾款
    的頭像 發(fā)表于 05-10 14:25 ?1661次閱讀
    先楫HPM6000系列<b class='flag-5'>雙</b><b class='flag-5'>核</b><b class='flag-5'>MCU</b>怎么玩?

    先楫HPM6000系列MCU通信方式和資源分配

    在《玩轉(zhuǎn)MCU(上)》文章里,我們給大家介紹了先楫HPM6000系列的特性、使用方法以及工程編譯與調(diào)試。本文緊接上篇內(nèi)容,給大家詳細(xì)
    的頭像 發(fā)表于 05-14 09:58 ?3584次閱讀
    先楫HPM6000系列<b class='flag-5'>MCU</b><b class='flag-5'>雙</b><b class='flag-5'>核</b>的<b class='flag-5'>通信</b>方式和資源分配
    RM新时代网站-首页