日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > 嵌入式微處理器
[導(dǎo)讀]由于需要對(duì)ADC進(jìn)行驅(qū)動(dòng)設(shè)計(jì),因此學(xué)習(xí)了一下Linux驅(qū)動(dòng)的IIO子系統(tǒng)。本文翻譯自《Linux Device Drivers Development 》--John Madieu

直接來(lái)源:嵌入式客棧

出處:https://www.cnblogs.com/yongleili717/p/10744252.html

作者三石li

由于需要對(duì)ADC進(jìn)行驅(qū)動(dòng)設(shè)計(jì),因此學(xué)習(xí)了一下Linux驅(qū)動(dòng)的IIO子系統(tǒng)。本文翻譯自《Linux Device Drivers Development 》--John Madieu

IIO Framework

工業(yè)I/O(IIO)是專用于模數(shù)轉(zhuǎn)換器(ADC)和數(shù)模轉(zhuǎn)換器(DAC)的內(nèi)核子系統(tǒng)。隨著越來(lái)越多的具有不同代碼實(shí)現(xiàn)的傳感器(具有模擬到數(shù)字或數(shù)字到模擬,功能的測(cè)量設(shè)備)分散在內(nèi)核源上,收集它們變得必要。這就是IIO框架以通用的方式所做的事情。自2009年以來(lái),Jonathan Cameron和Linux-IIO社區(qū)一直在開發(fā)它。

加速度計(jì),陀螺儀,電流/電壓測(cè)量芯片,光傳感器,壓力傳感器等都屬于IIO系列器件。

IIO模型基于設(shè)備和通道架構(gòu):

  • 設(shè)備代表芯片本身。它是層次結(jié)構(gòu)的頂級(jí)。
  • 通道代表設(shè)備的單個(gè)采集線。設(shè)備可以具有一個(gè)或多個(gè)通道。例如,加速度計(jì)是具有 ?三個(gè)通道的裝置,每個(gè)通道對(duì)應(yīng)一個(gè)軸(X,Y和Z)。

IIO芯片是物理和硬件傳感器/轉(zhuǎn)換器。它作為字符設(shè)備(當(dāng)支持觸發(fā)緩沖時(shí))暴露給用戶空間,以及包含一組文件的sysfs目錄條目,其中一些文件代表通道。單個(gè)通道用單個(gè)sysfs文件條目表示。

下面是從用戶空間與IIO驅(qū)動(dòng)程序交互的兩種方式:

  • /sys/bus/iio/iio:deviceX/:表示傳感器及其通道
  • /dev/iio:deviceX: 表示導(dǎo)出設(shè)備事件和數(shù)據(jù)緩沖區(qū)的字符設(shè)備

IIO框架架構(gòu)和布局

上圖顯示了如何在內(nèi)核和用戶空間之間組織IIO框架。驅(qū)動(dòng)程序使用IIO核心公開的一組工具和API來(lái)管理硬件并向IIO核心報(bào)告處理。然后,IIO子系統(tǒng)通過(guò)sysfs接口和字符設(shè)備將整個(gè)底層機(jī)制抽象到用戶空間,用戶可以在其上執(zhí)行系統(tǒng)調(diào)用。

IIO API分布在多個(gè)頭文件中,如下所示:

#include?????/*?mandatory?*/
#include???/*?mandatory?since?sysfs?is?used?*/
#include??/*?For?advanced?users,?to?manage?iio?events?*/
#include??/*?mandatory?to?use?triggered?buffers?*/
#include?/*?Only?if?you?implement?trigger?in?your?driver?(rarely?used)*/

在以下文章中,我們將描述和處理IIO框架的每個(gè)概念,例如

  • 遍歷其數(shù)據(jù)結(jié)構(gòu)(設(shè)備,通道等)
  • 觸發(fā)緩沖支持和連續(xù)捕獲,以及其sysfs接口
  • 探索現(xiàn)有的IIO觸發(fā)器
  • 以單次模式或連續(xù)模式捕獲數(shù)據(jù)
  • 列出可用于幫助開發(fā)人員測(cè)試其設(shè)備的可用工具

