《VxWorks7編程指南》筆記(七)——I/O系統:基礎I/O

目錄

1.文件描述符

2.內核中的文件描述符表

3.RTP中的文件描述符表

4.打開和關閉函數

5.創建和刪除函數

6.讀和寫函數

7.文件截斷函數

8.使用select()等待多個文件描述符

9.在內核中使用select()

10.在RTP中使用select()

11.POSIX文件系統函數


在VxWorks中,基礎I/O是最底層的I/O。基礎I/O的接口同標準C庫中的I/O原語是源碼級兼容的。最基礎的I/O調用有7個,如下圖所示。

 

1.文件描述符

在基礎I/O層級,文件通過文件描述符引用。一個文件描述符是一個由open()或creat()函數返回的整數。其他I/O調用使用一個文件描述符作爲參數,以操作某個特定的文件。

文件描述符不是全局的。內核與RTP均有其獨有的文件描述符集合。內核中的任務或某個任務中的子任務將共享文件描述符。例如:

  • 如果任務A和任務B運行在進程foo中,然後它們均使用write()函數對文件描述符7進行操作,那麼它們將對同一個文件(設備)進行寫操作。
  • 如果一個進程bar與進程foo獨立運行(bar不是foo的孩子),然後進程bar的任務X和任務Y使用文件描述符7進行write()操作,那麼這個文件將與進程foo的任務A和任務B所操作的文件描述符7指定的文件不同。
  • 如果進程foobar由進程foo創建,然後進程foobar的任務M和任務B分別調用write()對文件描述符7進行操作,那麼它們所操作的文件將同進程foo中的任務A和任務B按照文件描述符7操作的文件相同。然而,如果任務將該文件關閉了,後續再次打開文件描述符7時,該文件描述符將指向另外的文件。

當文件打開時,將分配並返回一個文件描述符;當文件關閉時,文件描述符將被釋放。

 

2.內核中的文件描述符表

內核中可用的文件描述符數量由宏NUM_FILES定義。這個數量也定義了文件描述符表的大小,該表控制了同時可以使用多少個文件描述符。默認大小是50,但是可以根據系統需要進行修改。

爲了避免用盡文件描述符,導致創建文件時出現錯誤,應用程序應該在不再使用一個文件描述符時將其關閉。

內核的文件描述符表大小也可以通過編程的方式進行修改。rtpIoTablesizeGet()函數用於獲取文件描述符表的大小,rtpIoTableSizeSet()函數用於對其進行修改。注意:這些函數在內核與RTP中均可使用(I/O系統將內核看做一類特殊的進程)。

 

3.RTP中的文件描述符表

在RTP中的文件描述符表的大小,定義了一個進程中可以同時打開的最大文件數量。該最大值是從其創建環境繼承而來的。如果該進程由一個內核任務創建,那麼新進程將繼承內核任務的文件描述符表的最大值。

 

4.打開和關閉函數

在對一個設備執行I/O操作之前,必須使用open()或creat()函數打開一個文件描述符。open()函數所需的參數爲:文件名、訪問類型、文件權限。語法如下:

fd=open("name",flags,mode);

對於open()函數,參數mode是可選的,如果對文件權限並不關心,就可以將mode設置爲0。

對於用戶級與內核級調用,open()函數的flags參數可以指定爲如下值:

 

在使用文件的訪問與模式參數調用open()函數時,需要注意如下情況:

  • 通常,僅能使用open()打開一個已經存在的設備和文件。然而,對於NFS、網絡、dosFs和HRFS設備,可以通過帶O_CREAT的標記使用open()函數。
  • 可以使用open()函數打開HRFS目錄,但是僅能使用O_RDONLY標誌。
  • 對於dosFs和NFS設備,可以使用O_CREAT標記和FSTAT_DIR模式創建一個子目錄。dosFs將忽略其他mode參數。
  • 對於HRFS設備,不能使用O_CREAT標記和FSTAT_DIR模式選項創建一個子目錄。HRFS將忽略mode選項,僅創建一個普通文件。
  • netDrv默認文件系統不支持F_STAT_DIR mode選項或O_CREAT標記。
  • 對於NFS設備,open()的第三個參數通常用於指定文件模式。
  • 儘管HRFS支持爲一個文件設定權限模式,但是在VxWorks中並不這麼使用。
  • 文件可以使用O_SYNC標記打開,表明每次寫操作都將立即把內容寫到底層介質中。當前dosFs文件系統支持這個標記,可以用於同步FAT與目錄條目。
  • O_SYNC標記對HRFS文件系統不起作用,因爲HRFS本身總是進行同步。HRFS總是更新文件,就好像O_SYNC標記被設置了一樣。

注意:驅動或文件系統可能不會完全遵守flag值或mode值。如果驅動允許,一個按照O_RDONLY模式打開的文件實際上可能是可寫的。

 

