問題的提出
數(shù)控機床最重要的工作是自動加工 在開放式數(shù)控系統(tǒng)中 執(zhí)行自動加工功能時 數(shù)據(jù)處理的流程一般如圖 1一個編制好的加工文件 首先經(jīng)過 PC 用戶態(tài)程序的處理 完成所謂粗插補的工作 然后控制系統(tǒng)再把粗插補的結(jié)果通過 CNC 內(nèi)核 俗稱驅(qū)動 傳遞給運動控制卡 讓控制卡完成精插補的工作 實際中 在 CNC 內(nèi)核層會完成更多的 實時性相對高的工作 比如端口掃描 為了討論方便 忽略這些內(nèi)容
所謂的粗插補 是指對文件的一系列操作 包括對文件描述的刀路的語義理解 速度規(guī)劃軌跡處理 插補等等 人們之所以選擇在 PC 上完成粗插補 是看中了計算機強大的運算能力 但一般人們不會采用在 CNC 內(nèi)核層完成粗插補的工作 有如下原因 1 Windows 系統(tǒng)在調(diào)度內(nèi)核模式的線程時不會自動保存和恢復(fù)浮點寄存器中的內(nèi)容 如要做需要手工完成 2 CNC 內(nèi)核中的程序不方便調(diào)試 俗稱驅(qū)動程序不方便調(diào)試 3 為了保證控制卡處理數(shù)據(jù)的完整性 一般的控制系統(tǒng)都會設(shè)計成驅(qū)動程序由控制卡發(fā)出的中斷來驅(qū)動運行 在中斷服務(wù)程序中一般不宜做特別復(fù)雜的事情 有時 對于復(fù)雜的插補算法和刀路情形 可能需要較長的計算時間 這在性能上是不允許的 因此 人們一般把粗插補工作放在應(yīng)用程序?qū)?/span> 然后把插補結(jié)果傳遞給驅(qū)動程序

這里有一個問題 當(dāng)用戶應(yīng)用程序完成粗插補后 插補結(jié)果的數(shù)據(jù)量一般都是巨大的 而用戶程序和內(nèi)核程序之間的數(shù)據(jù)傳遞一般情況下是不方便的 這就要求人們找到一種高效的方法來完成數(shù)據(jù)交換
從 Intel80386 開始 出于安全性和穩(wěn)定性的考慮 該系列的 CPU 可以運行于 ring0~ring3 從高到低四個不同的權(quán)限級 對數(shù)據(jù)也提供相應(yīng)的四個保護(hù)級別 運行于較低級別的代碼不能隨意調(diào)用高級別的代碼和訪問較高級別的數(shù)據(jù) 而且也只有運行在 ring0 層的代碼可以直接對物理硬件進(jìn)行訪問 由于 WindowsNT 是一個支持多平臺的操作系統(tǒng) 為了與其他平臺兼容 它只利用了 CPU 的兩個運行級別 一個被稱為內(nèi)核模式 對應(yīng) 80 86 的 ring0 層 是操作系統(tǒng)的核心部分 設(shè)備驅(qū)動程序就是運行在該模式下 另一個被稱為用戶模式 對應(yīng) 80 86 的 ring3 層 操作系統(tǒng)的用戶接口部分 就是我們通常所說的 Win32 API 以及所有的用戶應(yīng)用程序都運行在該級別
運行在這兩個模式下的程序 一般都是通過專門的 API 應(yīng)用程序接口 函數(shù) DeviceIOControl 進(jìn)行數(shù)據(jù)交換的 用戶模式程序通過該函數(shù)向內(nèi)核程序申請服務(wù) 同時把需要傳遞的數(shù)據(jù)一并告知 內(nèi)核程序在接收到該服務(wù)申請信息以后 將傳遞的數(shù)據(jù)拷貝到內(nèi)核的緩沖區(qū)中 這就造成在傳遞數(shù)據(jù)之前和傳遞到內(nèi)核程序以后 都需要進(jìn)行數(shù)據(jù)的拷貝 并且 DeviceIOControl 函數(shù)在執(zhí)行時也有較大的開銷 因此造成用這種方法進(jìn)行數(shù)據(jù)傳遞效率不高 為了解決上述方案的不足 本文給出另一種使用內(nèi)存映射的方式來完成數(shù)據(jù)交換的方法
2.內(nèi)存映射方式傳遞數(shù)據(jù)
我們知道 32 位 Windows 操作系統(tǒng)會為每個應(yīng)用程序分配 4G 的內(nèi)存地址空間 這些在邏輯上連續(xù)的內(nèi)存地址所對應(yīng)的物理地址其實并不一定連續(xù) 既有可能把不相鄰的存儲空間映射成相鄰的 也可能把相鄰的物理塊映射成不相鄰的邏輯地址 同時 它還具有把同一塊物理存儲設(shè)備分別映射到不同的地址的能力 本方案使用的就是操作系統(tǒng)的后一種能力
方案思路 將某一塊內(nèi)存空間 分別映射到內(nèi)核地址空間和用戶模式地址空間 這樣 兩種模式下的程序就可以直接對該內(nèi)存區(qū)域進(jìn)行讀寫 從而達(dá)到數(shù)據(jù)交換的目的
圖 2 中 物理內(nèi)存 C 被分別映射成用戶地址空間的 A 和內(nèi)核地址空間的 B內(nèi)核模式程序從 B 處開始讀取數(shù)據(jù) 用戶程序從 A 處開始寫入數(shù)據(jù)