IIO數(shù)據(jù)結(jié)構(gòu)

IIO設(shè)備在內(nèi)核中表示為struct iio_dev結(jié)構(gòu)體的一個(gè)實(shí)例,并由struct iio_info結(jié)構(gòu)體描述。所有重要的IIO結(jié)構(gòu)都在include/linux/iio/iio.h中定義。

iio_dev結(jié)構(gòu)

該結(jié)構(gòu)代表IIO設(shè)備,描述設(shè)備和驅(qū)動(dòng)程序。它告訴我們:

  • 設(shè)備上有多少個(gè)通道?

  • 設(shè)備可以在哪些模式下運(yùn)行:?jiǎn)未?,觸發(fā)緩沖?

  • 這個(gè)驅(qū)動(dòng)程序可以使用哪些hooks鉤子?

struct?iio_dev?{
???[...]
???int?modes;
???int?currentmode;
???struct?device?dev;
???struct?iio_buffer?*buffer;
???int?scan_bytes;
???const?unsigned?long?*available_scan_masks;
???const?unsigned?long?*active_scan_mask;
???bool?scan_timestamp;
???struct?iio_trigger?*trig;
???struct?iio_poll_func?*pollfunc;
???struct?iio_chan_spec?const?*channels;
???int?num_channels;
???const?char?*name;
???const?struct?iio_info?*info;
???const?struct?iio_buffer_setup_ops?*setup_ops;
???struct?cdev?chrdev;

};

完整的結(jié)構(gòu)在IIO頭文件中定義。我們將不感興趣的字段在此處刪除。

  • modes: 這表示設(shè)備支持的不同模式。支持的模式有:

    • INDIO_DIRECT_MODE表示設(shè)備提供的sysfs接口。
    • INDIO_BUFFER_TRIGGERED表示設(shè)備支持硬件觸發(fā)器。使用iio_triggered_buffer_setup()函數(shù)設(shè)置觸發(fā)緩沖區(qū)時(shí),此模式會(huì)自動(dòng)添加到設(shè)備中.
    • INDIO_BUFFER_HARDWARE表示設(shè)備具有硬件緩沖區(qū)。
    • INDIO_ALL_BUFFER_MODES是上述兩者的聯(lián)合。
  • currentmode: 這表示設(shè)備實(shí)際使用的模式。

  • dev: 這表示IIO設(shè)備所依賴的struct設(shè)備(根據(jù)Linux設(shè)備型號(hào))。

  • buffer: 這是您的數(shù)據(jù)緩沖區(qū),在使用觸發(fā)緩沖區(qū)模式時(shí)會(huì)推送到用戶空間。使用iio_triggered_buffer_setup函數(shù)啟用觸發(fā)緩沖區(qū)支持時(shí),它會(huì)自動(dòng)分配并與您的設(shè)備關(guān)聯(lián)。

  • scan_bytes: 這是捕獲并饋送到緩沖區(qū)的字節(jié)數(shù)。當(dāng)從用戶空間使用觸發(fā)緩沖區(qū)時(shí),緩沖區(qū)應(yīng)至少為indio-> scan_bytes字節(jié)大。

  • available_scan_masks: 這是允許的位掩碼的可選數(shù)組。使用觸發(fā)緩沖器時(shí),可以啟用通道捕獲并將其饋入IIO緩沖區(qū)。如果您不想允許某些通道啟用,則應(yīng)僅使用允許的通道填充此數(shù)組。以下是為加速度計(jì)(帶有X,Y和Z通道)提供掃描掩碼的示例:

/*
?*?Bitmasks?0x7?(0b111)?and?0?(0b000)?are?allowed.
?*?It?means?one?can?enable?none?or?all?of?them.
?*?one?can't?for?example?enable?only?channel?X?and?Y
?*/


