激情综合丁香-激情综合六月-激情综合婷婷亚洲图片-激情综合图区-激情综合网五月

ESM8000異構(gòu)CPU實時應(yīng)用——6路CAN-FD的實現(xiàn)

 2021-9-7     作者:劉乾坤 黃志超 朱賢武         
文章標(biāo)簽:C/C++ESM8000系列CAN

  ESM8000工控主板搭載了NXP i.MX8M Mini Quad 64位異構(gòu)處理器,包含了一顆主頻1.6GHz的四核ARM Cortex-A53和一顆主頻400MHz 的ARM Cortex-M4。Linux系統(tǒng)在Cortex-A53核心上運行,對于一些實時性要求極高的應(yīng)用,Linux系統(tǒng)可能無法滿足對中斷事件的及時響應(yīng),而且頻繁的中斷響應(yīng)也會大大的降低操作系統(tǒng)性能。對這類應(yīng)用場合就可充分利用i.MX8MM異構(gòu)多核結(jié)構(gòu),由高性能的Cortex-A53(Linux系統(tǒng))完成人機交互、數(shù)據(jù)處理、通訊管理等復(fù)雜運算,而對于實時的數(shù)據(jù)采集、高速的中斷事件響應(yīng)等實時任務(wù)交由Cotex-M4完成。


  控制器局域網(wǎng) (Controller Area Network,簡稱CAN或者CAN bus) 是一種功能豐富的總線標(biāo)準(zhǔn)。最開始作為車載總線而被設(shè)計出來,隨著CAN總線標(biāo)準(zhǔn)的不斷發(fā)展和完善,在工業(yè)領(lǐng)域中越來越多的行業(yè)會使用到CAN總線。在實際的應(yīng)用中,為了保證CAN總線的實時性,一般要求CAN總線的負(fù)載不能過高。因此在連接多個設(shè)備的時候,就需要使用到多路CAN總線來進行連接,保證每一路CAN總線的負(fù)載滿足要求。


  英創(chuàng)公司針對多CAN總線應(yīng)用的需求設(shè)計了ETA706模塊,該模塊通過SPI總線與主板連接,利用ESM8000的SPI1,再通過ESM8000的兩位GPIO譯碼出4個片選,擴展了4片MCP2518FD CAN控制芯片,支持CAN2.0 / CAN FD協(xié)議,加上主板上自帶的兩路CAN,實現(xiàn)了6路CAN總線方案。CAN擴展原理框圖與硬件測試環(huán)境,如圖1、圖2所示:


ESM8000異構(gòu)CPU實時應(yīng)用——多路CAN擴展.png

圖1:6x CAN擴展驅(qū)動原理框圖


sbc880+esm8000+eta706.png

圖2:  6x CAN硬件測試環(huán)境


  當(dāng)CAN總線上數(shù)據(jù)量較大時,SPI總線需要頻繁的中斷和讀寫操作,如果由Linux系統(tǒng)來處理中斷和SPI操作,就會占用相當(dāng)多的CPU資源。此時就可充分利用i.MX8MM異構(gòu)CPU結(jié)構(gòu),由Crotex-M4來處理CAN中斷和SPI通訊,Linux系統(tǒng)只處理Crotex-M4傳遞過來的CAN帖數(shù)據(jù),從而大大節(jié)省ESM8000上Cortex-A53的開銷,留出更多CPU資源。


  Coretx-M4應(yīng)用程序基于FreeRTOS,完成了對MCP2518FD參數(shù)配置、中斷響應(yīng)、數(shù)據(jù)收發(fā)等工作。由于擴展的4路MCP2518FD使用ESM8000的SPI1,通過2位GPIO譯碼出4個片選,所以對SPI1的操作使用Mutex信號量進行互斥保護。對多個MCP2815FD進行片選的實現(xiàn)代碼如下:


#define CH_SEL0 ESM_GPIO26
#define CH_SEL1 ESM_GPIO27
ecspi_rtos_handle_t *DRV_SPI_ChipSelectAssert(uint8_t spiSlaveDeviceIndex, bool assert)
{
    ecspi_rtos_handle_t *handle = NULL;
    static uint8_t last_spiIndex = 0;
    if (assert)
    {        
        if(spiSlaveDeviceIndex < 2)
            handle = &spi[1 + spiSlaveDeviceIndex];
        else        {
            /* Lock resource mutex */
            xSemaphoreTake(spi1_mutex, portMAX_DELAY);  
            
            handle = &spi[0];
            spiSlaveDeviceIndex -= 2;
            /* i.MX8MM 操作一次GPIO的需要300ns左右,所以這里對操作GPIO進行優(yōu)化 */
            if(spiSlaveDeviceIndex != last_spiIndex)           {
                switch (spiSlaveDeviceIndex)
                {
                case 0:
                    GPIO_PortOutClear(CH_SEL0, (0x1 << CH_SEL0->pin) | (0x1 << CH_SEL1->pin));
                    break;
                case 1:    
                    if((last_spiIndex & 0x01) == 0)                
                        GPIO_OutSet(CH_SEL0, 1);
                    if((last_spiIndex & 0x02) != 0)
                        GPIO_OutSet(CH_SEL1, 0);
                    break;
                case 2:
                    if((last_spiIndex & 0x01) != 0)   
                        GPIO_OutSet(CH_SEL0, 0);
                    if((last_spiIndex & 0x02) == 0)
                        GPIO_OutSet(CH_SEL1, 1);
                    break;
                case 3:
                    GPIO_PortOutSet(CH_SEL0, (0x1 << CH_SEL0->pin) | (0x1 << CH_SEL1->pin));
                    break;
                default:
                    handle = NULL;
                    last_spiIndex = 0;
                    GPIO_PortOutClear(CH_SEL0, (0x1 << CH_SEL0->pin) | (0x1 << CH_SEL1->pin));
                }
                last_spiIndex = spiSlaveDeviceIndex;
            }
        }
    }
    else    {
        if (spiSlaveDeviceIndex > 1)        {
            /* Unlock resource mutex */
            (void)xSemaphoreGive(spi1_mutex);
        }
    }
return handle;
}


  4路MCP2815FD的中斷輸出直接連接到ESM8000的4位GPIO, GPIO在i.MX8MM處理器上是按組(PORT)操作的。每組32位IO,而IO中斷又在PORT內(nèi)再次被分為高低兩組,每組對應(yīng)16位IO,共享一個中斷源。以擴展的CAN2和CAN3為例,它們的中斷輸出分別連接到ESM8000的GPIO2、GPIO3,分別對應(yīng)到i.MX8MM的GPIO_PORT5_Pin26和GPIO_PORT5_Pin27,它們使用同一個GPIO中斷源GPIO5_Combined_16_31_IRQn。當(dāng)GPIO中斷產(chǎn)生后,需要通過讀取gpio_isr中斷狀態(tài)寄存器來判斷具體是那位GPIO引起的中斷。對應(yīng)的中斷處理代碼如下所示:


static inline void GPIO_CommonIRQHandler(uint8_t index, uint32_t gpio_isr, uint32_t gpio_imr, BaseType_t *reschedule)
{        
    if (((gpio_imr >> mcp251xfd[index].int_gpio->pin) & 1) != 0)
    {               
        if (((gpio_isr >> mcp251xfd[index].int_gpio->pin) & 1) != 0)
        {
            /* Disable GPIO pin interrupt */            
            GPIO_PinIntEnalbe_FromISR(mcp251xfd[index].int_gpio, false);            
            /* clear the interrupt status */
            GPIO_ClearStatus(mcp251xfd[index].int_gpio);
            /* Unlock the task to process the event. */
            xSemaphoreGiveFromISR(mcp251xfd[index].xMcp251xINT_event, reschedule);
        }        
    }    
}
void GPIO5_Combined_16_31_IRQHandler(void)
{
    uint32_t gpio_isr, gpio_imr;
    BaseType_t reschedule = false;
    gpio_isr = GPIO_PortGetStatus(GPIO5);  
    gpio_imr = GPIO_PortGetIMR(GPIO5);      
    GPIO_CommonIRQHandler(2, gpio_isr, gpio_imr, &reschedule);
    GPIO_CommonIRQHandler(3, gpio_isr, gpio_imr, &reschedule);
    /* Perform a context switch to wake the higher priority task. */
    portYIELD_FROM_ISR(reschedule);      
}


  在ESM8000的Linux系統(tǒng)中,可以通過RPMsg和Crotex-M4進行通訊來獲取相關(guān)的信息,關(guān)于RPMsg的介紹可以參考《ESM7000異構(gòu)CPU實時應(yīng)用之二基于rpmsg的通訊機制》。英創(chuàng)公司已經(jīng)提供了相應(yīng)的驅(qū)動文件,加載后會生成標(biāo)準(zhǔn)的CAN設(shè)備。在驅(qū)動中會通過RPMsg和Crotex-M4進行通信以及數(shù)據(jù)的處理,但對于用戶來說是不需要關(guān)心的,直接使用標(biāo)準(zhǔn)的socketcan操作驅(qū)動生成的CAN設(shè)備就行了,用戶程序?qū)AN設(shè)備的操作,驅(qū)動都會將對應(yīng)的操作通過RPMsg發(fā)送給Crotex-M4,然后由Crotex-M4實際對硬件執(zhí)行對應(yīng)的操作,如下圖所示:


ESM8000異構(gòu)CPU實時應(yīng)用——多路CAN擴展.png

圖3:軟件原理框圖


  驅(qū)動文件在系統(tǒng)啟動完成后會自動加載,如下圖:


ESM8000異構(gòu)CPU實時應(yīng)用——多路CAN擴展.png


  通過命令ifconfig –a可以查看新生成的can0-can5這6個CAN設(shè)備,使用標(biāo)準(zhǔn)的socketcan就能夠?qū)@6個CAN設(shè)備進行操作。詳細的程序可以參考英創(chuàng)公司提供的例程test_socketcan。下面主要介紹針對這6路CAN設(shè)備進行的測試情況。


  首先測試單路CAN總線(can0)的性能,測試采用250Kbps波特率,在該波特率下,CAN總線負(fù)載最高大約為每秒2000幀,分別測試了收發(fā)不同數(shù)據(jù)量情況下主板的負(fù)載表現(xiàn),為了更直觀的體現(xiàn)出M4對負(fù)載的分擔(dān),我們在同樣條件下測試了直接使用Linux系統(tǒng)(即Cortex-A53)控制時的負(fù)載:


測試數(shù)據(jù)與擴展方式

接收

1000幀/秒

接收

2000幀/秒

發(fā)送

1000幀/秒

接收和發(fā)送

各1000幀/秒

異構(gòu)CPU控制

A53:10%

M4:8.5%

A53:18%

M4:15.8%

A53:10%

M4:5.3%

A53:18%

M4:14.8%

Linux直接控制A53:10%A53:22%A53:24%A53:38%


  因為運行Linux系統(tǒng)的Cortex-A53為4核心,所以A53總負(fù)載為400%。通常系統(tǒng)會自動均衡負(fù)載,比如20%的負(fù)載,理想狀態(tài)下會自動為4個核心各配分5%的負(fù)載。


  下面同時對比測試兩路CAN總線(can0和can1)通訊的情況:


測試數(shù)據(jù)與擴展方式

接收

1000幀/秒

接收

2000幀/秒

發(fā)送

1000幀/秒

接收和發(fā)送

各1000幀/秒

異構(gòu)CPU控制

A53:13%

M4:24.3%

A53:25%

M4:39%

A53:18%

M4:10.1%

A53:32%

M4:31.8%

Linux直接控制A53:40%A53:80%A53:46%A53:88%


  通過上面表格的對比,可以看出來通過Cortex-M4擴展的方案可以有效的降低Linux系統(tǒng)的負(fù)載,留出更多的CPU資源給用戶使用。


  下面我們采用比較極限的情況來進行測試這套擴展方案的性能,將6路CAN總線同時運行起來,測試每一路CAN總線在250Kbps波特率下每秒接收1000幀和2000幀數(shù)據(jù)時的系統(tǒng)負(fù)載,測試數(shù)據(jù)如下表:


測試數(shù)據(jù)與擴展方式

接收

1000幀/秒

接收

2000幀/秒

異構(gòu)CPU控制

A53:37.5%

M4:48%

A53:48%

M4:99%


  同時我們驗證了每一路CAN總線接收數(shù)據(jù)的準(zhǔn)確性,均沒有出現(xiàn)丟幀的情況。在250Kbps波特率下,每秒2000幀數(shù)據(jù)已經(jīng)達到CAN總線的滿載。而6路CAN總線均滿載的情況下Cortex-M4也已經(jīng)達到滿載,說明這套方案的極限性能大約為6路CAN總線每一路達到每秒2000幀的數(shù)據(jù)量。


  如果對這套方案感興趣的客戶,可以和英創(chuàng)的工程師聯(lián)系,獲取詳細的測試代碼和資料。

文章標(biāo)簽:C/C++ESM8000系列CAN
主站蜘蛛池模板: 免费性生活视频| 欧美性v视频播放| 精品在线一区| 国产精品午夜久久| 欧美亚洲综合一区| 亚洲精品久久久久福利网站| 一级特黄a视频| 伊人手机在线视频| 国产精品a v 免费视频| 91丝袜美腿高跟国产极品老师| 久久精品视频播放| 人人狠狠综合久久亚洲| 亚洲欧美日本一区| 3至13呦女毛片| 中文字幕精品一区二区日本大胸| 交在线观看网站视频| 欧美成人v视频免费看| 国产女人的一级毛片视频| 国产精品乳摇在线播放| 涩涩免费网站| 国产乱子伦一区二区三区| 欧美精品久久久亚洲| 色悠久久久久综合欧美99| 亚洲国产系列一区二区三区| 2022日本卡一卡二新区| www.国产嫩草在线观看| 人人射人人舔| 九九精品视频在线免费观看| 日本ab在线| 日本片网址| 日本一区二区三区有限公司| 日韩黄色一级| 国产在线观看91| 国产精品老女人精品视| 香蕉爱爱视频| 特级aaa毛片| 特级黄毛片| 特级毛片aaaa级毛片免费| 黄色小网站在线观看| 黄色小视频在线观看| 特黄特黄|