前言

驱动开发中通常为设备定义一个设备相关的设备结构体,其包含该设备的cdev 、私有数据、信号量、irq等这些信息。

驱动开发中通常将文件的私有数据private_data指向设备结构体,在read()、write()、ioctl()等函数通过 private_data 访问数据 设备结构体。

container_of() 是一个比较常用的宏,其作用为通过结构体成员的指针找到对应结构体的指针。

通过分析 akm8975.c 这个文件进行分析

分析

自定义的结构体 akm8975_data ,包含了 i2c_client 、work_struct等信息。

struct akm8975_data {

struct i2c_client *this_client;

struct akm8975_platform_data *pdata;

struct input_dev *input_dev;

struct work_struct work;

struct mutex flags_lock;

#ifdef CONFIG_HAS_EARLYSUSPEND

struct early_suspend early_suspend;

#endif

定义一个全局的变量 akmd_data

/*

* Because misc devices can not carry a pointer from driver register to

* open, we keep this global. This limits the driver to a single instance.

*/

struct akm8975_data *akmd_data;

自定义的设备结构体的初始化:

int akm8975_probe(struct i2c_client *client,

const struct i2c_device_id *devid){

...

struct akm8975_data *akm; //申请一个局部的结构体指针

akm = kzalloc(sizeof(struct akm8975_data), GFP_KERNEL); //初始这个指针

akmd_data = akm; //复制给全局的变量

}

将自定义的设备结构体赋值给 file的private_data

static int akm_aot_open(struct inode *inode, struct file *file){

...

file->private_data = akmd_data;

}

通过file取得private_data

tatic int akm_aot_ioctl(struct inode *inode, struct file *file,

unsigned int cmd, unsigned long arg)

{

void __user *argp = (void __user *) arg;

short flag;

struct akm8975_data *akm = file->private_data;

自定义的设备结构体,通常有以下操作

定义一个全局的变量

在probe 或者入口函数中初始化 全局变量

在 file_operation open 中,将全局变量赋值给file的private_data

在read() 、wriete、ioctl()的操作中,通过file取中private_data 进行操作

在定义的设备结构体中 一项 工作队列。 这个工作队列 是如何和 container_of联系起来的呢? 先看下代码中的相关内容。

初始化工作队列

int akm8975_probe(struct i2c_client *client,

const struct i2c_device_id *devid){

...

INIT_WORK(&akm->work, akm_work_func);

}

工队队列

static void akm_work_func(struct work_struct *work)

{

struct akm8975_data *akm =

container_of(work, struct akm8975_data, work); //利用container_of,获得work指针对于的设备结构体指针 akm

FUNCDBG("called");

//通过获得的akm指针,从结构体中,取出成员来执行相应的操作。

enable_irq(akm->this_client->irq);

}

调度 工作队列

static irqreturn_t akm8975_interrupt(int irq, void *dev_id)

{

struct akm8975_data *akm = dev_id;

FUNCDBG("called");

disable_irq_nosync(akm->this_client->irq);

schedule_work(&akm->work);

return IRQ_HANDLED;

}

通过定义一个设备结构体,可以将设备相关的操作、信息封装在一起,后边可以使用 container_of 得到这个结构体。将数据传递给private_data 更加规范和调理。

container_of

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

offsetof 通过将 0 地址,强制转为为TYPE类型的指针,然后取它的成员 NUMBER , 在转为size_t 类型。即得到 NUMBER 在这个TYPE的位置。

/**

* container_of - cast a member of a structure out to the containing structure

* @ptr: the pointer to the member.

* @type: the type of the container struct this is embedded in.

* @member: the name of the member within the struct.

*

*/

#define container_of(ptr, type, member) ({ \

const typeof(((type *)0)->member) * __mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); }) #endif

参考文献