5.創建和刪除函數

面向文件的設備,除了能夠打開已經存在的文件,還要能夠創建和刪除文件。

面向文件的設備可以使用creat()函數創建一個文件,並返回其文件描述符。creat()的參數與open()的參數類似,區別是creat()傳入的文件名指向一個新文件,而open()傳入的文件名指向的是一個已經存在的文件。

注意,在HRFS文件系統中,creat()函數是POSIX兼容的,其第二個參數用於指定文件權限;文件將按照O_RDWR模式打開。

對於dosFs,creat()函數不是POSIX兼容的,第二個參數用於指定打開模式標記。

remove()函數將刪除文件系統中的一個命名文件。再刪除文件之前,需要先關閉文件。

對於非文件系統設備,creat()函數與open()函數等效。remove()函數將不起作用。

 

6.讀和寫函數

當通過open()或creat()函數得到一個文件描述符之後,可以調用read()或write()函數向文件中讀取或寫入數據。read()函數的參數包括:文件描述符、存放待讀取數據的緩衝區地址,待讀取數據的最大長度。

read()函數等待從指定文件讀取數據,並返回實際讀取到的字節數。對於一個文件系統設備,如果讀取到的字節數比指定的字節數少,那麼後續的read()調用將返回0,表明已經讀取到文件的末尾。對於非文件系統設備,讀取到的字節數可以比指定的大小要少,就算還有可讀的數據也是允許的。後續的read()調用可能返回0.對於串口設備和TCP套接字,爲了讀取指定大小的數據,可能需要重複調用read()函數。讀取失敗時將返回ERROR(-1)。

write()函數的參數爲:文件描述符,待寫入數據的緩衝區地址,待寫數據長度。語法如下:

actualBytes=write(fd,&buffer,nBytes);

write()函數保證在返回到調用函數之前,至少會將所有指定的數據緩存到輸出緩衝區中,所以有可能數據還沒有真正的寫到設備中(因驅動而異)。write()函數返回寫入的字節數大小;如果返回的大小不等於需要寫入的大小,將返回錯誤。

RTP的read()和write()函數時POSIX兼容的。

 

7.文件截斷函數

有時需要丟棄文件中的一部分數據。當打開一個文件後,可以使用ftruncate()函數將文件截斷爲一個指定的大小。其參數爲:文件描述符、期望的文件字節長度。語法如下:

status=ftruncate(fd,length);

如果截斷成功,將返回OK。

如果一個文件描述符所指向的設備是不可截斷的,那麼ftruncate()將返回ERROR,並將errno設置爲EINVAL。

如果指定大小比文件實際的大小還要大,其結果將取決於具體的文件系統。對於dosFs和HRFS,文件的大小將擴展到指定的大小然而,對於其他文件系統,ftruncate()將返回ERROR,並將errno設置爲EINVAL。

ftruncate()函數時POSIX1003.1b標準的一部分。HRFS將完全支持,dosFs的實現則是部分兼容:創建和修改的次數不會改變。

對於HRFS,截斷不會修改seek的位置,但是在dosFs中,seek的位置將被設置爲文件末尾。

 

8.使用select()等待多個文件描述符

VxWorks的select()函數提供了一種等待多個文件描述的方法(允許任務等待多個設備可用)。VxWorks的select()同UNIX和Windows是兼容的。

內核的selectLib庫包括了select()和相關的函數,需要使用INCLUDE_SELECT組件。

對於RTP的select()函數,需要配置INCLUDE_IO_BASIC組件。

任務級的select()函數,不僅允許任務可以同時等待多個設備I/O,還允許任務制定等待多長時間。一個典型的例子就是客戶端-服務器模型,服務器端同時等待多個文件描述符,以同時爲本地和遠端的客戶端提供服務。服務器任務使用管道同本地客戶通信,使用一個套接字同遠端的客戶端通信。服務器任務必須儘快響應客戶端。如果服務器阻塞等待一個通信流,那麼除非這個通信流被處理,否則其他通信流將得不到服務。select機制具有同時監控套接字和管道的能力,所以可以用於解決該問題。

任務將阻塞直到數據可用或設備可寫。select()函數將在一個或多個文件描述符就緒或發生超時時返回。使用select()函數,任務可以制定等待哪些文件描述符的活動。在select()函數中使用位域指定感興趣的讀和寫文件描述符。當select()函數返回時,位域將修改爲反映當前哪些文件描述符可用。用於構建和操作位域的宏如下所示:

 

9.在內核中使用select()

 

10.在RTP中使用select()

11.POSIX文件系統函數

對於內核和RTP應用程序,VxWorks針對多種文件操作提供了相應的POSIX I/O和文件系統函數。如下所示:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章