驱动开发

如何创建设备属性节点


文章目录

  • 驱动开发
  • 前言
  • 一、代码添加
  • 二、编译
  • 三、 验证
  • 总结

前言

最简单的设备属性节点


一、代码添加

在AU_LINUX_ANDROID_LA.VENDOR.1.0\kernel_platform\msm-kernel\drivers\misc\目录下新建test_device.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>static char  test_flag[32]="0";static ssize_t test_mode_show(struct device *dev,struct device_attribute *attr,char *buf)
{  printk("xxxxx xxx %s,%d: buf: %s test_flag:%s\n",__func__,__LINE__,buf,test_flag);return sprintf(buf, "%s\n",test_flag);
}static ssize_t test_mode_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{ sprintf(test_flag, "%s",buf);printk("xxxxx %s,%d: buf: %s \n",__func__,__LINE__,buf); return count;
}static DEVICE_ATTR(xxx_test_mode,0644, test_mode_show, test_mode_store);static int test_driver_probe(struct platform_device *pdev)
{int ret; int force_gpio;struct device_node *np = pdev->dev.of_node;printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);force_gpio = of_get_named_gpio(np,"qcom,gpio-force-download", 0);if(gpio_is_valid(force_gpio)){ret = gpio_request(force_gpio, "qcom-force-9008-gpio");gpio_export(force_gpio,0);}ret = device_create_file(&pdev->dev, &dev_attr_xxx_test_mode); if (ret < 0){  printk("xxxxx create files fail\n"); return ret;}  return 0;
}static int test_driver_remove(struct platform_device *pdev)
{ printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);device_remove_file(&pdev->dev, &dev_attr_xxx_test_mode); return 0;
}static const struct of_device_id of_xxx_test_mode_match[] = {{ .compatible = "xxx-force-usb-boot", },{},
};static struct platform_driver test_driver ={ .probe = test_driver_probe, .remove = test_driver_remove, .driver = {.name = "xxx-test-mode", .owner  = THIS_MODULE,.of_match_table = of_match_ptr(of_xxx_test_mode_match),},
};static int test_driver_init(void)
{ printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);return platform_driver_register(&test_driver);
}static void test_driver_exit(void)
{ printk("xxxxx %s,%d: Enter\n",__func__,__LINE__);platform_driver_unregister(&test_driver); return;
}module_init(test_driver_init);
module_exit(test_driver_exit);MODULE_AUTHOR("zh@testsmart.com");
MODULE_DESCRIPTION("test Smart Hardware Verion driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:test-mode-driver");

kernel_platform/qcom/proprietary/devicetree/qcom/cape-mtp.dtsi

&soc {gpio_keys {compatible = "gpio-keys";label = "gpio-keys";pinctrl-names = "default";pinctrl-0 = <&key_vol_up_default>,<&gpio_keys_active>;vol_up {label = "volume_up";gpios = <&pm8350_gpios 6 GPIO_ACTIVE_LOW>;linux,input-type = <1>;linux,code = <KEY_VOLUMEUP>;gpio-key,wakeup;debounce-interval = <15>;linux,can-disable;};home {label = "home";gpios = <&tlmm 46 GPIO_ACTIVE_LOW>;linux,input-type = <1>;linux,code = <KEY_HOME>;debounce-interval = <15>;gpio-key,wakeup;linux,can-disable;};vol_down {label = "volume_down";gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;linux,input-type = <1>;linux,code = <KEY_VOLUMEDOWN>;gpio-key,wakeup;debounce-interval = <15>;linux,can-disable;};};+xxx-force-usb {+        compatible = "xxx-force-usb-boot";+       qcom,gpio-force-download = <&tlmm 47 0x2002>;+};};

修改misc目录下的Makefile
AU_LINUX_ANDROID_LA.VENDOR.1.0\kernel_platform\msm-kernel\drivers\misc\Makefile

+obj-m  += test_device.o

注:obj-m最好是以宏控的方式控制,当然也可以以obj-y的方式编译进内核,后续详细介绍

二、编译

以骁龙8 gen1 plus平台为例
在AU_LINUX_ANDROID_LA.VENDOR.1.0目录下执行:

xxxx@u99:~/AU_LINUX_ANDROID_LA.VENDOR.1.0$bash kernel_platform/qcom/proprietary/prebuilt_HY11/vendorsetup.shxxxx@u99:~/AU_LINUX_ANDROID_LA.VENDOR.1.0$cd kernel_platform/xxxx@u99:~/AU_LINUX_ANDROID_LA.VENDOR.1.0/kernel_platform$BUILD_CONFIG=./common/build.config.msm.waipio ./build/all-variants.sh "./build/build.sh"

如上编译完成后AU_LINUX_ANDROID_LA.VENDOR.1.0\kernel_platform\out\msm-waipio-waipio-consolidate\dist\目录下会生成hello_world.ko;push到设备中验证即可。