static?const?unsigned?long?my_scan_masks[]?=?{0x7,?0};
indio_dev->available_scan_masks?=?my_scan_masks;
  • active_scan_mask: 這是啟用通道的位掩碼。只有來(lái)自這些通道的數(shù)據(jù)能被推入緩沖區(qū)。例如,對(duì)于8通道ADC轉(zhuǎn)換器,如果只啟用第一個(gè)(0),第三個(gè)(2)和最后一個(gè)(7)通道,則位掩碼將為0b10000101(0x85)。active_scan_mask將設(shè)置為0x85。然后,驅(qū)動(dòng)程序可以使用for_each_set_bit宏遍歷每個(gè)設(shè)置位,根據(jù)通道獲取數(shù)據(jù),并填充緩沖區(qū)。

  • scan_timestamp: 這告訴我們是否將捕獲時(shí)間戳推入緩沖區(qū)。如果為true,則將時(shí)間戳作為緩沖區(qū)的最后一個(gè)元素。時(shí)間戳大8字節(jié)(64位)。

  • trig: 這是當(dāng)前設(shè)備觸發(fā)器(支持緩沖模式時(shí))。

  • pollfunc:這是在接收的觸發(fā)器上運(yùn)行的函數(shù)。

  • channels: 這表示通道規(guī)范結(jié)構(gòu),用于描述設(shè)備具有的每個(gè)通道。

  • num_channels: 這表示通道中指定的通道數(shù)。

  • name: 這表示設(shè)備名稱。

  • info: 來(lái)自驅(qū)動(dòng)程序的回調(diào)和持續(xù)信息。

  • setup_ops: 啟用/禁用緩沖區(qū)之前和之后調(diào)用的回調(diào)函數(shù)集。這個(gè)結(jié)構(gòu)在include / linux / iio / iio.h中定義,如下所示:

struct?iio_buffer_setup_ops?{
????int?(*?preenable)?(struct?iio_dev?*);
????int?(*?postenable)?(struct?iio_dev?*);
????int?(*?predisable)?(struct?iio_dev?*);
????int?(*?postdisable)?(struct?iio_dev?*);
????bool?(*?validate_scan_mask)?(struct?iio_dev?*indio_dev,
?????????????????????????????????const?unsigned?long?*scan_mask);
};
  • setup_ops: 如果未指定,則IIO內(nèi)核使用drivers / iio / buffer / industrialio-triggered-buffer.c中定義的缺省iio_triggered_buffer_setup_ops。

  • chrdev: 這是由IIO核心創(chuàng)建的關(guān)聯(lián)字符設(shè)備。

用于為IIO設(shè)備分配內(nèi)存的函數(shù)是iio_device_alloc():

struct?iio_dev?*?iio_device_alloc(int?sizeof_priv)?
///struct?iio_dev?*devm_iio_device_alloc(struct?device?*dev,?int?sizeof_priv)
/*?Resource-managed?iio_device_alloc()*/
/*Managed?iio_device_alloc.?iio_dev?allocated?with?this?function?is?automatically?freed?on?driver?detach.
If?an?iio_dev?allocated?with?this?function?needs?to?be?freed?separately,?devm_iio_device_free()?must?be?used.?*/

dev是為其分配iio_dev的設(shè)備,sizeof_priv是用于為任何私有結(jié)構(gòu)分配的內(nèi)存空間。這樣,傳遞每個(gè)設(shè)備(私有)數(shù)據(jù)結(jié)構(gòu)非常簡(jiǎn)單。如果分配失敗,該函數(shù)返回NULL:

struct?iio_dev?*indio_dev;
struct?my_private_data?*data;
indio_dev?=?iio_device_alloc(sizeof(*data));
if?(!indio_dev)
??????????return?-ENOMEM;
/*data?is?given?the?address?of?reserved?momory?for?private?data?*/
data?=?iio_priv(indio_dev);

在分配IIO設(shè)備存儲(chǔ)器之后,下一步是填充不同的字段。完成后,必須使用iio_device_register函數(shù)向IIO子系統(tǒng)注冊(cè)設(shè)備:

int?iio_device_register(struct?iio_dev?*indio_dev)
???????//devm_iio_device_register(dev,?indio_dev)
/*?Resource-managed?iio_device_register()?*/

在執(zhí)行此功能后,設(shè)備將準(zhǔn)備好接受來(lái)自用戶空間的請(qǐng)求。反向操作(通常在釋放函數(shù)中完成)是iio_device_unregister():

void?iio_device_unregister(struct?iio_dev?*indio_dev)
//?void?devm_iio_device_unregister(struct?device?*?dev,?struct?iio_dev?*?indio_dev)

一旦取消注冊(cè),iio_device_alloc分配的內(nèi)存可以用iio_device_free釋放:

void?iio_device_free(struct?iio_dev?*iio_dev)
//?void?devm_iio_device_free(struct?device?*?dev,?struct?iio_dev?*?iio_dev)

給定IIO設(shè)備作為參數(shù),可以通過(guò)以下方式檢索私有數(shù)據(jù):

?struct?my_private_data?*the_data?=?iio_priv(indio_dev);

iio_info結(jié)構(gòu)體

struct iio_info結(jié)構(gòu)用于聲明IIO內(nèi)核使用的鉤子,以讀取/寫入通道/屬性值:

struct?iio_info?{
???????????struct?module?*driver_module;
????????????const?struct?attribute_group?*attrs;
????????????int?(*read_raw)(struct?iio_dev?*indio_dev,
???????????????struct?iio_chan_spec?const?*chan,
???????????????int?*val,?int?*val2,?long?mask);

????????????int?(*write_raw)(struct?iio_dev?*indio_dev,

????????????????struct?iio_chan_spec?const?*chan,

????????????????int?val,?int?val2,?long?mask);
?????????????[...]

};
  • driver_module: 這是用于確保chrdev正確擁有的模塊結(jié)構(gòu),通常設(shè)置為THIS_MODULE。

  • attrs: 這表示設(shè)備屬性。

  • read_raw: 這是用戶讀取設(shè)備sysfs文件屬性時(shí)的回調(diào)運(yùn)行。mask參數(shù)是一個(gè)位掩碼,它允許我們知道請(qǐng)求了哪種類型的值。channel參數(shù)讓我們知道相關(guān)的通道。它可以是采樣頻率,用于將原始值轉(zhuǎn)換為可用值的比例,或原始值本身。

  • write_raw: 這是用于將值寫入設(shè)備的回調(diào)。例如,可以使用它來(lái)設(shè)置采樣頻率。

以下代碼顯示了如何設(shè)置struct iio_info結(jié)構(gòu):

static?const?struct?iio_info?iio_dummy_info?=?{
????.driver_module?=?THIS_MODULE,
????.read_raw?=?&iio_dummy_read_raw,
????.write_raw?=?&iio_dummy_write_raw,
[...]

/*
?*?Provide?device?type?specific?interface?functions?and
?* constant data. 提供設(shè)備類型特定的接口功能和常量數(shù)據(jù)。
?*/

indio_dev->info?=?&iio_dummy_info;

IIO channels

通道代表單條采集線。例如加速度計(jì)具有3個(gè)通道(X,Y,Z),因?yàn)槊總€(gè)軸代表單個(gè)采集線。struct iio_chan_spec是表示和描述內(nèi)核中單個(gè)通道的結(jié)構(gòu):

?struct?iio_chan_spec?{
????????enum?iio_chan_type?type;
????????int?channel;
????????int?channel2;
????????unsigned?long?address;
????????int?scan_index;
????????struct?{
????????????charsign;
????????????u8?realbits;
????????????u8?storagebits;
????????????u8?shift;
????????????u8?repeat;
????????????enum?iio_endian?endianness;
????????}?scan_type;
????????long?info_mask_separate;
????????long?info_mask_shared_by_type;
????????long?info_mask_shared_by_dir;
????????long?info_mask_shared_by_all;
????????const?struct?iio_event_spec?*event_spec;
????????unsigned?int?num_event_specs;
????????const?struct?iio_chan_spec_ext_info?*ext_info;
????????const?char?*extend_name;
????????const?char?*datasheet_name;
????????unsigned?modified:1;
????????unsigned?indexed:1;
????????unsigned?output:1;
????????unsigned?differential:1;

????};

