国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

iTOP4412開發板Android5.1.1移植教程

發布時間:2021-1-21 11:20    發布者:落風

對于傳統的操作系統來說,普通的 I/O 操作一般會被內核緩存,這種 I/O 被稱作緩存 I/O。本文所介紹的文件訪問機制不經過操作系統內核的緩存,數據直接在磁盤和應用程序地址空間進行傳輸,所以該文件訪問的機制稱作為直接 I/O。Linux 中就提供了這樣一種文件訪問機制,對于那種將 I/O 緩存存放在用戶地址空間的應用程序來說,直接 I/O 是一種非常高效的手段。
“Linux 中一切皆文件”這句話已經不知道說了多少遍了,后面也會提到很多次。那么在深入學習之前,肯定要掌握對 Linux 文件的各種操作,包括讀、寫、創建等基本知識。
本章配套視頻為:
“視頻 05_01 文件 IO 之 open 打開操作”
“視頻 05_02 文件 IO 之 creat 創建操作”
“視頻 05_03 文件 IO 之 write 寫操作”
“視頻 05_04 文件 IO 之 read 讀操作”
16.1 Linux 中 中 IO  的概念介紹
所有的 I/O 操作都是通過讀文件或者寫文件來完成的。在這里,把所有的外圍設備,包括鍵盤和顯示器,都看成是文件系統中的文件。
什么是緩存 I/O
緩存 I/O 又被稱作標準 I/O,大多數文件系統的默認 I/O 操作都是緩存 I/O。在 Linux 的緩存 I/O 機制中,操作系統會將 I/O 的數據緩存在文件系統的頁緩存( page cache ) 中,也就是說,數據會先被拷貝到操作系統內核的緩沖區中,然后才會從操作系統內核的緩沖區拷貝到應用程序的地址空間。緩存 I/O 有
以下這些優點:
緩存 I/O 使用了操作系統內核緩沖區,在一定程度上分離了應用程序空間和實際的物理設備。
緩存 I/O 可以減少讀盤的次數,從而提高性能。
當應用程序嘗試讀取某塊數據的時候,如果這塊數據已經存放在了頁緩存中,那么這塊數據就可以立即返回給應用程序,而不需要經過實際的物理讀盤操作。當然,如果數據在應用程序讀取之前并未被存放在頁緩存中,那么就需要先將數據從磁盤讀到頁緩存中去。對于寫操作來說,應用程序也會將數據先寫到
頁緩存中去,數據是否被立即寫到磁盤上去取決于應用程序所采用的寫操作機制:如果用戶采用的是同步寫機制( synchronous writes ), 那么數據會立即被寫回到磁盤上,應用程序會一直等到數據被寫完為止;如果用戶采用的是延遲寫機制( deferred writes ),那么應用程序就完全不需要等到數據全部被寫回到磁盤,數據只要被寫到頁緩存中去就可以了。在延遲寫機制的情況下,操作系統會定期地將放在頁緩存中的數據刷到磁盤上。與異步寫機制( asynchronous writes )不同的是,延遲寫機制在數據完全寫到磁盤上的時候不會通知應用程序,而異步寫機制在數據完全寫到磁盤上的時候是會返回給應用程序的。所以延遲寫機制本身是存在數據丟失的風險的,而異步寫機制則不會有這方面的擔心。
緩存 I/O  的缺點
在緩存 I/O 機制中,DMA 方式可以將數據直接從磁盤讀到頁緩存中,或者將數據從頁緩存直接寫回到磁盤上,而不能直接在應用程序地址空間和磁盤之間進行數據傳輸,這樣的 話,數據在傳輸過程中需要在應用程序地址空間和頁緩存之間進行多次數據拷貝操作,這些數據拷貝操作所帶來的 CPU 以及內存開銷是
非常大的。
對于某些特殊的應用程序來說,避開操作系統內核緩沖區而直接在應用程序地址空間和磁盤之間傳輸數據會比使用操作系統內核緩沖區獲取更好的性能,下邊這一小節中提到的自緩存應用程序就是其中的一種。
小貼士-關于文件的相關知識的一點說明
在 Linux 中,文件非常重要,所以在 linux 系統中提供了豐富的文件操作函數。
在系統編程中,只會介紹編程中用到的最終的 API 和必須掌握的知識,還有大量的和文件相關的知識,例如高級 IO,制作文件系統,虛擬文件系統,文件共享,網絡文件系統等等。
如果真是要詳細的介紹整個 linux 文件,可能好幾千頁的書都介紹不完,而且對于大家學習初期也沒有太大的幫助,得不償失。
手冊中還會以其它形式介紹文件相關的知識,有的時候會介紹一步一步介紹如何操作,例如制作文件系統,NFS 網絡啟動;有時候會介紹如何使用,例如內核教程中介紹的虛擬文件系統等等。大家如果感興趣,在學習教程之外可以通過學習相關知識,去了解更加具體的含義。
文件對于 Linux 實在是太重要了,不過大家學習了本章的知識和實驗,了解其他和文件系統相關的知識,在后面 Linux 編程中遇到的問題基本可以自行解決了。
函數頭文件
在所有的 Linux 系統中,如果需要對文件的進行操作,只要包含如下 4 個頭文件即可。
#include
#include
#include
#include
上面四個頭文件中包含了打開,關閉,創建,讀文件,寫文件的函數,還有標志位,以及在不同 32 位以及 64 位系統下數據長度的宏變量定義。
16.2  打開文件函數 open
使用 open 函數的時候會返回一個文件句柄,文件句柄是文件的唯一識別符 ID。對文件的操作必須從讀取句柄開始。
先來看一下函數 open 的兩個原型。
int open(const char *path, int oflags);
有兩個參數的‘open’函數主要用于創建文件,在本章的 10.5.5 小節會和創建文件的函數 creat 的同時介紹具體用法,并給出例子。
int open(const char *path, int oflags,mode_t mode);
open 函數可以建立一個文件或者設備的訪問路徑。在打開或創建文件時可以指定文件的屬性及用戶的
權限等參數。
第一個參數 path 表示:路徑名或者文件名。路徑名為絕對路徑名,例如開發板中的 led 驅動的設備節點/dev/leds。
第二個參數 oflags 表示:打開文件所采取的動作。下 面 三 個 選 項 是 必 須 選 擇 其 中 之 一的 。
O_RDONLY 文件只讀
O_WRONLY 文件只寫
O_RDWR 文件可讀可寫
下面是可以任意選擇的。
O_APPEND 每次寫操作都寫入文件的末尾
O_CREAT 如果指定文件不存在,則創建這個文件
O_EXCL 如果要創建的文件已存在,則返回 -1,并且修改 errno 的值
O_TRUNC 如果文件存在,并且以只寫/讀寫方式打開,則清空文件全部內容
O_NOCTTY 如果路徑名指向終端設備,不要把這個設備用作控制終端。
O_NONBLOCK 如果路徑名指向 FIFO/塊文件/字符文件,則把文件的打開和后繼 I/O 設置為非阻塞模式
(nonblocking mode),后面會介紹什么是阻塞和非阻塞。
O_NDELAY 和 O_NONBLOCK 功能類似,調用 O_NDELAY 和使用的 O_NONBLOCK 功能是一樣的。第三個參數 mode 表示:設置創建文件的權限。
S_IRUSR,S_IWUSER,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,S_IWOTH,S_IXOTH. 其中 R:讀,W:寫,X:執行,USR:文件所屬的用戶,GRP:文件所屬的組,OTH: 其他用戶。第三個參數可以直接使用參數代替,參考 10.4.5 小節‘Linux 權限’。
前面用過的‘chmod 0777 helloworld’命令,其中的含義是一樣的,只不過 chmod 是在文件創建之后再修改權限。
open  函數代碼
編寫簡單的 open.c 文件測試 open 函數。首先添加頭文件,如下圖所示。
首先添加頭文件,如下圖所示。

