劉江
【摘要】在嵌入式開發(fā)中我們有時(shí)需要在用戶層控制內(nèi)核及其驅(qū)動的一些功能。傳統(tǒng)的方法是通過ioctl系統(tǒng)調(diào)用實(shí)現(xiàn)。而Sysfs為我們提供了一種更為方便的通過讀寫文件的方法。大大方便了嵌入式開發(fā)。
【關(guān)鍵詞】嵌入式;內(nèi)核驅(qū)動;Sysfs文件系統(tǒng)
Sysfs是一個向用戶空間導(dǎo)出內(nèi)核數(shù)據(jù)結(jié)構(gòu),對象和性質(zhì)的文件系統(tǒng),它不僅提供了察看內(nèi)核內(nèi)部數(shù)據(jù)結(jié)構(gòu)的能力,還可以修改這些數(shù)據(jù)結(jié)構(gòu)。Sysfs已經(jīng)成為老式的IOCTL機(jī)制的一種替代品。向內(nèi)核發(fā)送神秘的ioctl通常需要一個C程序。與之相比,從/向Sysfs文件讀/寫一個值要簡單的多。一個簡單的shell命令就足夠了。
一、建立屬性文件
Sysfs是用于表現(xiàn)設(shè)備驅(qū)動模型的文件系統(tǒng),它基于ramfs。要使用Sysfs就需要了解Sysfs提供給外界的API。Sysfs文件系統(tǒng)中提供了四類文件的創(chuàng)建與管理,分別是目錄、普通文件、軟鏈接文件、二進(jìn)制文件。目錄層次往往代表著設(shè)備驅(qū)動模型的結(jié)構(gòu),軟鏈接文件則代表著不同部分間的關(guān)系。比如某個設(shè)備的目錄只出現(xiàn)在/sys/devices下,其他地方涉及到它時(shí)只好用軟鏈接文件鏈接過去,保持了設(shè)備唯一的實(shí)例。而普通文件和二進(jìn)制文件往往代表了設(shè)備的屬性,讀寫這些文件需要調(diào)用相應(yīng)的屬性讀寫。
我們可以使用DEVICE_ATTR函數(shù)宏來建立一個屬性文件。函數(shù)宏DEVICE_ATTR原型是DRIVER_ATTR(_name,_mode,_show,_store)。函數(shù)宏DEVICE_ATTR內(nèi)封裝的是__ATTR(_name,_mode,_show,_stroe)方法。_show:表示的是讀方法,_stroe表示的是寫方法。通過以下實(shí)例我們可以在Sysfs文件系統(tǒng)中建立一個dev_attr_watchdog的屬性文件。其中wd_show和wd_store分別為讀寫方法。
staticDEVICE_ATTR(watchdog,S_IRUGO|S_IWUSR,wd_show,wd_store);
將_mode設(shè)置為S_IRUGO|S_IWUSR使創(chuàng)建的屬性文件為可讀可寫。在驅(qū)動的初始化函數(shù)中需要調(diào)用device_create_file來使屬性文件與驅(qū)動設(shè)備文件關(guān)聯(lián)。函數(shù)原型為intdevice_create_file(structdevicedev,conststructdevice_attributeattr);
二、屬性的讀寫
注意到它和虛擬字符設(shè)備或proc項(xiàng)的read/write的作用很類似,但有一點(diǎn)不同是show/store函數(shù)上的buf/count參數(shù)是在Sysfs層已作了用戶區(qū)/內(nèi)核區(qū)的內(nèi)存復(fù)制,虛擬字符設(shè)備上常見的__user屬性在這里并不需要,因而也不需要多一次copy_from_user/copy_to_user,在show/store函數(shù)參數(shù)上的buf/count參數(shù)已經(jīng)是內(nèi)核區(qū)的地址,可以直接操作。
使用show和store方法時(shí)的注意事項(xiàng):
(1)緩沖區(qū)的大小應(yīng)總是為PAGE_SIZE個字節(jié)。多數(shù)情況下PAGE_SIZE=4096。
(2)show方法應(yīng)該返回放入緩沖區(qū)的字節(jié)數(shù)。
(3)store方法應(yīng)該返回實(shí)際使用的字節(jié)數(shù)。
(4)show和/或者store方法可能會出錯,所以當(dāng)失敗時(shí),記得返回錯誤值。
三、用戶層操作方法
建立屬性文件后Sysfs會在相應(yīng)的目錄創(chuàng)建文件,通過讀寫此文件我們就可以直接向驅(qū)動層發(fā)送和讀取數(shù)據(jù)。例如上面DEVICE_ATTR調(diào)用會創(chuàng)建/sys/devices/platform/omap/omap_wdt/watchdog文件,此文件就是看門狗驅(qū)動在Sysfs中的屬性文件。當(dāng)需要查看看門狗參數(shù)時(shí)可以使用cat命令讀取watchdog文件實(shí)現(xiàn)。修改看門狗參數(shù)時(shí)可以使用echo命令向watchdog文件寫入內(nèi)容實(shí)現(xiàn)。
屬性文件的創(chuàng)建使用戶層通過驅(qū)動控制硬件的方式更加方便,只需使用系統(tǒng)自帶的cat和echo命令就能實(shí)現(xiàn)對硬件的控制,極大地方便了嵌入式開發(fā)。
四、結(jié)語
Sysfs給應(yīng)用程序提供了統(tǒng)一訪問設(shè)備的接口。通過這一接口我們可以使用shell腳本在用戶層實(shí)現(xiàn)對內(nèi)核及其驅(qū)動的控制。這一功能極大的方便了嵌入式應(yīng)用的開發(fā)。但是目前Sysfs僅僅是提供了一個可以統(tǒng)一訪問設(shè)備的框架,但究竟是否支持Sysfs還需要各設(shè)備驅(qū)動程序的編程支持。但由于Sysfs強(qiáng)大的功能和用戶空間友好的特性,越來越多的子系統(tǒng)、設(shè)備驅(qū)動程序逐漸轉(zhuǎn)向Sysfs。
參考文獻(xiàn)
[1]WolfgangMauerer深入Linux內(nèi)核架構(gòu)[M].北京:人民郵電出版社,2010.
[2]JonathanCorber,AlessandroRubini&GregKroan-hartman Linux設(shè)備驅(qū)動程序[M].北京:中國電力出版社,2005.