各個(gè)參數(shù)意義:

  • type: 這指定了通道的測(cè)量類型。在電壓測(cè)量的情況下,它應(yīng)該是IIO_VOLTAGE。對(duì)于光傳感器,它是IIO_LIGHT。對(duì)于加速度計(jì),使用IIO_ACCEL。所有可用類型都在include / uapi / linux / iio / types.h中定義,如enum iio_chan_type。要為給定轉(zhuǎn)換器編寫驅(qū)動(dòng)程序,請(qǐng)查看該文件以查看每個(gè)通道所屬的類型。

  • channel: 這指定.indexed設(shè)置為1時(shí)的通道索引。

  • channel2: 這指定.modified設(shè)置為1時(shí)的通道修飾。

  • modified: 這指定是否將修飾符應(yīng)用于此通道屬性名稱。在這種情況下,修飾符設(shè)置在.channel2中。(例如,IIO_MOD_X,IIO_MOD_Y,IIO_MOD_Z是關(guān)于xyz軸的軸向傳感器的修改器)??捎眯揎椃斜碓趦?nèi)核IIO頭中定義為枚舉iio_modifier。修飾符只會(huì)破壞sysfs中的通道屬性名稱,而不是值。

  • indexed: 這指定通道屬性名稱是否具有索引。如果是,則在.channel字段中指定索引。

  • scan_index and scan_type: 當(dāng)使用緩沖區(qū)觸發(fā)器時(shí),這些字段用于標(biāo)識(shí)緩沖區(qū)中的元素。scan_index設(shè)置緩沖區(qū)內(nèi)捕獲的通道的位置。具有較低scan_index的通道將放置在具有較高索引的通道之前。將.scan_index設(shè)置為-1將阻止通道進(jìn)行緩沖捕獲(scan_elements目錄中沒(méi)有條目)。

暴露給用戶空間的通道sysfs屬性以位掩碼的形式指定。根據(jù)共享信息,可以將屬性設(shè)置為以下掩碼之一:

  • info_mask_separate 將屬性標(biāo)記為特定于此通

  • info_mask_shared_by_type 將該屬性標(biāo)記為由相同類型的所有通道共享。導(dǎo)出的信息由相同類型的所有通道共享。

  • info_mask_shared_by_dir 將屬性標(biāo)記為由同一方向的所有通道共享。導(dǎo)出的信息由同一方向的所有通道共享。

  • info_mask_shared_by_all 將屬性標(biāo)記為所有通道共享,無(wú)論其類型或方向如何。導(dǎo)出的信息由所有渠道共享。用于枚舉這些屬性的位掩碼都在include / linux / iio / iio.h中定義:

enum?iio_chan_info_enum?{
????IIO_CHAN_INFO_RAW?=?0,
????IIO_CHAN_INFO_PROCESSED,
????IIO_CHAN_INFO_SCALE,
????IIO_CHAN_INFO_OFFSET,
????IIO_CHAN_INFO_CALIBSCALE,
????[...]
????IIO_CHAN_INFO_SAMP_FREQ,
????IIO_CHAN_INFO_FREQUENCY,
????IIO_CHAN_INFO_PHASE,
????IIO_CHAN_INFO_HARDWAREGAIN,
????IIO_CHAN_INFO_HYSTERESIS,
????[...]
};

字節(jié)序字段應(yīng)為以下之一:

enum?iio_endian?{
??????IIO_CPU,
??????IIO_BE,
??????IIO_LE,
};

通道屬性命名約定

屬性的名稱由IIO核心自動(dòng)生成,具有以下模式:{direction} _ {type} _ {index} _ {modifier} _ {info_mask}:

  • direction方向?qū)?yīng)于屬性方向,根據(jù)drivers / iio / industrialio-core.c中的struct iio_direction結(jié)構(gòu):