然后 main 函數如下。

上圖中打開了三個文件分別屬于不同的情況。
/dev/leds 已經在開發板中存在,屬于驅動的設備節點,在 linux 驅動教程中會具體介紹
/bin/test1 和/bin/test2 都不存在
使用 open 函數調用上面三個文件,如果出錯就會打印錯誤,然后打印句柄。
編譯運行測試
Ubuntu 系統下,如下圖所示,進入前面實驗創建的目錄“/home/linuxsystemcode/iofile”,使用命令“mkdir iofile”新建 iofile 文件夾,將源碼 open.c 拷貝進去,進入新建的文件夾 iofileopen,如下圖所示。

使用命令“arm-none-linux-gnueabi-gcc -o open open.c -static”編譯 open 文件,如下圖所示,使用命令“ls”可以看到生成了 open 可執行文件。

這里介紹 U 盤拷貝代碼的方法,也可以編譯進文件系統,具體方法參考 10.3.5 小節。將編譯成的可執行文件 open,拷貝到 U 盤,啟動開發板,插入 U 盤,加載 U 盤,運行程序如下。

如上圖所示,可以看到打開/dev/leds 成功,這個是板載 LED 的內核驅動,調用的時候, 還調用了內核驅動中的函數,這個函數會打印“LEDS_CTL DEBUGevice Opened Success!”和“LEDS_CTL DEBUGeviceOpened Success!”
然后打印句柄 ID,/dev/leds fd is 3
調用“/bin/test1”會報錯“open /bin/test1 failed”,這種打開文件的方式是 linux 中標準的用法,幾乎所有對文件的 open 操作都會加上出錯報警的語句。
創建“/bin/test2”會打印“/bin/test2 fd is 4”,表明創建“/bin/test2 ”成功了。
使用命令“ls /bin/test2”,查看一下對應目錄‘/bin’下應該新建了“test2”,如下圖所示。

