当前位置: 首页 > wzjs >正文

生产营销网站开发联系方式如何进行市场推广

生产营销网站开发联系方式,如何进行市场推广,余杭网站建设,企业信用信息公示系统(辽宁)背景 所有驱动开发都是基于全志T507(Android 10)进行开发,用于记录驱动开发过程。 简介 什么是platform驱动自己上网搜索了解。 在driver/linux/platform_device.h中定义了platform_driver结构体。 struct platform_driver {int (*probe…

背景

所有驱动开发都是基于全志T507(Android 10)进行开发,用于记录驱动开发过程。

简介

什么是platform驱动自己上网搜索了解。

在driver/linux/platform_device.h中定义了platform_driver结构体。

struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table;bool prevent_deferred_probe;
};

驱动实现

步骤一、实现platform_driver 结构体。

在longan/kernel/linux-4.9/drivers目录下创建自己的文件夹,定义一个led_drv.c文件。

定义platform结构体:

/* platform驱动结构体 */
static struct platform_driver gpio_led_driver = {.driver		= {.name	= "devled",			        	// 无设备树时,用于设备和驱动间的匹配.of_match_table	= gpio_led_of_match,     // 有设备树后,利用设备树匹配表},.probe		= gpio_led_probe,.remove		= gpio_led_remove,
};

1、实现的是以下两个方法

//驱动匹配成功后会回调这个函数,用来给驱动进行初始化操作
.probe		= xxx,
//驱动被移除或被卸载后会回调这个函数,用来释放资源
.remove		= xxx,

2、用于和指定的设备树驱动进行匹配

.driver		= {.name	= "devled",			        	// 无设备树时,用于设备和驱动间的匹配.of_match_table	= gpio_led_of_match,     // 有设备树后,利用设备树匹配表},

因此需要定义匹配列表,这里compatible就是设备树里面要定义的名称,这样才能正确识别到设备树配置的驱动。

/* 匹配列表 */
static const struct of_device_id gpio_led_of_match[] = {{ .compatible = "devled" },{}
};

在设备树中定义一个设备节点,注意这里led子节点根据实际情况进行配置。这里以PI1为例

	led_test {compatible = "devled";pinctrl-names = "default";status = "okay";pinctrl-0 = <&pinctrl_led_test>;led {gpios = <&pio PI 1 1 2 0 1>;state = "on";};};

在PIO节点下定义pinctrl_led_test节点,主要用于配置IO口。

    soc@03000000 {pio: pinctrl@0300b000 {...pinctrl_led_test: led_test_grp@0 {allwinner,pins = "PI1";allwinner,function = "led_test_grp";allwinner,muxsel = <0x01>;allwinner,drive = <0x00>;allwinner,pull = <0x01>;allwinner,data = <0x01>;};...}}

步骤2、定义设备节点

主要定义一下gpio_leds_priv,用来存放节点信息,用于生成/dev/xxx节点。

/* 存放led信息的结构体 */
struct gpio_led_data 
{char                    name[16];       // 设备名字int                     pin;            // gpio编号int                     active;         // 控制亮灭的标志
};/* 存放led的私有属性 */
struct gpio_leds_priv 
{struct cdev             cdev;           // cdev结构体struct class            *dev_class;     // 自动创建设备节点的类int                     num_leds;       // led的数量struct gpio_led_data    led;            // 存放led信息的结构体数组
};

步骤3、初始化设备

定义一个初始化方法gpio_led_probe,并绑定到步骤1中的.probe

static int gpio_led_probe(struct platform_device *pdev)
{struct gpio_leds_priv   *priv;          // 临时存放私有属性的结构体struct device           *dev;           // 设备结构体dev_t                   devno;          // 设备的主次设备号int                     i, rv = 0;      /* 1)解析设备树并初始化led状态 */rv = parser_dt_init_led(pdev);if( rv < 0 )return rv;/* 将之前存入的私有属性,放入临时的结构体中 */priv = platform_get_drvdata(pdev);/* 2)分配主次设备号 */if (0 != dev_major) {   /* 静态分配主次设备号 */devno = MKDEV(dev_major, 0); rv = register_chrdev_region(devno, priv->num_leds, "devled"); }   else {   /* 动态分配主次设备号 */rv = alloc_chrdev_region(&devno, 0, priv->num_leds, "devled"); dev_major = MAJOR(devno); }   if (rv < 0) {   dev_err(&pdev->dev, "major can't be allocated\n"); return rv; }   /* 3)分配cdev结构体 */cdev_init(&priv->cdev, &led_fops);priv->cdev.owner  = THIS_MODULE;rv = cdev_add (&priv->cdev, devno , priv->num_leds); if( rv < 0) {dev_err(&pdev->dev, "struture cdev can't be allocated\n");goto undo_major;}/* 4)创建类,实现自动创建设备节点 */priv->dev_class = class_create(THIS_MODULE, "led");if( IS_ERR(priv->dev_class) ) {dev_err(&pdev->dev, "fail to create class\n");rv = -ENOMEM;goto undo_cdev;}/* 5)创建设备 */for(i=0; i<priv->num_leds; i++){devno = MKDEV(dev_major, i);dev = device_create(priv->dev_class, NULL, devno, NULL, "led");if( IS_ERR(dev) ) {dev_err(&pdev->dev, "fail to create device\n");rv = -ENOMEM;goto undo_class;}}printk("success to install driver[major=%d]!\n", dev_major);return 0;undo_class:class_destroy(priv->dev_class);undo_cdev:cdev_del(&priv->cdev);undo_major:unregister_chrdev_region(devno, priv->num_leds);return rv;}

parser_dt_init_led用于获取设备树中的节点信息,并进行初始化。

/* 解析设备树并初始化led属性 */
static int parser_dt_init_led(struct platform_device *pdev)
{struct device_node *np = pdev->dev.of_node;     // 当前设备节点struct device_node *child;                      // 当前设备节点的子节点struct gpio_leds_priv *priv;                    // 存放私有属性int num_leds, gpio;                             // led数量和gpio编号                /* 获取该节点下子节点的数量 */num_leds = 1;if(num_leds <= 0) {dev_err(&pdev->dev, "fail to find child node\n");return -EINVAL;}/* devm_kzalloc是内核内存分配函数,跟设备有关的,驱动卸载时,内存会被自动释放* void * devm_kzalloc (struct device * dev, size_t size, gfp_t gfp)* dev:申请内存的目标设备 size:申请的内存大小 gfp:申请内存的类型标志* GFP_KERNEL是分配内核空间的内存时的一个标志位,无内存可用时可引起休眠*/priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(num_leds), GFP_KERNEL);if (!priv){return -ENOMEM;}priv->num_leds = 1;/* 找到子节点并传给child */child = of_get_child_by_name(np, "led");/* 解析dts并且获取gpio口,函数返回值就得到gpio号,并且读取gpio现在的标志 */gpio = of_get_named_gpio(child, "gpios", 0);/* 将子节点的名字,传给私有属性结构体中的led信息结构体中的name属性 */strncpy(priv->led.name, child->name, sizeof(priv->led.name)); printk(">>>>>  init_led gpio=%d name=%s\n", gpio, priv->led.name);/* 将gpio编号和控制亮灭的标志传给结构体* active属性,1代表亮,0代表灭,初始属性为亮*/priv->led.active = 1; priv->led.pin = gpio; /* 申请gpio口,相较于gpio_request增加了gpio资源获取与释放功能 */gpio_request(priv->led.pin, "led");/* 设置gpio为输出模式,并设置初始状态 */gpio_direction_output(priv->led.pin, 1);/* 将led的私有属性放入platform_device结构体的device结构体中的私有数据中 */platform_set_drvdata(pdev, priv);return 0;}

步骤4、移除设备

常规操作,将所有设备依次注销回收。

static int gpio_led_remove(struct platform_device *pdev)
{struct gpio_leds_priv *priv = platform_get_drvdata(pdev);int i;dev_t devno = MKDEV(dev_major, 0);/* 注销设备结构体,class结构体和cdev结构体 */for(i=0; i<priv->num_leds; i++){devno = MKDEV(dev_major, i);device_destroy(priv->dev_class, devno);}class_destroy(priv->dev_class);cdev_del(&priv->cdev); unregister_chrdev_region(MKDEV(dev_major, 0), priv->num_leds);/* 将led的状态设置为灭 */for (i = 0; i < priv->num_leds; i++) {gpio_set_value(priv->led.pin, ~priv->led.active);}   printk("success to remove driver[major=%d]!\n", dev_major);return 0;} 

步骤5、字符设备描述file_operations

static struct file_operations led_fops = 
{.owner = THIS_MODULE,.open = led_open,.release = led_release,.unlocked_ioctl = led_ioctl,.compat_ioctl = led_ioctl,
};

实现led_open、led_release、led_ioctl。

static int led_open(struct inode *inode, struct file *file)
{struct gpio_leds_priv *priv;priv = container_of(inode->i_cdev, struct gpio_leds_priv, cdev);file->private_data = priv;return 0;}static int led_release(struct inode *inode, struct file *file)
{return 0;
}static long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{struct gpio_leds_priv *priv;priv = file->private_data;printk(">>>>>  led_ioctl command=%d arg=%d\n", cmd, arg);switch (cmd){case LED_ON:printk("LED_ON:%d state: %d\n", priv->led.pin, gpio_get_value(priv->led.pin));gpio_set_value(priv->led.pin, 1);priv->led.active = 1;printk("gpio_pin: %d\n", priv->led.pin);break;case LED_OFF:printk("LED_OFF:%d state: %d\n", priv->led.pin, gpio_get_value(priv->led.pin));gpio_set_value(priv->led.pin, 0);priv->led.active = 0;printk("gpio_pin: %d\n", priv->led.pin);break;default:printk("Ioctl command=%d can't be supported\n", cmd);break;}return 0;}

步骤6、编译环境MakeFile

在自定义目录下创建Makefile文件。这里默认加载设备。

obj-y	+= led_drv.o

也可以创建Kconfig文件,添加配置项后就可以在驱动中进行配置。

config CHR_DEV_BASEtristate "First chr device"default yhelpThis is first che device.
obj-${CONFIG_CHR_DEV_BASE}	+= led_drv.o

源码

附上全部驱动代码

#include <linux/init.h>                  
#include <linux/module.h>          
#include <linux/errno.h>             
#include <linux/types.h>                  
#include <linux/kernel.h>         
#include <linux/fs.h>                  
#include <linux/cdev.h>           
#include <linux/device.h>               
#include <linux/of_gpio.h>             
#include <linux/platform_device.h>    
#include <linux/gpio.h>
#include <linux/of_device.h>
#include <linux/slab.h>#define LED_OFF                     0       
#define LED_ON                      1static int dev_major = 0;/* 存放led信息的结构体 */
struct gpio_led_data 
{char                    name[16];       // 设备名字int                     pin;            // gpio编号int                     active;         // 控制亮灭的标志
};/* 存放led的私有属性 */
struct gpio_leds_priv 
{struct cdev             cdev;           // cdev结构体struct class            *dev_class;     // 自动创建设备节点的类int                     num_leds;       // led的数量struct gpio_led_data    led;            // 存放led信息的结构体数组
};/* 为led私有属性开辟存储空间的函数 */
static inline int sizeof_gpio_leds_priv(int num_leds)
{return sizeof(struct gpio_leds_priv) + (sizeof(struct gpio_led_data) * num_leds);
}/* 解析设备树并初始化led属性 */
static int parser_dt_init_led(struct platform_device *pdev)
{struct device_node *np = pdev->dev.of_node;     // 当前设备节点struct device_node *child;                      // 当前设备节点的子节点struct gpio_leds_priv *priv;                    // 存放私有属性int num_leds, gpio;                             // led数量和gpio编号                /* 获取该节点下子节点的数量 */num_leds = 1;if(num_leds <= 0) {dev_err(&pdev->dev, "fail to find child node\n");return -EINVAL;}/* devm_kzalloc是内核内存分配函数,跟设备有关的,驱动卸载时,内存会被自动释放* void * devm_kzalloc (struct device * dev, size_t size, gfp_t gfp)* dev:申请内存的目标设备 size:申请的内存大小 gfp:申请内存的类型标志* GFP_KERNEL是分配内核空间的内存时的一个标志位,无内存可用时可引起休眠*/priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(num_leds), GFP_KERNEL);if (!priv){return -ENOMEM;}priv->num_leds = 1;/* 找到子节点并传给child */child = of_get_child_by_name(np, "led");/* 解析dts并且获取gpio口,函数返回值就得到gpio号,并且读取gpio现在的标志 */gpio = of_get_named_gpio(child, "gpios", 0);/* 将子节点的名字,传给私有属性结构体中的led信息结构体中的name属性 */strncpy(priv->led.name, child->name, sizeof(priv->led.name)); printk(">>>>>  init_led gpio=%d name=%s\n", gpio, priv->led.name);/* 将gpio编号和控制亮灭的标志传给结构体* active属性,1代表亮,0代表灭,初始属性为亮*/priv->led.active = 1; priv->led.pin = gpio; /* 申请gpio口,相较于gpio_request增加了gpio资源获取与释放功能 */gpio_request(priv->led.pin, "led");/* 设置gpio为输出模式,并设置初始状态 */gpio_direction_output(priv->led.pin, 1);/* 将led的私有属性放入platform_device结构体的device结构体中的私有数据中 */platform_set_drvdata(pdev, priv);return 0;}static int led_open(struct inode *inode, struct file *file)
{struct gpio_leds_priv *priv;priv = container_of(inode->i_cdev, struct gpio_leds_priv, cdev);file->private_data = priv;return 0;}static int led_release(struct inode *inode, struct file *file)
{return 0;
}static long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{struct gpio_leds_priv *priv;priv = file->private_data;printk(">>>>>  led_ioctl command=%d arg=%d\n", cmd, arg);switch (cmd){case LED_ON:printk("LED_ON:%d state: %d\n", priv->led.pin, gpio_get_value(priv->led.pin));gpio_set_value(priv->led.pin, 1);priv->led.active = 1;printk("gpio_pin: %d\n", priv->led.pin);break;case LED_OFF:printk("LED_OFF:%d state: %d\n", priv->led.pin, gpio_get_value(priv->led.pin));gpio_set_value(priv->led.pin, 0);priv->led.active = 0;printk("gpio_pin: %d\n", priv->led.pin);break;default:printk("Ioctl command=%d can't be supported\n", cmd);break;}return 0;}static struct file_operations led_fops = 
{.owner = THIS_MODULE,.open = led_open,.release = led_release,/*** 注: 20250403  yozad.von* 如果是32位内核+32位用户空间或者64位内核+64位用户空间只配置unlocked_ioctl就行*/.unlocked_ioctl = led_ioctl,/*** 注: 20250403  yozad.von* adb shell getprop ro.product.cpu.abi查安卓版本是armeabi-v7a,即32位系统。* compat_ioctl,是为兼容32位的用户空间程序在64位内核上执行ioctl操作* 所以测试发现只有写1是正常的,写其他值都返回-1*/.compat_ioctl = led_ioctl,
};static int gpio_led_probe(struct platform_device *pdev)
{struct gpio_leds_priv   *priv;          // 临时存放私有属性的结构体struct device           *dev;           // 设备结构体dev_t                   devno;          // 设备的主次设备号int                     i, rv = 0;      /* 1)解析设备树并初始化led状态 */rv = parser_dt_init_led(pdev);if( rv < 0 )return rv;/* 将之前存入的私有属性,放入临时的结构体中 */priv = platform_get_drvdata(pdev);/* 2)分配主次设备号 */if (0 != dev_major) {   /* 静态分配主次设备号 */devno = MKDEV(dev_major, 0); rv = register_chrdev_region(devno, priv->num_leds, "devled"); }   else {   /* 动态分配主次设备号 */rv = alloc_chrdev_region(&devno, 0, priv->num_leds, "devled"); dev_major = MAJOR(devno); }   if (rv < 0) {   dev_err(&pdev->dev, "major can't be allocated\n"); return rv; }   /* 3)分配cdev结构体 */cdev_init(&priv->cdev, &led_fops);priv->cdev.owner  = THIS_MODULE;rv = cdev_add (&priv->cdev, devno , priv->num_leds); if( rv < 0) {dev_err(&pdev->dev, "struture cdev can't be allocated\n");goto undo_major;}/* 4)创建类,实现自动创建设备节点 */priv->dev_class = class_create(THIS_MODULE, "led");if( IS_ERR(priv->dev_class) ) {dev_err(&pdev->dev, "fail to create class\n");rv = -ENOMEM;goto undo_cdev;}/* 5)创建设备 */for(i=0; i<priv->num_leds; i++){devno = MKDEV(dev_major, i);dev = device_create(priv->dev_class, NULL, devno, NULL, "led");if( IS_ERR(dev) ) {dev_err(&pdev->dev, "fail to create device\n");rv = -ENOMEM;goto undo_class;}}printk("success to install driver[major=%d]!\n", dev_major);return 0;undo_class:class_destroy(priv->dev_class);undo_cdev:cdev_del(&priv->cdev);undo_major:unregister_chrdev_region(devno, priv->num_leds);return rv;}static int gpio_led_remove(struct platform_device *pdev)
{struct gpio_leds_priv *priv = platform_get_drvdata(pdev);int i;dev_t devno = MKDEV(dev_major, 0);/* 注销设备结构体,class结构体和cdev结构体 */for(i=0; i<priv->num_leds; i++){devno = MKDEV(dev_major, i);device_destroy(priv->dev_class, devno);}class_destroy(priv->dev_class);cdev_del(&priv->cdev); unregister_chrdev_region(MKDEV(dev_major, 0), priv->num_leds);/* 将led的状态设置为灭 */for (i = 0; i < priv->num_leds; i++) {gpio_set_value(priv->led.pin, ~priv->led.active);}   printk("success to remove driver[major=%d]!\n", dev_major);return 0;} /* 匹配列表 */
static const struct of_device_id gpio_led_of_match[] = {{ .compatible = "devled" },{}
};MODULE_DEVICE_TABLE(of, gpio_led_of_match);/* platform驱动结构体 */
static struct platform_driver gpio_led_driver = {.driver		= {.name	= "devled",			        	// 无设备树时,用于设备和驱动间的匹配.of_match_table	= gpio_led_of_match,     // 有设备树后,利用设备树匹配表},.probe		= gpio_led_probe,.remove		= gpio_led_remove,
};module_platform_driver(gpio_led_driver);MODULE_LICENSE("GPL");

http://www.dtcms.com/wzjs/224208.html

相关文章:

  • 海口智能建站模板优化科技
  • 网站建设维护培训河北网站建设案例
  • 投标网站怎么做百度旗下产品
  • 做网站设计用什么软件免费网站搭建
  • 成都市住房和城乡建设局网站优化大师客服
  • 巴南区网站建设班级优化大师官方网站
  • 荔枝视频在线观看高清完整版上海seo公司哪家好
  • 易语言做网站图片下载如何找友情链接
  • 仿糗事百科网站源码dede二次开发分享+评论+互动卢镇seo网站优化排名
  • 怎样制作网站站点百度快照搜索引擎
  • 做网站要了解的事情竞价托管推广多少钱
  • 网站建设商城制作洛阳seo博客
  • 何做好网站建设销售百度seo2022
  • 台湾wordpressseo视频网页入口网站推广
  • 网站建设静态代码产品推广找哪家公司
  • 网站空间购买时选择什么脚本语言网络媒体软文案例
  • 网站优化排名教程关键词密度
  • 做IPv6网站升级的公司有哪些微指数查询
  • 石家庄做网站电话seo群发软件
  • 营销型网站建设的注意事项线上推广引流渠道
  • 大连 做网站东莞seo推广
  • 交易猫钓鱼网站制作教学简短的营销软文范文
  • 小程序建站网站上海互联网公司排名
  • 网页制作与网站建设实战教程视频定西seo排名
  • 建德网站建设德品牌网网站推广平台排行
  • 做网站公司排名电话营销案例最新
  • 网站后台修改不了湖北荆门今日头条
  • 网站的网站建设公司企业网络组网设计
  • 如何查看一个网站是用什么cms做的灰色关键词代发可测试
  • 怎么在百度上创建网站推广普通话的意义简短