如何访问嵌套结构的成员并为其分配从设备树中读取的值?

时间:2018-12-13 08:32:45

标签: android linux-device-driver device-driver device-tree android-kernel

以下是我的设备树:

任何人都可以纠正此代码吗,我是c和驱动程序开发的新手,它如何访问嵌套结构的成员并分配从设备树中读取的值,并将其填充到sys类中。

我期望以下结构:

$ cd sys / class / my_driver / x / 与节点a相同。

/ {
my_features: my_features {
    compatible = "my_driver";
            airplane {
                getAirplaneUIStatus = <0>;
                setAirplaneUIStatus=<2>;
                turnonairpane=<1>;
            };
            hotspot {
                getHotspotUIStatus = <1>;
                setHotspotUIStatus = <3>;
            };

    };

};

我编写了以下代码:

#include <linux/device.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/slab.h>

//int airplane;
//static struct class *my_feature_driver_class;
static struct myConfig *my_pdata = NULL;

typedef struct  {
     int setAirplaneUIStatus;
     int turnonairpane;
} airplane;

typedef struct {
    int setHotspotUIStatus;
    int getHotspotUIStatus;
} hotspot;

typedef struct myConfig {
    struct airplane *ap;
    struct hotspot *hp;   
  } myConfig;

enum my_configuration_t {
    my_CONFIG_AIRPLAN = 0,
    my_CONFIG_HOTSPOT = 1,

};

static int process_my_entry(struct device_node *np, char *name) {
    int value = 0, ret = 0;
    ret = of_property_read_u32(np, name, &value);
    pr_err("my ret value : %d",  ret);
    pr_err("my value : %d", value );
    return value;
  };

struct myConfig *my_entries_parse_dt(struct device *dev) {

    struct device_node *np, *pp;
    struct myConfig *pdata;
    struct airplane *ap;
    struct hotspot *hp;

    //struct my_apis_keys *api; 
    int error;
    int napis;
    int i;

    np = dev->of_node;

    if(!np)
    {
        error = -ENODEV;
        goto err_out;
    }

    napis = of_get_child_count(np);
    pr_err("my child nodes : %d",  napis);
    if (napis == 0) {
        error = -ENODEV;
        goto err_out;
    }

    pdata = devm_kzalloc(dev, sizeof(*pdata) + napis ,
            GFP_KERNEL);

    if (!pdata) {
        error = -ENOMEM;
        goto err_out;
    }

    //pdata->airplane = (struct my_apis_keys *)(pdata + 1);
    //pdata->napis = napis;

    pdata->ap = ap;
    pdata->hp = hp;

    i = 0;
    for_each_child_of_node(np, pp){
        //api = &pdata->airplane[i++];
        ap->setAirplaneUIStatus = process_my_entry(pp, "setAirplaneUIStatus");
        ap->turnonairpane = process_my_entry(pp, "turnonairpane");
        hp->setHotspotUIStatus = process_my_entry(pp, "setHotspotUIStatus");
        hp->getHotspotUIStatus = process_my_entry(pp, "getHotspotUIStatus");
        pr_err("my_entries_parse_dt ");
    }

    if (ap->turnonairpane == 0) {
        error = -EINVAL;
        goto err_free_pdata;
    }

    return pdata;

err_free_pdata:
    kfree(pdata);
    kfree(ap);
    kfree(hp);
err_out:
    return ERR_PTR(error);

};


int GetmyConfiguration(enum my_configuration_t type)
  {
    int ret=0;

    switch (type) {
        case my_CONFIG_AIRPLAN:
            return my_pdata->ap->setAirplaneUIStatus;
        case my_CONFIG_HOTSPOT:
            return my_pdata->hp->getHotspotUIStatus;
        default:
            return ret;
        }
  };

