如何访问嵌套结构的成员并为它们分配从设备树读取的值?
How to access members of nested struct and assign them the values read from device tree?
以下是我的设备树:
任何人都可以更正此代码,我是 c 和驱动程序开发的新手,如何访问嵌套结构的成员并分配从设备树读取的值并将其填充到 sys class 中的值。
我期待以下结构:
$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;
您的 pdata
、ap
和 hp
声明不正确。变化:
struct myConfig *pdata;
struct airplane *ap;
struct hotspot *hp;
至:
myConfig *pdata;
airplane *ap;
hotspot *hp;
这是因为 myConfig
、airplane
和 hotspot
定义为:
typedef struct {
...
} XX;
这导致声明 struct myConfig *pdata
被错误地解释为 struct struct ...
。
以下是我的设备树:
任何人都可以更正此代码,我是 c 和驱动程序开发的新手,如何访问嵌套结构的成员并分配从设备树读取的值并将其填充到 sys class 中的值。
我期待以下结构:
$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;
您的 pdata
、ap
和 hp
声明不正确。变化:
struct myConfig *pdata;
struct airplane *ap;
struct hotspot *hp;
至:
myConfig *pdata;
airplane *ap;
hotspot *hp;
这是因为 myConfig
、airplane
和 hotspot
定义为:
typedef struct {
...
} XX;
这导致声明 struct myConfig *pdata
被错误地解释为 struct struct ...
。