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

ESM7000異構CPU實時應用之三
8路并行數采應用程序

 2021-5-14     作者:黃志超         

  英創公司推出了ESM7000異構CPU的實時應用,由高性能的Cortex-A7雙核完成人機交互、數據處理、通訊管理等復雜運算,而對于高速的數據采集、中斷事件響應等實時任務交由i.MX7D的Cotex-M4完成,具體的介紹可以參考文章《ESM7000異構CPU架構實時應用簡介》。基于ESM7000的異構CPU平臺,英創公司實現了多通道的高速數采方案,該方案最高支持100kSPS采樣率的AD轉換。


  關于M4端的AD操作的實現可以參考文章《ESM7000異構CPU實時應用之一 8通道并行100K 16bit AD采集》,本文主要介紹Linux系統中需要做的操作以及程序的實現,文章分為三個部分,第一部分是介紹如何將編譯好的M4程序燒寫到主板中,并設置自動啟動。第二部分是介紹如何加載英創公司提供的RPMsg驅動,RPMsg驅動主要實現了ESM7000中Crotex-A7核心與M4核心之間的通訊。第三部分是介紹Linux系統端User app的實現和性能的測試結果,其中User app正是通過英創公司定義的RPMsg通訊協議來實現的,關于RPMsg和通訊協議具體的介紹可以參考文章《ESM7000異構CPU實時應用之二 基于rpmsg的通訊機制》


  本文測試硬件平臺基于ESM2001工控機,感興趣的客戶可參考這里:EMX2000系列工控機


M4應用程序的燒寫


  首先將編譯好的M4應用程序(這里以英創公司提供的例程emx2001.bin為例)拷貝到主板中的,例如/mnt/mmc中,然后就可以通過英創公司提供的工具flash_opt將程序燒寫到系統中,并設置好隨系統自動啟動。flash_opt工具已經集成在了主板中,可以直接在命令執行。


  M4的應用程序可以選擇三個區域燒寫,分別是TCM、OCRAM 或 DDR 中運行,在TCM中的運行速度最快,但是代碼空間最小,OCRAM中運行速度會慢一些,代碼空間相對更大,而DDR中代碼運行速度最慢,但是代碼空間最大。各個區域提供的程序代碼空間具體數據如下表所示:


Configure文件名CODE Size
TCMemx2001_tcm.bin32K
OCRAMemx2001_ocram.bin128K
DDRemx2001_ddr.bin1MB


  在燒寫前需要根據不同的燒寫區域對程序重命名,如果需要燒寫到TCM 中,則程序需要命名為 emx2001_tcm.bin,如果燒寫到 OCRAM 中,則命名為 emx2001_ocram.bin,如果是燒寫到 DDR,則為 emx2001_ddr.bin。重命名只是為了滿足 flash_opt 對命令格式的要求,程序在編譯時必須根據運行的位置選擇對應的 ESM7000_M4_*.ld 文件。


  比如我們需要將emx2001.bin放在TCM中,則將程序命名為emx2001_tcm.bin,然后輸入命令#>flash_opt m4 /mnt/mmc/ emx2001_tcm.bin,如下圖:


ESM7000異構CPU實時應用之三 8路并行數采應用程序.png


  完成之后,每次主板重啟就都會自動啟動燒寫進去的M4應用程序。關于程序放在不同區域的具體的說明和對比,可以參考《ESM7000 Cortex-M4技術開發參考手冊》,這里不再贅述。


RPMsg驅動的加載


  RPMsg的驅動也同樣集成在了系統中,可以直接通過命令加載,只需要一條命令#>modprobe emx_rpmsg_tty,加載后驅動會生成響應的設備節點/dev/ttyEMx同時會打印出關于AD的信息,如下圖:


ESM7000異構CPU實時應用之三 8路并行數采應用程序.png


  從驅動打印的信息可以看到AD的詳細參數信息。驅動加載完成后,就可以運行User app來進行采集了。


User app的實現和測試


  通過《ESM7000異構CPU實時應用之二 基于rpmsg的通訊機制》的介紹,我們已經了解了英創公司設計的基于RPMsg的通訊協議,本文介紹的User app正是使用這一套通訊協議來實現的。


  驅動emx_rpmsg_tty.ko會虛擬出串口設備,所以通信部分的代碼都是使用的串口的標準操作函數來實現的。首先是向M4發送消息,設置好AD的采樣率,然后啟動AD,通過write函數就可以向M4發送數據,英創公司已經封裝好了函數供客戶參考:


int EM_Adc::setup_adc( int freq )  
{  
    int ret;  
    struct emx_rpmsg_t  *msg_t;  
  
    //打開虛擬串口ttyEMx,并建立好接收線程  
    ret = OpenPort();  
    if( ret<0 )  
    {  
        printf( "ttyEMx open fail\n");  
        return -1;  
    }  
  
    //發送復位指令  
    ret = Send_cmd(CMD_CODE_RESET, NULL, 0);  
    if( ret<0 )  
    {  
        printf( "send failed\n");  
    }  
      
    //發送設置指令,設置AD的采樣率  
    ret = Send_cmd(CMD_CODE_SETUP, (void *)&freq, sizeof(freq));  
    if( ret<0 )  
    {  
        printf( "send failed\n");  
    }  
  
    //發送啟動指令,開始采集  
    ret = Send_cmd(CMD_CODE_RUN, NULL, 0);  
    if( ret<0 )  
    {  
        printf( "send failed\n");  
    }  
    Dflags = 1;  
  
    return 0;  
}

 

  啟動了AD之后,M4就會開始進行數據采集,因為多通過告訴采集的數據量十分龐大,所以采用了共享內存的方式來發送數據。例程定義了兩塊32KB大小的共享區域,當M4采集的數據量達到16K之后,就會將數據寫入共享內存中,然后根據通訊協議發送消息通知User app去讀取。我們還是通過一個線程來專門接收采集數據,具體代碼如下:


int EM_Adc::PackagePro( char* Buf, int len )  
{  
    int         i1, num;  
    int         buf_len;  
    char        status_buf[100];  
  
    memcpy(&msg, (char *)Buf, sizeof(struct emx_rpmsg_t));  
    if(msg.cmd == CMD_CODE_DATA) {  
        Mlen = msg.len;  
        //判斷數據存放在哪一塊共享區域,然后將數據拷貝出來  
        if(msg.flags == 0) {  
            memcpy(MemBuf, (void *)base0, msg.len);  
        }  
        else {  
            memcpy(MemBuf, (void *)base1, msg.len);  
        }  
        //處理數據,這里是將每個通道的數據保存成文件  
        save_data(MemBuf, Mlen);  
    }  
  
    return 0;  
}

 

  例程中數據的處理主要是把每個通道的數據分離出來,分別保存在不同的文件中。為了保證寫文件的速度,一開始是寫在內存中,當文件大小超過1MB,就關閉AD,并且將文件拷貝到/mnt/mmc中儲存,處理數據的代碼如下:


int EM_Adc::save_data(int16_t *data, int len)  
{  
    FILE    *fp;  
    char filename[20];  
    int     i1, i2, ret;  
  
    for(i1=0; i1<8; i1++) {  
        sprintf( filename, "/tmp/ch%d", i1);  
        fp = fopen(filename, "ab+");  
        if( fp==NULL )  
        {  
                printf("open %s fail!\n", filename);  
                ret = -1;  
                return ret;  
        }  
  
        //將每個通道的數據分離出來,分別保存在文件中  
        for(i2=0; i2<(len/16); i2++) {  
            memcpy(&CHxBuf[i2], ((int16_t *)data + i1 + i2*8), sizeof(int16_t));  
        }  
        fwrite( CHxBuf, (i2-1)*sizeof(int16_t), 1, fp );  
  
        //如果保存數據已經大于1M,則關閉AD,將文件移至/mnt/mmc目錄保存,然后退出程序  
        if(i1 == 7) {  
            fseek(fp, 0, SEEK_END);  
            long length  = ftell(fp);  
            if(length > 1024*1024) {  
                fclose(fp);  
                system("cp /tmp/ch* /mnt/mmc");  
                stop_adc();  
                return 0;  
            }  
        }  
        fclose(fp);  
    }  
    return 0;  
}

 

  在實際測試的時候,我們將兩路正弦波信號分別接入通道1和通道2,當采集完成后使用波形繪制工具讀取保存的文件,效果如下:


ESM7000異構CPU實時應用之三 8路并行數采應用程序.png


  從圖中可以看到采集波形的效果,在實際應用中,客戶可以根據需求自行修改對于數據處理的方式。


  M4端應用程序采用的方式是每采集16000字節發送一次數據,為了驗證這套方案能夠滿足應用需求,我們對M4通過RPMsg發出消息,到Linux系統中User app讀取到共享內存數據的時間做了詳細的測試,響應時間如下表:


采樣率平均時間(us)最長時間(us)
5ksps298495
10ksps300489
50ksps287488
100ksps287469


  按照100ksps的采樣率計算,M4端每10us會采集一次,每個通道單次采集數據大小為2Byte,8個通道就為16Byte。所以在100Ksps采樣率的情況下,每10ms就會發送一次數據。按照這個時間間隔來看,ESM7000異構CPU平臺完全可以滿足需求。


  對這套方案感興趣的客戶可以和英創公司的工程師聯系,索取相關例程的代碼。

主站蜘蛛池模板: 精品一区二区三区视频| zoofilia杂交videos新一| 女人被狂躁的视频免费免费看| 国产视频在线免费观看| 国产亚洲高清在线精品99| 亚洲欧美性视频| 日韩欧美亚洲国产一区二区三区| 色免费在线观看| 欧洲一级鲁丝片免费| 黄色片网站在线免费观看| 国产younv交在线视频| 久久国产大片| 亚洲天堂色图| 久久视频精品36线视频在线观看 | 亚洲精品第一区二区三区| 日本老年人精品久久中文字幕| 在线观看二区三区午夜| 国产伦精品一区二区三区免费| 国产成人精品2021欧美日韩| 久久青青视频| 日本欧美韩国一区二区三区| www噜噜偷拍在线视频| 久久国产精品2020免费m3u8| 成人一区二区免费中文字幕| 国产伦一区二区三区高清| 蕾丝视频在线看片国产| 久久久久久久久久免免费精品| 亚洲欧美色一区二区三区| 最全精品自拍视频在线| 日本久色| 日本欧美中文字幕| 日韩在线视频免费| 成人国产第一区在线观看| 免费看av的网址| 国产亚洲3p一区二区三区| 黄色伊人网| 黑人操日本人视频| 清纯唯美亚洲综合五月天| 国产精品久久久久亚洲| 妞干在线| 亚洲 国产精品 日韩|