Linux驅動框架 hwmon

2021-06-23 06:54:23 字數 3553 閱讀 7118

寫在前面的話:

對於框架,我覺得就是在一定規範的形式下去實現你要的功能。這裡就涉及到乙個變與不變的地方。你所要實現的功能會是千差萬別的---這就是變的地方,而所謂既定的規範,包括建立目錄和屬性檔案這是linux系統已經為我們做好了的,我們只需要直接拿來引用就ok了。

那麼今天,我們就來看看hwmon框架是怎麼樣的。

對hwmon而言,它是sysfs框架下的乙個類,但是所有有關該類與sys的介面都已經在drivers/hwmon/hwmon.c實現,因而我們也不必過多的關心。

那麼我們到底要做些什麼呢?

對於你要實現的功能部分,你就自己去想象吧,下面我們來說說在我們的程式中對於不變的那部分要如何去實現。

我就以最基本的讀cpu溫度的程式為例,來說明整個框架的編寫。

一.作為驅動,首先我們要做就是驅動的註冊和撤銷。

因此,在***_hwmon_init()函式中對hwmon驅動和該驅動的屬性檔案等進行註冊。

my_hwmon_dev = hwmon_device_register(null);

ret = sysfs_create_group(&my_hwmon_dev->kobj,&my_hwmon_attribute_group);

ret = create_sysfs_temp_files(&my_hwmon_dev->kobj);

在有這麼多的註冊函式時,對於函式的異常處理,我個人覺得用goto來實現,比較直觀和易用,讓人看起來一目了然。

1

static

int __init my_hwmon_init(void)2

1314 ret = sysfs_create_group(&my_hwmon_dev->kobj,

15 &my_hwmon_attribute_group);

16if

(ret)

2021 ret = create_sysfs_temp_files(&my_hwmon_dev->kobj);

22if

(ret)

26return

ret;

2728

fail_create_sysfs_temp_files:

29 sysfs_remove_group(&my_hwmon_dev->kobj, &my_hwmon_attribute_group);

30fail_create_group_hwmon:

31hwmon_device_unregister(my_hwmon_dev);

32fail_hwmon_device_register:

33return

ret;

34 }

而在***_hwmon_exit()函式中,和***_hwmon_init()函式相對應的,以相反的順序對已註冊的裝置進行撤銷。

remove_sysfs_temp_files(&my_hwmon_dev->kobj);

sysfs_remove_group(&my_hwmon_dev->kobj,&my_hwmon_attribute_group);

hwmon_device_unregister(my_hwmon_dev);

好了,至此,hwmon架構的初始化和撤銷的工作已經完成。

二.接下去就是對hwmon下的各種屬性檔案的建立和對溫度的讀寫。

1.hwmon整體屬性框架

總的來講分為三部曲:

首先,每個hwmon裝置都會有自己獨有的屬性,這些獨有屬性就被sensor_device_attr宣告為struct attribute結構體。

sensor_device_attr具體定義在include/linux/hwmon-sysfs.h中:

1

#define sensor_device_attr(_name, _mode, _show, _store, _index) \23

struct

sensor_device_attribute sensor_dev_attr_##_name \

45 = sensor_attr(_name, _mode, _show, _store, _index)

在程式中,則被寫作:

1

static sensor_device_attr(name, s_irugo, get_my_hwmon_name, null, 0);

然後,加入到sysfs框架的struct attribute屬性結構體陣列中,注意該結構體陣列最後一項必須以null結尾。

struct attribute定義在include/linux/sysfs.h中。

1

static

struct attribute *my_hwmon_attributes =;

最後,將這些眾多的屬性彙總到結構struct attribute_group中。這個struct attribute_group被sysfs_create_group()函式呼叫建立整個屬性框架。

struct attribute_group定義在include/linux/sysfs.h中。

1

static

struct attribute_group my_hwmon_attribute_group =;

在我的程式中,這裡只有乙個屬性—name,表示該hwmon驅動的名稱。

2.溫度相關屬性檔案的建立

在上面,整個hwmon的框架已經建立,接下來就是溫度的讀取,顯示。這個過程其實是sysfs框架的內容。

首先,確定會有多少屬性,每個屬性檔案都會被sensor_device_attr宣告為struct attribute結構體。其中的_show和_store是以函式形式實現,因此對應的實現相應的函式,若沒有這個功能的實現就以null代替;

_show表示的是從屬性檔案中讀取出資料。

_store表示的是向屬性檔案中寫入資料。

因此,如果該屬性檔案是不可寫是,_store實現為null。

然後,將同一seneor的屬性加入到sysfs框架的struct attribute屬性結構體陣列中,注意該結構體陣列最後一項必須以null結尾,被sysfs_create_files()函式呼叫。

以上兩步是建立屬性檔案最基本的兩步,我們的具體功能可以在_show和_store兩個函式中去實現。當然對於一些複雜的裝置來講僅僅這兩步是不夠的,如果該裝置屬於平台驅動或者是某一大類裝置,如i2c,我們此時就需要根據具體情況去宣告相應的結構,並按照相應結構的規範去操作。

在我的程式中僅限於前兩步,因為程式中並未涉及到任何其他裝置,只是簡單的讀取了溫度暫存器。程式中定義了兩個屬性my_cpu_temp_label和get_my_cpu_temp。

下面是我模組在載入後生成目錄的tree型圖:

這些就是我對hwmon框架在目前基礎上的了解。

我的github位址為:

希望大家多多提意見哦!

LINUX驅動框架

include include include include include include include include include define led major 200 define led name new led 暫存器實體地址 define ccm ccgr1 base 0x0...

linux驅動(一) linux驅動框架

編寫linux驅動先看一下驅動框架是什麼樣子的。驅動編寫和應用層編寫有什麼區別呢?一 首先 入口函式的問題。應用層編寫我們的入口就是main函式,但在驅動編寫時不是這樣的,有兩種情況,1 預設情況下 int init init module void 載入模組時的初始化函式,也就是驅動模組的入口函式...

Linux 裝置驅動框架

1 驅動框架 linux將所有外部裝置看成是一類特殊檔案,稱之為 裝置檔案 如果說系統呼叫是linux核心和應用程式之間的介面,那麼裝置驅動程式則可以看成是linux核心與外部裝置之間的介面。裝置驅動程式向應用程式遮蔽了硬體在實現上的細節,使得應用程式可以像操作普通檔案一樣來操作外部裝置。在應用程式...