另外的“dev/leds”本身就存在,如下圖所示,這是驅動的設備節點文件,在后面的實驗會介紹如何操作調用,在 linux 驅動實驗中會介紹這個設備節點文件是如何生成的。

16.3  創建函數 creat 和 和 open
creat  函數介紹
關于 creat 函數,首先這個單詞并不是表示創建的意思,創建的英文單詞是“create”, 這是早期的一個小的拼寫錯誤,卻一直沿用下來。
在介紹 open 函數的時候,可以看到 open 函數有兩種形式,一個是兩個參數一個是三個參數,早期的時候 open 只有三個參數的形式,三個參數的形式會導致 open 函數無法打開一個未創建的文件,也就是無法建立文件,所以就有了這個 creat 函數。
現在 creat 函數可以完全用 open 替代,考慮到在閱讀代碼的時候可能會碰到,所以簡單介紹一下。
creat 函數原型如下。
int creat(const char * pathname, mode_t mode);
creat 函數只有兩個參數,參數的含義和 open 類似。大家看到這個函數的時候知道它是創建文件的就成,在寫代碼的時候完全可以用 open 代替。
creat  函數例程
編寫簡單的 creat.c 文件測試 creat 函數。首先添加頭文件,如下所示。

然后 main 函數如下所示。

第 22 行、27 行、31,open 可以打開已有的文件,也可以打開不存在的文件,即創建文件,創建文件的時候需要在參數中添加標志位 O_CREAT。在第 27 行代碼中,沒有添加標志位,運行的時候肯定會報錯,這么寫是希望大家能夠記住這個參數。
第 36 行是使用 creat 函數創建文件“test3”,注意一下 creat 函數和 open 函數在創建文件的時候,參數的區別。
編譯運行測試