linux驱动私有数据,linux驱动开发之字符设备--私有数据和container_of相关推荐

  1. Linux驱动开发:字符设备驱动开发实战

    Linux驱动开发:字符设备驱动开发实战 一.工程创建 VSCode 创建工程,设置 C/C++ 配置,导入 linux kernel 源码目录,方便 vscode 写代码自动补全,vscode 配置 ...

  2. 初入android驱动开发之字符设备(一)

    大学毕业,初入公司,招进去的是android驱动开发工程师的岗位,那时候刚进去,首先学到的就是如何搭建kernel.android的编译环境,然后就是了解如何刷设备以及一些最基本的工具.如adb.fa ...

  3. Linux驱动开发: 杂项字符设备

    一.什么是杂项设备? 杂项设备(misc device)也是在嵌入式系统中用得比较多的一种设备驱动. 在Linux内核的include\linux目录下有Miscdevice.h文件,misc设备定义 ...

  4. linux内核创建字符节点,Tiny6410学习ing—(四)、嵌入式Linux内核驱动进阶—(7)、高级字符设备驱动(自动创建节点)—#931...

    按照国嵌的视频教程上来说的,最后就是-自动创建设备文件! 其实我感觉以前完全可以直接是手动创建了设备文件,然后就可以直接讲述自动创建设备文件,为啥非要拖到最后来讲述,我也就不清楚了!! 不管了,写完收 ...

  5. Linux驱动编程 step-by-step (二) 简单字符设备驱动

    简单字符设备驱动 1.主次设备号 主设备号标识设备连接的的驱动,此设备好由内核使用,标识在相应驱动下得对应的设备 在linux中设备号是一个32位的dev_t类型 typedef __u32    _ ...

  6. 驱动开发:实现字符设备

    本文通过操作寄存器实现led灯的亮灭,使用开发板iTop4412 #include <linux/init.h> #include <linux/module.h> #incl ...

  7. python后端接收数据_python后端开发使用flask接收前端数据,处理后返回结果

    from flask import Flask, request import json, time, datetime import pysolr import pandas as pd ''' 使 ...

  8. 【嵌入式Linux学习笔记】Linux驱动开发

    Linux系统构建完成后,就可以基于该环境方便地进行开发了,相关的开发流程与MCU类似,但是引入了设备树的概念,编写应用代码要相对复杂一点.但是省去了很多配置工作. 学习视频地址:[正点原子]STM3 ...

  9. 【正点原子MP157连载】第二十二章 新字符设备驱动实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

最新文章

  1. 什么是原码、反码、补码?什么是按位与?范围数字按位与!
  2. php表单退出怎么写,PHP提交表单失败后如何保留填写的信息
  3. vmare安装ghostwin7
  4. 从壹开始前后端分离【 .NET Core2.2 +Vue2.0 】框架之六 || API项目整体搭建 6.1 仓储+服务+抽象接口模式...
  5. ecshop“发货查询”中加入收货人、收货地址、发货时间、配送方式
  6. 拓展小知识(一)——使用 CSS 和 JS 加载阿里小图标
  7. 企业邮箱服务器删除邮件,企业邮箱Webmail对邮件进行删除或者清空邮件的方法...
  8. opencv---颜色空间转化并实现物体跟踪
  9. python爬虫外快_我用Python爬虫挣钱的那些事
  10. cron java_cron表达式
  11. Emscripten教程之C++和JavaScript绑定(三)
  12. 论文数模真的好难?那是你还不会Matlab!
  13. pandas笔记(7)DataFrame数学运算
  14. 从现实到理想,你只差一个透视宝的距离
  15. 2017网易雷火实习生招聘编程题
  16. Keil uVision4使用总结
  17. 扎进“手机”红海,蔚来改造“生态圈”
  18. PlatoFarm推出正式版游戏经济模型的特点分析
  19. 手机上发表csdn博客
  20. Chrome插件开发先看这篇:如何实现一键上班赖皮

热门文章

  1. 算法与数据结构(part3)--数据结构概述
  2. 非科班生如何浑水摸鱼在省级大数据竞赛中获奖
  3. numpy基础(part15)--线性模型
  4. python基础(part11)-作用域LEGB
  5. 分类变量如何设置变量值的显示顺序
  6. python3程序设计基础刘德山答案_Python 3 程序设计学习指导与习题解答
  7. 利用Python对销售额进行预测
  8. 关于 SAP Fiori Elements 应用标题属性(title) 的复制逻辑单步调试
  9. postman和部署在 SAP 云平台上的SAP UI5应用发送同样的HTTP请求,为何前者成功,后者失败?
  10. SAP UI5里input field live search的实现例子