三、 验证

adb push AU_LINUX_ANDROID_LA.VENDOR.1.0\kernel_platform\out\msm-waipio-waipio-consolidate\dist\test_device.ko /vendor_dlkm/lib/modules/

adb push AU_LINUX_ANDROID_LA.VENDOR.1.0\kernel_platform\out\msm-waipio-waipio-consolidate\dist\test_device.ko /vendor/lib/modules/

taro:/ # insmod vendor/lib/modules/test_device.ko
taro:/ # dmesg |grep xxx
[ 6455.143660] xxxxx test_driver_exit,96: Enter
[ 6455.143738] xxxxx test_driver_remove,66: Enter
[ 6467.130438] xxxxx test_driver_init,89: Enter
[ 6467.131992] xxxxx test_driver_probe,46: Enter
taro:/ #
130|taro:/ # cat sys/devices/platform/soc/soc:xxx-force-usb/xxx_test_mode
0
taro:/ # echo 1 > sys/devices/platform/soc/soc:xxx-force-usb/xxx_test_mode
taro:/ # echo 1 > sys/devices/platform/soc/soc:xxx-force-usb/xxx_test_mode
taro:/ # cat sys/devices/platform/soc/soc:xxx-force-usb/xxx_test_mode
1taro:/ # dmesg |grep xxx
[ 6455.143660] xxxxx test_driver_exit,96: Enter
[ 6455.143738] xxxxx test_driver_remove,66: Enter
[ 6467.130438] xxxxx test_driver_init,89: Enter
[ 6467.131992] xxxxx test_driver_probe,46: Enter
[ 6486.875923] xxxxx xxx test_mode_show,24: buf:  test_flag:0
[ 6491.227092] xxxxx test_mode_store,33: buf: 1\x0a
[ 6493.537732] xxxxx test_mode_store,33: buf: 1\x0a
[ 6495.128476] xxxxx xxx test_mode_show,24: buf:  test_flag:1\x0a
taro:/ #

总结

这里是设备属性节点的添加,添加设备树的目的是为了申请gpio47,这样在开机后sys/class/gpio目录下就可以看到gpio348(SM8475平台的gpio偏移是301),以供厂测使用。关机时,此gpio拉高就可以进9008,即FORCE_USB_BOOT功能。

关于设备节点有几种比较方式:

static ssize_t xxx_store(struct kobject *dev, struct kobj_attribute *attr, const char *buf, size_t count)
{int value = 0;if (num != sscanf(buf, "%d\n", &value)){pr_err("mcu_wake>>>%s: num=%d!=1,regaddr=%d\n", __func__, num, value);return -1;}if((value==1)||(value==0)){if(value==1) {}else {}}else{pr_err("%s\n",__func__);}return count;
}
==========static ssize_t mode_show(struct device *dev, struct device_attribute *attr,char *buf)
{struct dwc3_msm *mdwc = dev_get_drvdata(dev);if (mdwc->vbus_active)return snprintf(buf, PAGE_SIZE, "peripheral\n");if (mdwc->id_state == DWC3_ID_GROUND)return snprintf(buf, PAGE_SIZE, "host\n");return snprintf(buf, PAGE_SIZE, "none\n");
}static ssize_t mode_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t count)
{struct dwc3_msm *mdwc = dev_get_drvdata(dev);if (sysfs_streq(buf, "peripheral")) {mdwc->vbus_active = true;mdwc->id_state = DWC3_ID_FLOAT;} else if (sysfs_streq(buf, "host")) {mdwc->vbus_active = false;mdwc->id_state = DWC3_ID_GROUND;} else {mdwc->vbus_active = false;mdwc->id_state = DWC3_ID_FLOAT;}dwc3_ext_event_notify(mdwc);return count;
}
==============static ssize_t usb_compliance_mode_show(struct device *dev,struct device_attribute *attr, char *buf)
{struct dwc3_msm *mdwc = dev_get_drvdata(dev);return snprintf(buf, PAGE_SIZE, "%c\n",mdwc->usb_compliance_mode ? 'Y' : 'N');
}static ssize_t usb_compliance_mode_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
{int ret = 0;struct dwc3_msm *mdwc = dev_get_drvdata(dev);ret = strtobool(buf, &mdwc->usb_compliance_mode);if (ret)return ret;return count;
}
=====================
static ssize_t dbg_state_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct sdhci_host *host = dev_get_drvdata(dev);struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);bool v;if (!capable(CAP_SYS_ADMIN))return -EACCES;if (kstrtobool(buf, &v))return -EINVAL;msm_host->dbg_en = v;return count;
}=========
static ssize_t gtp_dofwupdate_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct goodix_ts_data *ts = dev_get_drvdata(dev);char update_file_name[FW_NAME_MAX_LEN];int retval;if (count > FW_NAME_MAX_LEN) {dev_info(&ts->client->dev, "FW filename is too long\n");retval = -EINVAL;goto exit;}strlcpy(update_file_name, buf, count);ts->force_update = true;retval = gup_update_proc(update_file_name);if (retval == FAIL)dev_err(&ts->client->dev, "Fail to update GTP firmware.\n");elsedev_info(&ts->client->dev, "Update success\n");return count;exit:

android平台驱动开发(二)--设备属性节点的创建相关推荐

  1. android平台驱动开发(一)

    驱动开发 hello world 文章目录 驱动开发 前言 一.代码添加 二.编译 三. 验证 总结 前言 最简单的hello world 驱动 一.代码添加 在AU_LINUX_ANDROID_LA ...

  2. Linux驱动开发:设备树节点与属性

    目录 1.设备节点(node) 2.属性(property) 3.节点的一些特性 4.节点的一些标准属性 4.1 compatible属性 4.2 model属性 4.3 status属性 4.4 r ...

  3. 【Linux驱动开发】设备树详解(二)设备树语法详解

    ​ 活动地址:CSDN21天学习挑战赛 [Linux驱动开发]设备树详解(一)设备树基础介绍 [Linux驱动开发]设备树详解(二)设备树语法详解 [Linux驱动开发]设备树详解(三)设备树Kern ...

  4. 实现Android底层驱动开发并裁剪定制Android操作系统

    毕业论文 题   目实现Android底层驱动开发并裁剪定制Android操作系统 学   院电子信息与电气工程学院 姓   名牛xxx民 专   业电子信息科学与技术 学   号2012xxxxxx ...

  5. <Linux开发>--驱动开发-- 字符设备驱动(3) 过程详细记录

    <Linux开发>–驱动开发-- 字符设备驱动(3) 过程详细记录 驱动开发是建立再系统之上的,前面作者也记录了系统移植的过程记录,如果有兴趣,可进入博主的主页查看相关文章,这里就不添加链 ...

  6. STM32MP157驱动开发——蜂鸣器设备驱动

    STM32MP157驱动开发--蜂鸣器设备驱动 0.相关知识 一.驱动程序开发 1.设备树修改 2.启动程序编写 3.测试程序编写 二.编译及运行测试 0.相关知识   蜂鸣器常用于计算机.打印机.报 ...

  7. STM32MP157驱动开发——USB设备驱动

    STM32MP157驱动开发--USB设备驱动 一.简介 1.电气属性 2.USB OTG 3.STM32MP1 USB 接口简介 4.Type-C 电气属性 二.USB HOST 驱动开发 1.US ...

  8. 基于MTD的NAND驱动开发(二)

    基于MTD的NAND驱动开发(二) 基于MTD的NAND驱动开发(三) http://blog.csdn.net/leibniz_zsu/article/details/4977853 http:// ...

  9. Linux 设备驱动开发 —— platform设备驱动应用实例解析

    前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 -- platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...

最新文章

  1. 一次防CC***案例
  2. 回归Dos操作的快感,进入PowerShell世界
  3. vc2008中mfc菜单、控件等汉字显示为问号或乱码的解决方法
  4. 深入解析Windows系统两大进程
  5. 【蓝鸥Unity开发基础三】课时14 刚体
  6. raspberry pi_构建自己的Raspberry Pi龙卷风预警系统
  7. 如何修改计算机无线mac地址,修改计算机mac地址_怎么修改mac地址
  8. (Github)增强插件、脚本
  9. 【Zookeeper学习】Zookeeper-3.4.6安装部署
  10. mapreduce对日志数据上下行流量汇总
  11. c语言程序设计答案四,C语言程序设计练习四(参考答案)
  12. 大数据技术之Hadoop概述
  13. 汇编Dos下16位输入输出io.inc
  14. openstack虚拟机模板的搭建
  15. 睿智的目标检测51——Tensorflow2搭建yolo3目标检测平台
  16. 关于写论文的一些想法——如何写好一篇论文
  17. 山大往年自招计算机系试题,山大自招现场:考生笔试说“容易”体测喊“难”...
  18. 台式计算机的显卡,台式电脑显卡天梯图-台式机显卡性能排名
  19. 我们需要“梦想比回忆多”的精神
  20. switch开关语句

热门文章

  1. Oracle Cursor 游标
  2. 最全最简单的dubbo教程
  3. 检索多个word文档某个关键字并打印检索结果
  4. Docker容器之Docker Toolbox下配置国内镜像源-阿里云加速器(Windows)
  5. 中国纺织业漂泊难定,如今向东南亚转移该担心还是惋惜?
  6. pytorch镜像安装【清华源】
  7. Dreamweaver 1 网页制作
  8. 页面请求方法参数最长_url传值的长度限制解决办法
  9. 基于c51单片机的毕业设计——智能温度控制
  10. qss 画框_PyQt5系列教程(77):QSS入门2