static?const?char?*?const?iio_direction[]?=?{
???[0]?=?"in",
???[1]?=?"out",?
};?
  • type對(duì)應(yīng)于通道類型,根據(jù)char數(shù)組const iio_chan_type_name_spec:
static?const?char?*?const?iio_chan_type_name_spec[]?=?{
???[IIO_VOLTAGE]?=?"voltage",
???[IIO_CURRENT]?=?"current",
???[IIO_POWER]?=?"power",
???[IIO_ACCEL]?=?"accel",
???[...]
???[IIO_UVINDEX]?=?"uvindex",
???[IIO_ELECTRICALCONDUCTIVITY]?=?"electricalconductivity",
???[IIO_COUNT]?=?"count",
???[IIO_INDEX]?=?"index",
???[IIO_GRAVITY]??=?"gravity",
};
  • lindex 索引模式取決于是否設(shè)置了通道.indexed字段。如果設(shè)置,索引將從.channel字段中獲取,以替換{index}模式。
  • modifier 模式取決于通道所設(shè)置的.modified字段。如果設(shè)置,修飾符將從.channel2字段中獲取,{modifier}模式將根據(jù)char數(shù)組struct iio_modifier_names結(jié)構(gòu)替換:
static?const?char?*?const?iio_modifier_names[]?=?{
???[IIO_MOD_X]?=?"x",
???[IIO_MOD_Y]?=?"y",
???[IIO_MOD_Z]?=?"z",
???[IIO_MOD_X_AND_Y]?=?"x&y",
???[IIO_MOD_X_AND_Z]?=?"x&z",
???[IIO_MOD_Y_AND_Z]?=?"y&z",
???[...]
???[IIO_MOD_CO2]?=?"co2",
???[IIO_MOD_VOC]?=?"voc",
};

l info_mask取決于char數(shù)組iio_chan_info_postfix中的通道信息掩碼,私有或共享索引值:

/*?relies?on?pairs?of?these?shared?then?separate依賴于這些共享的對(duì),然后分離*/
static?const?char?*?const?iio_chan_info_postfix[]?=?{
???[IIO_CHAN_INFO_RAW]?=?"raw",
???[IIO_CHAN_INFO_PROCESSED]?=?"input",
???[IIO_CHAN_INFO_SCALE]?=?"scale",
???[IIO_CHAN_INFO_CALIBBIAS]?=?"calibbias",
???[...]
???[IIO_CHAN_INFO_SAMP_FREQ]?=?"sampling_frequency",
???[IIO_CHAN_INFO_FREQUENCY]?=?"frequency",
???[...]
};

通道區(qū)分

當(dāng)每種通道類型有多個(gè)數(shù)據(jù)通道時(shí),您可能會(huì)遇到麻煩。困境將是:如何識(shí)別它們。有兩種解決方案:索引和修飾符。

使用索引:給定具有一個(gè)通道線的ADC器件,不需要索引。通道定義如下:

static?const?struct?iio_chan_spec?adc_channels[]?=?{
????????????????{
????????????????????????.type?=?IIO_VOLTAGE,
????????????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),

???????????????},
}

由前面描述的通道產(chǎn)生的屬性名稱將是in_voltage_raw。

/sys/bus/iio/iio:deviceX/in_voltage_raw

現(xiàn)在讓我們看一下有4個(gè)甚至8個(gè)通道的轉(zhuǎn)換器。我們?nèi)绾巫R(shí)別它們?解決方案是使用索引。將.indexed字段設(shè)置為1將使用.channel值替換{index}模式來(lái)替換通道屬性名稱:

??static?const?struct?iio_chan_spec?adc_channels[]?=?{
????????{
????????????????.type?=?IIO_VOLTAGE,
????????????????.indexed?=?1,
????????????????.channel?=?0,
????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),

????????},

????????{
????????????????.type?=?IIO_VOLTAGE,
????????????????.indexed?=?1,
????????????????.channel?=?1,
????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),
????????},
????????{
????????????????.type?=?IIO_VOLTAGE,
????????????????.indexed?=?1,
????????????????.channel?=?2,
????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),
????????},
????????{
????????????????.type?=?IIO_VOLTAGE,
????????????????.indexed?=?1,
????????????????.channel?=?3,
????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),
????????},
}

