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

ESM8000異構CPU實時應用——6路CAN-FD的實現

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

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


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


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


ESM8000異構CPU實時應用——多路CAN擴展.png

圖1:6x CAN擴展驅動原理框圖


sbc880+esm8000+eta706.png

圖2:  6x CAN硬件測試環境


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


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


#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進行優化 */
            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內再次被分為高低兩組,每組對應16位IO,共享一個中斷源。以擴展的CAN2和CAN3為例,它們的中斷輸出分別連接到ESM8000的GPIO2、GPIO3,分別對應到i.MX8MM的GPIO_PORT5_Pin26和GPIO_PORT5_Pin27,它們使用同一個GPIO中斷源GPIO5_Combined_16_31_IRQn。當GPIO中斷產生后,需要通過讀取gpio_isr中斷狀態寄存器來判斷具體是那位GPIO引起的中斷。對應的中斷處理代碼如下所示:


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系統中,可以通過RPMsg和Crotex-M4進行通訊來獲取相關的信息,關于RPMsg的介紹可以參考《ESM7000異構CPU實時應用之二基于rpmsg的通訊機制》。英創公司已經提供了相應的驅動文件,加載后會生成標準的CAN設備。在驅動中會通過RPMsg和Crotex-M4進行通信以及數據的處理,但對于用戶來說是不需要關心的,直接使用標準的socketcan操作驅動生成的CAN設備就行了,用戶程序對CAN設備的操作,驅動都會將對應的操作通過RPMsg發送給Crotex-M4,然后由Crotex-M4實際對硬件執行對應的操作,如下圖所示:


ESM8000異構CPU實時應用——多路CAN擴展.png

圖3:軟件原理框圖


  驅動文件在系統啟動完成后會自動加載,如下圖:


ESM8000異構CPU實時應用——多路CAN擴展.png


  通過命令ifconfig –a可以查看新生成的can0-can5這6個CAN設備,使用標準的socketcan就能夠對這6個CAN設備進行操作。詳細的程序可以參考英創公司提供的例程test_socketcan。下面主要介紹針對這6路CAN設備進行的測試情況。


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


測試數據與擴展方式

接收

1000幀/秒

接收

2000幀/秒

發送

1000幀/秒

接收和發送

各1000幀/秒

異構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系統的Cortex-A53為4核心,所以A53總負載為400%。通常系統會自動均衡負載,比如20%的負載,理想狀態下會自動為4個核心各配分5%的負載。


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


測試數據與擴展方式

接收

1000幀/秒

接收

2000幀/秒

發送

1000幀/秒

接收和發送

各1000幀/秒

異構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系統的負載,留出更多的CPU資源給用戶使用。


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


測試數據與擴展方式

接收

1000幀/秒

接收

2000幀/秒

異構CPU控制

A53:37.5%

M4:48%

A53:48%

M4:99%


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


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

文章標簽:C/C++ESM8000系列CAN
主站蜘蛛池模板: 污网站网址| 中国帅小伙肌肉gaysextube| 国产高清视频在线观看不卡v| 国产精品成人一区二区1| 首页国产| 在线观看欧美日韩| 久久久久久久九九九九| 毛片三级| 成人毛片18女人毛片免费视频未| 国产成版人视频网站免费下| 啪啪三级| 99久久免费国产精品| 久久国产香蕉视频| 色噜噜狠狠一区二区三区| 在线不欧美| a级黄色大片在线观看视频男男| 日韩久久久精品中文字幕| 亚洲精品一区二区四季| 欧美+日本+国产+在线观看| 国产在线主播| 国产精品系列在线观看| 新久草视频| 大片免费观看入口| 国拍在线精品视频免费观看 | 在线看成品视频入口免| 欧美精品一区二区三区四区| 国产视频第二页| 国产精品嫩模在线播放| 黄色片一级免费| 麻豆国产在线观看一区二区| 99久久精品自在自看国产| 国产高清三级| 国产精品一区不卡| 国产一区二区三区四卡| 久久精品女人毛片国产| 女视频www女中国| 欧美国产精品| 免费性| 欧洲男女下面进出的视频| 日韩欧美亚洲另类| 欧美一区精品二区三区|