在 Ubuntu 系統下,如下圖所示,進入前面實驗創建的目錄“/home/linuxsystemcode/iofile”,將源碼creat.c 拷貝進去,如下圖所示。

使用命令“arm-none-linux-gnueabi-gcc -o creat creat.c -static”編譯 creat.c 文件,如下圖所示,使用命令“ls”可以看到生成了 creat 可執行文件。

這里介紹 U 盤拷貝代碼的方法,也可以編譯進文件系統,具體方法參考 10.3.5 小節
將編譯成的可執行文件 creat,拷貝到 U 盤,啟動開發板,插入 U 盤,加載 U 盤,運行程序如下。

如上圖所示。
打開文件"/dev/leds"成功,這個文件已經存在
打開文件"/bin/test1"失敗,因為沒有添加參數 O_CREAT,這個文件不存在,新建的時候需要參數
O_CREAT。
打開文件"/bin/test2"成功,不存在這個文件,創建成功。
打開文件"/bin/test3"成功,不存在這個文件,使用 creat 新建成功。
如下圖所示,使用命令“ls /bin/test* ”在“/bin”目錄下可以看到新建的文件 test2 和 test3。

16.4  關閉函數 close
任何一個文件在操作完成之后都需要關閉,這個時候需要調用 close 函數。
close  函數介紹
調用 close 函數之后,會取消 open 函數建立的映射關系,句柄將不再有效,占用的空間將被系統釋放。
close 函數在頭文件“#include ”中,close 函數的使用和參數都比較簡單.
int close(int fd);
參數 fd,使用 open 函數打開文件之后返回的句柄。返回值,一般很少使用 close 的返回值。
close  函數例程
調用很簡單,在下一個實驗中會永到 close 函數。

16.5  寫函數 write
對文件進行寫操作,write 函數使用的比較多。
write  函數介紹
write 函數在頭文件“#include ”中。
函數原型為 ssize_t write(int fd,const void *buf,size_t count) 參數 fd,使用 open 函數打開文件之后返
回的句柄。
參數*buf,需要寫入的數據。
參數 count,將參數*buf 中最多 count 個字節寫入文件中。
返回值為 ssize 類型,出錯會返回-1,其它數值表示實際寫入的字節數。
write  函數例程
編寫簡單的 write.c 文件測試 write 函數。首先添加頭文件,如下所示。
//標準輸入輸出頭文件
#include
//文件操作函數頭文件
#include
#include
#include
#include
#include
然后 main 函數如下所示。

如上圖代碼所示。
在 16 行定義了 buffer_write 字符數組。
在 18 行,進行寫操作之前,必須得到文件的句柄,在這一行中使用 open 函數創建和打開文件“/bin/testwrite"。
在 23 行中會調用 write 函數,將 buffer_write 字符數組中的內容寫到新建的文件中。
在 31 行調用 close 函數,將"/bin/testwrite"文件關閉。
后面測試的時候可以在超級終端中,使用 vi 編輯器打開"/bin/testwrite"文件,可以看到這個文件中有字符 Hello Write Function!.
編譯運行測試
在 Ubuntu 系統下,如下圖所示,進入前面實驗創建的目錄“/home/linuxsystemcode/iofile”,將源碼write.c 拷貝進去,如下圖所示。

使用命令“arm-none-linux-gnueabi-gcc -o write write.c -static”編譯 write.c 文件,如下圖所示,使用命令“ls”可以看到生成了 write 可執行文件。

這里介紹 U 盤拷貝代碼的方法,也可以編譯進文件系統。
將編譯成的可執行文件 write,拷貝到 U 盤,啟動開發板,插入 U 盤,加載 U 盤,運行程序。如下圖所示,打印出了 Write Function OK!。

在代碼中定義的文件是"/bin/testwrite",使用 vi 編輯器打開文件,如下圖所示,程序執行運行成功。

