數據采集是工業控制系統中的重要環節,較高的采樣率對數據處理環節提出了高的要求。當數據量不大,采樣率不高時,使用CPU進行傳輸處理是非常簡單方便的;當遇到大的數據容量,高的采樣率時,如果仍然使用CPU處理數據傳輸,將會帶來巨大的CPU負載,難以滿足高速大容量數據采集的要求。通常,在數據容量比較大,采樣率較高的場合,使用DMA技術將數據直接傳輸到內存,不經過CPU管理,是比較通用的方案。
英創公司針對英創主板ESM335x已有的硬件資源,在linux-4.1.6操作系統環境下,提出了一種基于SPI接口的大容量通用數據采集方案,其物理連接如圖1所示。這里用另一塊ESM335x作為主設備,模擬數采裝置,實際使用可以是任何支持SPI主模式的設備。使用時,連接SPI主從設備的公共地后,只需要連接ESM335x主板上對應SPI_SCLK、SPI_MOSI、SPI_CS0N的 3個管腳,見表1。
圖1 SPI接口大容量通用數據采集連接圖
表1 ESM335x工控主板SPI接口數采方案管腳說明
信號名稱 | CN2(管腳標號) | 說明 |
GPIO29/SPI_MOSI | F14 | SPI數據信號,主設備輸出,從設備輸入 |
GPIO30/SPI_SCLK | F15 | SPI時鐘信號,主設備輸出,從設備輸入 |
GPIO31/SPI_CS0N | F16 | SPI片選信號,低有效,主設備輸出,從設備輸入 |
該方案使用SPI作為傳輸協議,采用雙buffer的DMA技術,能夠達到1Msps(一個采樣點數據位寬8-16位)。ESM335x工作在SPI從模式,能夠接收的最高時鐘為16MHz(最低不限制),即最高數據傳輸率為2MBytes/s。當DMA緩存buffer1裝滿數據后,會觸發DMA中斷,通知CPU將數據讀出DMA緩存,然后繼續將新傳輸進入的數據存儲在buffer2;buffer2裝滿數據后,也產生DMA中斷通知CPU取出數據,然后將新數據存儲到buffer1,如此循環,如圖2所示。當主機傳輸完成不再提供時鐘信號后,ESM335x(從設備)通過定時器超時讀出DMA緩存中剩余的數據。
圖2 DMA雙buffer示意圖
圖3 使用DMA技術的SPI數據采集CPU負載
如圖3所示,使用此方案后,CPU負載率很低,此例中不到1%。用戶使用時,需要按如下步驟進行操作:
1、加載SPI從模式驅動。在linux操作系統中,使用insmod spi-slave.ko命令,會創建設備節點/dev/spi-slave。
2、應用程序打開設備:
fd = open ( "/dev/spi-slave", O_RDWR, S_IRUSR | S_IWUSR );
3、設定傳輸參數:
//configure info transfer to driver
structspi_slave_transfer
{
unsignedintclk; //驅動根據不同clk,設定不同長度的dma buffer,滿足填滿一個buffer的時間不超過10ms(雙buffer)
unsignedintmode; //SPI mode: 0,1,2,3
unsignedintbits_per_word; //每個采樣點的位數
};
structspi_slave_transfer transfer;
transfer.clk =16000000; //16M clk ---16KB every buffer
transfer.mode = 1;
transfer.bits_per_word = 16;
4、傳入參數至內核,啟動傳輸:
if(ioctl ( fd, SPI_SLAVE_START, &transfer )<0)
{
printf ( "START WRONG!!!!!!!!!!!!!!!!\n" );
exit ( 1 );
}
此時,主板上的SPI已經進入從模式,有數據傳入時,將存入DMA緩存,存滿一個buffer就通知CPU讀出數據到CPU維護的一個內存區域(256個kfifo組成鏈表,kfifo大小與buffer相同,使用完后會覆蓋第一個kfifo)。同時,當一次傳輸完成后,通過定時器讀出剩余在DMA buffer中的數據。應用程序應及時使用read函數從CPU維護的區域讀出數據,以免CPU維護太多內存。
count_in_byte = 0;
read_count = 0;
while(1)
{
FD_ZERO(&fdRead);
FD_SET(fd,&fdRead);
aTime.tv_sec = 2;
aTime.tv_usec = 0;
ret = select ( fd+1, &fdRead, NULL, NULL, &aTime );
if( ret<0 )
printf( "select, something wrong!\n " );
if( ret>0 )
{
if( FD_ISSET(fd, &fdRead) )
{
memset(read_buf,0,4096*4);
read_count = read(fd, read_buf, 4096*4);
if( read_count<0 )
{
printf ( "READ WRONG!!!!!!!!!!!!!!!!\n" );
exit ( 1 );
}
if(read_count){ //0 --- end-of-file not printf
count_in_byte += read_count;
printf("\nread_count = %d\ncount_in_byte = %d\n", read_count, count_in_byte);
}
//process data, here just print to console
if(read_count < 20){
for( i=0; i
{
printf ( "%02x ", read_buf[i] );
if(i%10 == 9)
printf ( "\n" );
}
printf("\n");
}
}
}
printf ( "remaining time %u.%u!\n",aTime.tv_sec, aTime.tv_usec );
}
5、完成傳輸,關閉SPI。
if(ioctl ( fd, SPI_SLAVE_STOP, &transfer )<0)
{
printf ( "STOP WRONG!!!!!!!!!!!!!!!!\n" );
exit ( 1 );
}
6、關閉設備文件
close ( fd );
當主設備前后兩次傳輸的參數不一樣時,從設備需要分兩次調用open/close函數,按以上步驟進行操作。如有用戶對這個方案感興趣,可以聯系我們,我們將提供驅動文件和完整的應用程序示例。
-
Linux
+關注
關注
87文章
11479瀏覽量
213026 -
嵌入式主板
+關注
關注
7文章
6097瀏覽量
36195
發布評論請先 登錄
電機數據采集網關具有哪些特點?

深控信息技術公司:不需要點表的工業網關數據采集方案

數據網關與數據采集器的區別
PLC數據采集解決方案

中科創達榮獲2024年軟件和信息技術服務優秀企業
水利數據采集遠程監控平臺是什么
Modbus數據采集物聯網平臺可以采集什么設備?有什么功能?

數據采集網關與工業物聯網平臺一體化解決方案

NI數據采集板卡如何連接使用?
信捷PLC數據采集監控系統解決方案

評論