生成的通道屬性為:

/sys/bus/iio/iio:deviceX/in_voltage0_raw
/sys/bus/iio/iio:deviceX/in_voltage1_raw
/sys/bus/iio/iio:deviceX/in_voltage2_raw
/sys/bus/iio/iio:deviceX/in_voltage3_raw

使用修飾符:給定一個(gè)帶有兩個(gè)通道的光傳感器 - 一個(gè)用于紅外光,一個(gè)用于紅外和可見光,沒(méi)有索引或修改器,屬性名稱將為in_intensity_raw。在這里使用索引可能容易出錯(cuò),因?yàn)槭褂胕n_intensity0_ir_raw和in_intensity1_ir_raw是沒(méi)有意義的。使用修飾符將有助于提供有意義的屬性名稱。通道的定義如下:

static?const?struct?iio_chan_spec?mylight_channels[]?=?{

????????{
????????????????.type?=?IIO_INTENSITY,
????????????????.modified?=?1,
????????????????.channel2?=?IIO_MOD_LIGHT_IR,
????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),
????????????????.info_mask_shared?=?BIT(IIO_CHAN_INFO_SAMP_FREQ),
????????},
????????{
????????????????.type?=?IIO_INTENSITY,
????????????????.modified?=?1,
????????????????.channel2?=?IIO_MOD_LIGHT_BOTH,
????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),
????????????????.info_mask_shared?=?BIT(IIO_CHAN_INFO_SAMP_FREQ),
????????},
????????{
????????????????.type?=?IIO_LIGHT,
????????????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_PROCESSED),
????????????????.info_mask_shared?=BIT(IIO_CHAN_INFO_SAMP_FREQ),

????????},
???????}

屬性結(jié)果:

l?/sys/bus/iio/iio:deviceX/in_intensity_ir_raw?用于測(cè)量IR強(qiáng)度的通道
l?/sys/bus/iio/iio:deviceX/in_intensity_both_raw用于測(cè)量紅外和可見光的通道
l?/sys/bus/iio/iio:deviceX/in_illuminance_input用于處理后的數(shù)據(jù)
l?/sys/bus/iio/iio:deviceX/sampling_frequency?用于采樣頻率,由所有人共享

這也適用于加速度計(jì),我們將在案例研究中進(jìn)一步了解?,F(xiàn)在,讓我們總結(jié)一下我們到目前為止在虛擬IIO驅(qū)動(dòng)程序中討論過(guò)的內(nèi)容。

總結(jié)

讓我們總結(jié)一下迄今為止我們?cè)谝粋€(gè)簡(jiǎn)單的虛擬驅(qū)動(dòng)器中看到的內(nèi)容,它將暴露出四個(gè)電壓通道。我們將忽略read()或write()函數(shù):

#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?
#include?


#define?FAKE_VOLTAGE_CHANNEL(num)??????????????????\
???{???????????????????????????????????????????????\
?????????.type?=?IIO_VOLTAGE,??????????????????????\
?????????.indexed?=?1,?????????????????????????????\
?????????.channel?=?(num),?????????????????????????\
?????????.address?=?(num),?????????????????????????\
?????????.info_mask_separate?=?BIT(IIO_CHAN_INFO_RAW),???\
?????????.info_mask_shared_by_type?=BIT(IIO_CHAN_INFO_SCALE)?\

???}

struct?my_private_data?{
????int?foo;
????int?bar;
????struct?mutex?lock;
};

static?int?fake_read_raw(struct?iio_dev?*indio_dev,
???????????????????struct?iio_chan_spec?const?*channel,?int?*val,
???????????????????int?*val2,?long?mask)

{
????return?0;
}

static?int?fake_write_raw(struct?iio_dev?*indio_dev,
???????????????????struct?iio_chan_spec?const?*chan,
???????????????????int?val,?int?val2,?long?mask)