static ssize_t get_airplan(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  {
    return sprintf(buf,"%d",GetmyConfiguration(my_CONFIG_AIRPLAN));
  }

  static ssize_t get_hotspot(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  {
    return sprintf(buf,"%d",GetmyConfiguration(my_CONFIG_HOTSPOT));
  }

static struct kobj_attribute airplane_attribute = __ATTR(airplane, 0444, get_airplan, NULL);
static struct kobj_attribute hotspot_attribute = __ATTR(hotspot, 0444, get_hotspot, NULL);
static struct attribute *myconfig_attrs[] = {
    &airplane_attribute.attr,
    &hotspot_attribute.attr,
    NULL,
    };
static struct attribute_group myconfig_attr_group = {
    .attrs = myconfig_attrs,
  };
int my_feature_driver_probe(struct platform_device * pdev)
{
    int ret = 0;
   struct device *dev = &pdev->dev;
   struct myConfig *pdata= my_entries_parse_dt(dev);
   struct kobject *myconfig_kobj;

   if(pdata == NULL)
    {
        dev_err(dev, "SW version is not included in device tree\n");
        return -EINVAL;
    }
    /* setup pdata */
  my_pdata = pdata;
  platform_set_drvdata(pdev, pdata);
  myconfig_kobj = kobject_create_and_add("my_config", NULL);
  if (!myconfig_kobj)
  {
       pr_err("myconfig_kobj null ");
        return -ENOMEM;
  }
  ret = sysfs_create_group(myconfig_kobj, &myconfig_attr_group);

    if (ret)
    {
        pr_err("my sys_fs_create if %d", ret);
        kobject_put(myconfig_kobj);
    }
    pr_err("my sys_fs_create out %d", ret);

  return 0;

}

int my_feature_driver_remove(struct platform_device * pdev)
{
  int err=0;
  pr_err("my Feature  driver remove :");
  return err;

}

static struct of_device_id bs_of_match[] = {
    { .compatible = "my_driver", },
    { },
};

MODULE_DEVICE_TABLE(of, bs_of_match);

static struct platform_driver my_feature_device_driver = {
    .probe          = my_feature_driver_probe,
    .remove         = my_feature_driver_remove,
    .driver         = {
        .name   = "my_driver",
        .owner  = THIS_MODULE,
        .of_match_table = of_match_ptr(bs_of_match),
    }
};

static int __init my_feature_init(void)
{
    pr_err("my feature Driver init");
    return platform_driver_register(&my_feature_device_driver);
}

static void __exit my_feature_exit(void)
{
    pr_err("my feature driver exit");
    platform_driver_unregister(&my_feature_device_driver);
}

late_initcall(my_feature_init);
module_exit(my_feature_exit);

MODULE_LICENSE("GPL v1");
MODULE_AUTHOR("SKY ");
MODULE_DESCRIPTION("my  Feature Configatrion ");
MODULE_DEVICE_TABLE(of, bs_of_match);

现在,我遇到以下错误,有人可以告诉我如何解决此问题。

error: dereferencing pointer to incomplete type
   ap->setAirplaneUIStatus = process_osx_entry(pp, "setAirplaneUIStatus");
     ^
 error: dereferencing pointer to incomplete type
   ap->turnonairpane = process_osx_entry(pp, "turnonairpane");
     ^
 error: dereferencing pointer to incomplete type
   hp->setHotspotUIStatus = process_osx_entry(pp, "setHotspotUIStatus");
     ^
 error: dereferencing pointer to incomplete type
   hp->getHotspotUIStatus = process_osx_entry(pp, "getHotspotUIStatus");
     ^
 error: dereferencing pointer to incomplete type
  if (ap->turnonairpane == 0) {
        ^
 In function 'GetOSXConfiguration':
 error: dereferencing pointer to incomplete type
    return osx_pdata->ap->setAirplaneUIStatus;
                        ^
 error: dereferencing pointer to incomplete type
             return osx_pdata->hp->getHotspotUIStatus;

1 个答案:

答案 0 :(得分:0)

您的pdataaphp声明不正确。更改:

struct myConfig *pdata;
struct airplane *ap;
struct hotspot *hp;

收件人:

myConfig *pdata;
airplane *ap;
hotspot *hp;

这是因为myConfigairplanehotspot被定义为:

typedef struct {
    ...
} XX;

这会导致声明struct myConfig *pdata被错误地解释为struct struct ...