16.6  文件的讀 read  函數
對文件進行寫操作,read 函數使用的比較多。
read  函數介紹
read 函數在頭文件“#include ”中。
函數原型為 ssize_t read(int fd,void *buf,size_t len)
參數 fd,使用 open 函數打開文件之后返回的句柄。
參數*buf,讀出的數據保存的位置。
參數 len,每次最多讀 len 個字節。
返回值為 ssize 類型,出錯會返回-1,其它數值表示實際寫入的字節數,返回值大于 0 小于 len 的數
值都是正常的。
read  函數例程
編寫簡單的 read.c 文件測試 read 函數。
首先添加頭文件和定義讀函數緩沖區為 1000,如下圖所示。
//標準輸入輸出頭文件
#include
//文件操作函數頭文件

#include
#include
#include
#include
#include
然后 main 函數如下圖所示。

如上代碼所示。 在 1-9 行,頭文件。
在 20 行,使用 open 函數打開或者新建"/bin/testwrite"文件。
在 23 行,使用 write 函數將 buffer 中的內容寫到"/bin/testwrite"文件中。在 35 行,使用 read 函數,將"/bin/testwrite"文件中的內容讀出來。
在 38 行,使用打印函數 printf 打印 read 函數讀出的數據。在 39 行,調用 close 函數關閉打開的文件,程序結束。
最終測試的時候,除了會出現"/bin/testwrite"文件,還會打印 read 函數讀取的數據。
編譯運行測試
在 Ubuntu 系統下,如下圖所示,進入前面實驗創建的目錄“/home/linuxsystemcode/iofile”,將源碼read.c 拷貝進去,如下圖所示。

使用命令“arm-none-linux-gnueabi-gcc -o read read.c -static”編譯 read.c 文件,如下圖所示,使用命令“ls”可以看到生成了 read 可執行文件。

這里介紹 U 盤拷貝代碼的方法,也可以編譯進文件系統。
將編譯成的可執行文件 read,拷貝到 U 盤,啟動開發板,插入 U 盤,加載 U 盤,運行程序。如下圖所示,可以看到打印出了“Files Content is Hello Write Function”,使代碼中預期的結果。


本文地址:http://m.qingdxww.cn/thread-755227-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • 利用SAM E54 Xplained Pro評估工具包演示CAN轉USB橋接器以及基于CAN的主機和自舉程序應用程序
  • 使用SAM-IoT Wx v2開發板演示AWS IoT Core應用程序
  • 使用Harmony3加速TCP/IP應用的開發培訓教程
  • 集成高級模擬外設的PIC18F-Q71家族介紹培訓教程
  • 貿澤電子(Mouser)專區
關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一级一片免费播放 | 99玖玖爱视频在线观看 | a一级一色一情 | 狠狠操综合网 | 男女性高爱麻豆 | 91香蕉成人免费高清网站 | 无吗无卡v清免费 | 国产99久久久国产精品小说 | 在线韩日 | 日韩国产成人精品视频 | 国产成人在线观看免费网站 | 国产精品啪 | 国产在线播放不卡 | 91色在线观看 | 欧美性猛交xxxxx免费看 | 欧美大片va欧美在线播放 | 国产香蕉在线精彩视频 | 精品麻豆视频 | 亚洲三级一区 | 男女污网站 | 欧美成年黄网站色视频 | 天天操中文字幕 | 亚洲欧美视频网站 | 黄网站在线播放视频免费观看 | 青青青视频在线播放 | 四虎影院精品 | 性三级视频| 精品自拍视频在线观看 | 亚洲日本天堂在线 | 久久精品成人欧美大片免费 | 成人一级 | 中文字幕手机在线播放 | 欧美一区二区高清 | 两个人在线观看完整 | 男人影院天堂网址 | 99热这里只有精品免费国产 | 欧美日韩三级在线 | 自拍偷拍欧美视频 | 久久h| 最新国产三级在线不卡视频 | 日本一区二区三区中文字幕 |