{
????return?0;
}

static?const?struct?iio_chan_spec?fake_channels[]?=?{
???FAKE_VOLTAGE_CHANNEL(0),
???FAKE_VOLTAGE_CHANNEL(1),?
???FAKE_VOLTAGE_CHANNEL(2),
???FAKE_VOLTAGE_CHANNEL(3),

};

static?const?struct?of_device_id?iio_dummy_ids[]?=?{
????{?.compatible?=?"packt,iio-dummy-random",?},
????{?/*?sentinel?*/?}
};

static?const?struct?iio_info?fake_iio_info?=?{
???.read_raw?=?fake_read_raw,
???.write_raw????????=?fake_write_raw,
???.driver_module?=?THIS_MODULE,
};

static?int?my_pdrv_probe?(struct?platform_device?*pdev)
{
????struct?iio_dev?*indio_dev;
????struct?my_private_data?*data;
???indio_dev?=?devm_iio_device_alloc(&pdev->dev,?sizeof(*data));

???if?(!indio_dev)?{
?????????dev_err(&pdev->dev,?"iio?allocation?failed!\n");
?????????return?-ENOMEM;
???}

???data?=?iio_priv(indio_dev);
???mutex_init(&data->lock);
???indio_dev->dev.parent?=?&pdev->dev;
???indio_dev->info?=?&fake_iio_info;
???indio_dev->name?=?KBUILD_MODNAME;
???indio_dev->modes?=?INDIO_DIRECT_MODE;
???indio_dev->channels?=?fake_channels;
???indio_dev->num_channels?=?ARRAY_SIZE(fake_channels);
???indio_dev->available_scan_masks?=?0xF;
????iio_device_register(indio_dev);
????platform_set_drvdata(pdev,?indio_dev);
????return?0;
}
static?void?my_pdrv_remove(struct?platform_device?*pdev)
{
????struct?iio_dev?*indio_dev?=?platform_get_drvdata(pdev);
????iio_device_unregister(indio_dev);
}
static?struct?platform_driver?mypdrv?=?{
????.probe??????=?my_pdrv_probe,
????.remove?????=?my_pdrv_remove,
????.driver?????=?{
????????.name?????=?"iio-dummy-random",
????????.of_match_table?=?of_match_ptr(iio_dummy_ids),??
????????.owner????=?THIS_MODULE,
????},
};
module_platform_driver(mypdrv);
MODULE_AUTHOR("John?Madieu?");
MODULE_LICENSE("GPL");

加載上述模塊后, 我們將有以下輸出, 顯示我們的設(shè)備確實(shí)對(duì)應(yīng)于我們已注冊(cè)的平臺(tái)設(shè)備:

??~#?ls?-l?/sys/bus/iio/devices/
lrwxrwxrwx?1?root?root?0?Jul?31?20:26?iio:device0?->?../../../devices/platform/iio-dummy-random.0/iio:device0
lrwxrwxrwx?1?root?root?0?Jul?31?20:23?iio_sysfs_trigger?->?../../../devices/iio_sysfs_trigger

下面的列表顯示了此設(shè)備的通道及其名稱, 這些通道與我們?cè)隍?qū)動(dòng)程序中描述的內(nèi)容完全對(duì)應(yīng):

?~#?ls?/sys/bus/iio/devices/iio\:device0/
dev?in_voltage2_raw?name?uevent
in_voltage0_raw?in_voltage3_raw?power
in_voltage1_raw?in_voltage_scale?subsystem
~#?cat?/sys/bus/iio/devices/iio:device0/name
iio_dummy_random

END

來(lái)源:嵌入式客棧

版權(quán)歸原作者所有,如有侵權(quán),請(qǐng)聯(lián)系刪除。

推薦閱讀

飛機(jī)上一般是什么操作系統(tǒng)?

高速CAN、容錯(cuò)CAN、LIN總線有什么區(qū)別?

大佬終于把鴻蒙OS講明白了,收藏了!

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

嵌入式ARM

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