IIO子系统
一些传感器可以挂载在 I I O IIO IIO子系统总线上,支持很多总线,比如 I I C , S P I IIC,SPI IIC,SPI等
用的时候配置 c h a n n e l s channels channels通道,每个通道代表一个类测量,比如陀螺仪有:三个方向角度,三个方向加速度、温度,一共7个通道
通道根据 ∗ m a s k ∗ *mask* ∗mask∗成员( i n f o _ m a s k _ s e p a r a t e info\_mask\_separate info_mask_separate、 i n f o _ m a s k _ s h a r e d _ b y _ t y p e info\_mask\_shared\_by\_type info_mask_shared_by_type等)确定通道下面有几个参数,例如温度有分辨率、原始值、偏置等参数。
每参数Linux会生成一个相应的文件,应用可以直接读取文件获取数据,而不是以前那样驱动和应用商量好一个数据结构才可以解码出来。
应用读或写相应文件时,实质是调用 i i o _ i n f o iio\_info iio_info结构体中的 r e a d _ ∗ read\_ * read_∗或 w r i t e _ ∗ write\_ * write_∗函数进行处理, v a l val val表示整数部分, v a l 2 val2 val2表示小数部分,两者均为 i n t int int类型,只是 v a l 2 val2 val2是放大了一个倍数,具体倍数由相应函数 r e t u r n return return的值决定。
在读相应文件时,读取相应寄存器的值之后将换算后的写入 v a l val val指针指向的空间中,通过 r e t u r n return return不同的宏定义小数放大的倍数。
当写相应文件时,首先执行 w r i t e _ r a w _ g e t _ f m t write\_raw\_get\_fmt write_raw_get_fmt写前置函数,这个函数的返回值对应小数放大的倍数;之后执行 w r i t e _ r a w write\_raw write_raw函数进行具体的寄存器设置。
操作寄存器前需要进行加锁,防止多线程同时对同一总线进行操作引起混乱。
i i o _ c h a n _ s p e c iio\_chan\_spec iio_chan_spec结构体中的 t y p e type type变量用于区分通道类型,有 I I O _ T E M P , I I O _ A C C E L IIO\_TEMP,IIO\_ACCEL IIO_TEMP,IIO_ACCEL,具体可以理解为陀螺仪中的角度、温度、加速度三种类型
i i o _ c h a n _ s p e c iio\_chan\_spec iio_chan_spec结构体中的 c h a n n e l 2 channel2 channel2变量用于区分通道,修饰通道,比如陀螺仪有 X , Y , Z X,Y,Z X,Y,Z三通道
m a s k mask mask掩码区分通道中的参数,如: I I O _ C H A N _ I N F O _ R A W , I I O _ C H A N _ I N F O _ S C A L E IIO\_CHAN\_INFO\_RAW,IIO\_CHAN\_INFO\_SCALE IIO_CHAN_INFO_RAW,IIO_CHAN_INFO_SCALE,也就是函数中的 ∗ m a s k ∗ *mask* ∗mask∗成员( i n f o _ m a s k _ s e p a r a t e info\_mask\_separate info_mask_separate、 i n f o _ m a s k _ s h a r e d _ b y _ t y p e info\_mask\_shared\_by\_type info_mask_shared_by_type等),比如陀螺仪中可以区分分辨率,原始值,偏置,校准
例-icm20608
通道设置
假设一个陀螺仪有三个方向的角度,三个方向的加速度,还有温度
其中三个角度共用一个分辨率,每个角度各有一个校准值和原始值
三个加速度也共用一个分辨率,每个加速度均有一个校准值和原始值
温度有一个原始值,一个分辨率,一个偏置
/*通道设置*/
//温度
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW)
| BIT(IIO_CHAN_INFO_OFFSET)
| BIT(IIO_CHAN_INFO_SCALE),
//角度
.type = IIO_ANGL_VEL,
.modified = 1,
.channel2 = IIO_MOD_X, //IIO_MOD_Y IIO_MOD_Z
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
//加速度
.type = IIO_ACCEL,
.modified = 1,
.channel2 = IIO_MOD_X, //IIO_MOD_Y IIO_MOD_Z
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_CALIBBIAS),
区分逻辑
- 对角度和加速度的各个方面的值读写方式一致;温度的原始值读写方式相同;分辨率和偏置不同
- 对原始值读写,角度加速度温度均一致;对温度偏置可以单独读取;角度和加速度的分辨率读写方式相同,温度和它们不同;角度和加速度的校准值读写方式相同
- 可以将原始值的读取封装为一个函数;将角度和加速度的分辨率读取和校准读取各封装为一个函数;对温度的处理单独出来(c语言)
- 也可以将温度、加速度和角度封装成两个类,类中初始化各自的地址,然后实现各自的读写操作(c++)