Windows 提供了相應(yīng)的 API 函數(shù)和數(shù)據(jù)結(jié)構(gòu) 整個過程敘述如下
首先申請一個 MDL 內(nèi)存描述表 memory descriptor list 用來映射我們需要大小的內(nèi)存地址 然后從已獲得的 MDL 分配一塊物理內(nèi)存 獲得其起始地址 最后把這塊內(nèi)存地址映射到用戶地址空間中 上述過程依次使用 IoAllocateMdl MmBuildMdlForNonPagedPool 和 MmMapLockedPages 三個 API 函數(shù)
下面是一個例子 假設(shè) CNccmdFifo 為描述緩沖區(qū)的數(shù)據(jù)結(jié)構(gòu)
CNccmdFifo NccmdFifo;
PMDL pMdlNccmdFifo = IoAllocateMdl(&NccmdFifo, sizeof(NccmdFifo), false, false, NULL);
MmBuildMdlForNonPagedPool(pMdlNccmdFifo);
void* pNccmdFifoUserSpace = (CNccmdFifo*)MmMapLockedPages(pMdlNccmdFifo, UserMode);
現(xiàn)在 pNccmdFifoUserSpace 即為用戶在用戶模式中也能訪問的地址 從這以后 用戶可以直接在用戶模式中向該地址寫入數(shù)據(jù) 也可以直接從內(nèi)核模式讀取該緩沖區(qū)中的數(shù)據(jù)


3.效率比較
作者所從事的工作是開發(fā)開放式數(shù)控系統(tǒng) 為了對比如上兩種方案的效率 在公司一款已經(jīng)成熟的產(chǎn)品上做測試 結(jié)果表明 使用內(nèi)存直接映射的方式 在效率上有較大的優(yōu)勢 表 1 是一些測試數(shù)據(jù)
表 1 所測試的文件約 500 行 從數(shù)據(jù)可以看出 使用緩沖區(qū)映射方式 所花費的時間只有使用普通方式 用 DeviceIOControl 交換 的 78.85% 效率明顯提高
表 2 是更多的實驗數(shù)據(jù)
從表 2 能看出 內(nèi)存映射方式有較大優(yōu)勢
4.優(yōu)缺點和一些問題
因為對讀寫信息存儲時為了避免因為線程的調(diào)度而產(chǎn)生問題 需要讓記錄在一個指令中完成 這意味著從理論上講 該映射空間不能太大不能大于 2^32 4G 實際上這是遠(yuǎn)遠(yuǎn)夠用的
內(nèi)存映射要求使用物理內(nèi)存進(jìn)行映射 不能將這些內(nèi)存用作交換區(qū) 減少了交換區(qū)內(nèi)存的使用量實現(xiàn)比較復(fù)雜 要求對 Windows 操作系統(tǒng)有較深的了解
因為對緩沖區(qū)的訪問是在不同的線程中進(jìn)行的 一個讀 另一個可能會同時寫 需要處理訪問沖突的情況
在對比兩種數(shù)據(jù)交換方式的效率時 筆者發(fā)現(xiàn) 如果遇到一些極端的加工文件 它們在粗插補階段需要花費較多的時間的話整體的效率差別就會比較小 這是本方案在實際應(yīng)用時需要考慮到的一點
本文由 伯特利技術(shù)文章 整理發(fā)表,文章來自網(wǎng)絡(luò)僅參考學(xué)習(xí),本站不承擔(dān)任何法律責(zé)任。
伯特利數(shù)控一直以盡心、盡力、盡意的態(tài)度把握每一臺 加工中心、鉆攻中心的質(zhì)量
相關(guān)文章可查閱本站:技術(shù)文章 或本文下方 標(biāo)簽 分類
相關(guān)產(chǎn)品可查閱本站:產(chǎn)品中心
2014-07
問題的提出 數(shù)控機床最重要的工作是自動加工 在開放式數(shù)控系統(tǒng)中 執(zhí)行自動加工功能時 數(shù)據(jù)處理的流程一般如圖 1一個編制好的加工文件 首先經(jīng)過 PC 用戶態(tài)程序的處理 完成所謂粗插補的工作 然后控制系統(tǒng)再把粗插補的結(jié)果通過 CNC 內(nèi)核 俗稱驅(qū)動 傳遞給運動控制卡 讓控制卡完成精插… [了解更多]